Deploy with Docker stack
Create your docker-compose
file.
Ensure it’s stating a version of at least 3.
version: '3' services: app: image: php:7 environment: DB_HOST: db DB_USER: root DB_PASS: root DB_NAME: test ports: - 8000:80 networks: - devnet deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure db: image: mysql:latest environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: test networks: - devnet deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure networks: devnet: driver: overlay
Initiate swarm
You can only deploy to a swarm. So when you’re not on a swarm yet, initiate a swarm.
$ docker swarm init Swarm initialized: current node (12345abcd) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token long-token-1234-abdc 192.168.1.2:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Deploy the stack
$ docker stack deploy -c docker-compose.yml dev Creating network dev_devnet Creating service dev_app Creating service dev_db
Check the status of your stack
To check the status of the services in your stack, issue the command docker stack ps <stackname>
.
$ docker stack ps dev ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS smfn5wlsf9iy dev_db.1 mysql:latest linuxkit-025000000001 Running Running 33 seconds ago q6zade4sjes3 dev_app.1 php:7 linuxkit-025000000001 Running Preparing 37 seconds ago
Check services in your stack
$ docker stack services dev ID NAME MODE REPLICAS IMAGE PORTS 085u7la8kgso dev_app replicated 1/1 php:7-apache *:8000->80/tcp ogwbs8ge3a7x dev_db replicated 1/1 mysql:latest
Get more detailed info of a service with docker service ps
$ docker service ps apibot-test_app ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS rd7lpji8noqx apibot-test_app.1 registry.gitlab.com/pauledenburg/apibot:latest Running Pending 4 minutes ago "no suitable node (2 nodes not…"
Get the full errormessage. Because, by default, it’s truncated. No prob, just use the --no-trunc
flag
$ docker service ps apibot-test_app --no-trunc ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS rd7lpji8noqxftr6c4dozzg8d apibot-test_app.1 registry.gitlab.com/pauledenburg/apibot:latest Running Pending 4 minutes ago "no suitable node (2 nodes not available for new tasks)"
Services use containers too
The services use containers too. This knowledge can help if you need to debug and want to execute a command on one of the containers.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 24501897f39a php:7-apache "docker-php-entrypoi…" 2 hours ago Up 2 hours 80/tcp dev_app.1.sct5wyx3hcix3rvtac9eaek6i 168f471918a6 mysql:latest "docker-entrypoint.s…" 2 hours ago Up 2 hours 3306/tcp dev_db.1.smfn5wlsf9iyndvqq0j4cyz7j
Pro-tip
The containers have really long names. I prefer to use a little helperscript to make executing commands on containers easier.
#!/usr/bin/env bash search=$1 shift 1 command="$@" CONTAINER=$(docker ps -q --filter="name=_$search") CONTAINER_NAME=$(docker ps --filter="name=_$search" | rev | awk '{print $1}' | sed -n '1!p' | rev) printf "[executing on container $CONTAINER_NAME]\n\n" docker exec -it $CONTAINER bash -lc "$command"
Now when I want to execute a command on a container with ‘app’ in the name, I use that as the first argument. So the command becomes ./dev <part_of_container_name> <command_to_execute_on_container>
$ ./dev app php -v [executing on dev_app.1.sct5wyx3hcix3rvtac9eaek6i] PHP 7.2.2 (cli) (built: Feb 6 2018 22:13:41) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
Update the stack
If there are changes to the images, you can update your stack by simply running the deploy
again.
$ docker stack deploy -c docker-compose.yml dev Updating service dev_db (id: ogwbs8ge3a7xv4l2icr4nd4x6) Updating service dev_app (id: 085u7la8kgso48obt948de2dp)
Getting the logs for a service
To debug your stack, you can use docker service logs
to see what happens on the service.
# see what services are in the stack $ docker stack services dev ID NAME MODE REPLICAS IMAGE PORTS 085u7la8kgso dev_app replicated 1/1 php:7-apache *:8000->80/tcp ogwbs8ge3a7x dev_db replicated 1/1 mysql:latest # get the logs for one of them $ docker service logs dev_db dev_db.1.smfn5wlsf9iy@linuxkit-025000000001 | Initializing database dev_db.1.smfn5wlsf9iy@linuxkit-025000000001 | 2018-02-14T13:56:16..... ...
Remove the stack
To remove your stack, use the rm
flag.
$ docker stack rm dev Removing service dev_app Removing service dev_db Removing network dev_devnet