By default the visionbox uses a local binary file to store collections. If you want to have multiple visionbox instances share one backend collection or if you want to enroll new images past a certain scale using a database backend might be a better option for you.
This guide will explain how to do that.
We'll be using docker compose to spin up a memsql and a visionbox container.
Let's get started.
Copy the following text into a file named visionbox-with-memsql-docker-compose.json
{
"codes": [
{
"code": "version: '2.2'\n\nnetworks:\n visionboxnet:\n driver: bridge\n\nvolumes:\n memsql_data_cpu:\n\nservices:\n reverse-proxy:\n image: traefik:v1.7\n # Enables the web UI and tells Traefik to listen to docker\n command: --api --docker\n labels:\n - \"traefik.enable=true\"\n ports:\n - 4000:80 \n - 4001:8080 # Traefik's web UI, enabled by --api\n volumes:\n # So that Traefik can listen to the Docker events\n - /var/run/docker.sock:/var/run/docker.sock\n depends_on:\n - visionbox\n networks:\n - visionboxnet\n\n visionbox:\n scale: 4\n labels:\n - \"traefik.frontend.rule=Host:localhost\"\n environment:\n - TOKEN=${TRUEFACE_TOKEN}\n - DB_USER=${DB_USER}\n - DB_PASSWORD=${DB_PASSWORD}\n - DB_HOST=${DB_HOST}\n - DB_PORT=${DB_PORT}\n - DB_NAME=${DB_NAME}\n image: \"trueface/visionbox\"\n restart: always\n expose:\n - \"8080\"\n networks:\n - visionboxnet\n depends_on:\n - memsql\n\n memsql:\n image: \"memsql/cluster-in-a-box\"\n restart: always\n user: root\n container_name: memsql\n networks:\n - visionboxnet\n volumes:\n - \"memsql_data_cpu:/var/lib/memsql\"\n ports:\n - \"3306:3306\"\n - \"8081:8080\"\n environment:\n - LICENSE_KEY=${MEMSQL_LICENSE_KEY}",
"language": "yaml",
"name": "visionbox-with-memsql-docker-compose.json"
}
]
}
Copy the following text into a file named .env and fill in your
- Trueface Token
- MemSQL License key which is free for Databases under 128GB
- Database password of your choice
TRUEFACE_TOKEN=<your Trueface license token>
DB_HOST=memsql
DB_PORT=3306
DB_NAME=tfvision_dev
DB_USER=root
DB_PASSWORD=<your chosen DB password>
MEMSQL_LICENSE_KEY=<free for DBs up to 128GB of RAM usage, please contact support@trueface.ai if you need help with this, we're happy to help>
Start the containers
Keep in mind that the visionbox container will try to connect to the DB with your password but the password hasn't been set on the Database yet. That's the next command after this one but until you've run that command you will see an error looping on your docker log output. [block:code] { "codes": [ { "code": "docker-compose -f visionbox-with-memsql-docker-compose.json up", "language": "shell" } ] } [/block]
[block:api-header] { "title": "Set the password on the MemSQL Database" } [/block]
[block:code] { "codes": [ { "code": "export $(cat .env | xargs) && docker exec -it memsql /usr/bin/memsqlctl change-root-password --password $DB_PASSWORD -a --yes", "language": "shell" } ] } [/block]
Now that the password is set your visionbox container (which has been restarting in the background) will be able to connect to the Database. [block:api-header] { "title": "Send your requests to the Load Balancer for distribution" } [/block] The load balancer listens on port 4000 and distributes requests across the visionbox instances in the backend. So you can send your requests to http://localhost:4000/enroll for example.
You can now use the /enroll and /identify endpoints as you normally would or if you don't want to copy that code, using our Postman collection.
Please keep in mind the port now 4000 and not 8080 like in those examples so in the python example linked above you would replace the line which says
[block:code] { "codes": [ { "code": "BASEURL = 'http://0.0.0.0:8080'", "language": "python" } ] } [/block] with
[block:code] { "codes": [ { "code": "BASEURL = 'http://localhost:4000'", "language": "python" } ] } [/block]
[block:api-header] { "title": "See what's going on in the database" } [/block] To issue database commands directly, for example to change a label name or delete a feature you can now connect your mysql client (MemSQL is just MySQL with some additional vector math functions). [block:code] { "codes": [ { "code": "$ mysql -u root -p -h 127.0.0.1 -P 3306\n\n# you will then be prompted for your DB password you set in the .env file earlier\n\n# From here you can point the mysql client at your database\nuse <name of your database from the .env file, we used tfvision_dev by default>\n\nMySQL [(none)]> use tfvision_dev;\nDatabase changed\n\n# I enrolled an image into a collection called home so you see the table here\n\nMySQL [tfvision_dev]> show tables;\n+------------------------+\n| Tables_in_tfvision_dev |\n+------------------------+\n| collection |\n| detection |\n| frame |\n| home |\n| video |\n| videopart |\n+------------------------+\n6 rows in set (0.001 sec)\n\nMySQL [tfvision_dev]> desc home;\n+----------+-------------+------+------+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+----------+-------------+------+------+---------+----------------+\n| Id | bigint(20) | NO | PRI | NULL | auto_increment |\n| label | varchar(90) | YES | | NULL | |\n| features | text | YES | | NULL | |\n| filepath | text | YES | | NULL | |\n+----------+-------------+------+------+---------+----------------+\n4 rows in set (0.001 sec)\n", "language": "shell" } ] } [/block]
[block:api-header] { "title": "How is this getting load balanced?" } [/block] The docker compose file uses a load balancer called traefik, it will distribute traffic across your visionbox instances following a round-robin schedule meaning the first request will go to node 1, the second to node 2. The fifth request will be sent to node 1 again.
You can check the status of your nodes on traefik's web interface by pointing a web browser at http://localhost:4001
[block:image] { "images": [ { "image": [ "https://files.readme.io/80ae13b-traefik.png", "traefik.png", 2803, 1880, "#dbf0f7" ] } ] } [/block]