Docker is a fantastic but sometimes container management can be complicated. To simplify and automate Docker application deployments we can use Saltstack, a strong configuration management written in Python and using ZeroMQ for dial with servers (called minions).
In this post, I'll show you how-to use Saltstack on a virtual cloud server based on Debian or Ubuntu. Salt will be used in a standalone mode, without master server.
Install Saltstack on your server
We're going to install salt-minion who'll manage our deployment.When your Salt code will be written you can re-use it to deploy again and again your application.
We'll use Salt-Bootstrap to automatically install Saltstack on our server, for this, run these commands :
wget -O install_salt.sh https://bootstrap.saltstack.com sudo sh install_salt.sh
Because pipe over the internet is a bad idea.
Salt should be installed few minutes later. We need to inform him that it will use the standalone mode (and not the master-client mode). For this, edit the /etc/salt/minion file :
Now, we can restart Salt-minion :
service salt-minion restart
If Salt is correctly installed, we can try to ping itself :
We use Salt-call in a standalone mode.
Write our Docker configuration
When Salt is installed on your server, we'll be able to deploy Docker and our Application configuration with some YAML files.
We start with /srv/salt/docker.sls :
import-docker-key: cmd.run: - name: apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D - creates: /etc/apt/sources.list.d/docker.list /etc/apt/sources.list.d/docker.list: file.managed: - source: salt://docker.list docker: pkg.installed: - name: docker-engine service.running: - name: docker - require: - pkg: docker-engine
This State (YAML file) install Docker and ensure the service is correctly running. We need to create the proper docker.list file with our PPA information (example for Debian 8) :
echo "deb https://apt.dockerproject.org/repo debian-jessie main" > /srv/salt/docker.list
Now, we can create our application state in /srv/salt/app.sls :
repo/my_app: dockerng.image_present: - force: true - name: repo/my_app:latest my_app: dockerng.running: - name: my_adpp - image: repo/my_app:latest - port_bindings: 80:80
This state first pull our image in the latest version then launch our container called my_app and with TCP port 80 exposed.
This example is quite simple but we can easily add some parameters to restrain resources or build our own image directly from Salt.
For this, I'll invite you to take a look on Saltstack documentation.
At this point, our application configuration is finished, we need to test it. But however, we add to create the /srv/salt/top.sls file for inform Salt what States it must use :
base: '*': - docker - app
Deploy our application
Our server is now ready to receive our application through Saltstack.
We're going to use the Highstate module who apply all the states present in the top.sls file.
You can use
test=True if you want to stimulate the Highstate.
The first launch can take few minutes because it install Docker and pull your image. If all the steps correctly pass, you should have a confirmation by Saltstack :
We can verify our container running using Docker CLI (I'll use tutum/lamp in my case) :
There you go ! Your web application is perfectly deployed using Docker managed by Saltstack. No more container started manually anymore.
You can use a git repo to host all your Salt's states for easily deploy codes on your servers.
You can also run the highstate periodically to ensure Docker stay correctly installed and running and for be sure that your application stay up.
00 00 * * * salt-call state.highstate
Docker is great but Docker managed by Saltstack, is better.
Last example, a state to run a persistent Wordpress application :
wordpress_app: dockerng.running: - name: wordpress_app - image: repo/wordpress:latest - port_bindings: 80:80 - environment: - WORDPRESS_DB_HOST: db:3306 - WORDPRESS_DB_PASSWORD: wordpress - links: wordpress_db:mysql wordpress_db: dockerng.running: - name: wordpress_db - image: repo/mariadb:latest - ports: 3306/tcp - binds: ./mysql:/var/lib/mysql:rw - environment: - MYSQL_ROOT_PASSWORD: wordpress - MYSQL_DATABASE: wordpress - MYSQL_USER: wordpress - MYSQL_PASSWORD: wordpress