-
Notifications
You must be signed in to change notification settings - Fork 65
Docker Compose Support
Docker Compose is a tool that lets you define complex multi-container applications in YAML formatted text files (usually named docker-compose.yml) and then deploy these application with a single simple command:
docker-compose up
In the docker-compose file it is possible to define multiple services (containers) with their specific properties (e.g. volume mounts port mappings, links, etc.). Is is also possible to specify a Docker file that defines how to build specific images that cannot be found in existing registries.
It is possible to import docker-compose templates in Admiral by navigating to the templates view and clicking on the "Import template or Docker Compose" button.
You will be prompted to either to upload the docker-compose template or to enter its contents yourself. Both options lead to the same result - after pressing the import button, the docker-compose is converted to a template and stored in Admiral. However, the current version of Admiral started its development when there was no networking in Docker. Since networking is now the recommended way to provide means of communication between containers, most of the docker-compose files that one may find on the Internet (e.g. in Docker hub containers' documentation) need some slight modifications to work correctly in Admiral. In the following sections the differences between standard and Admiral supported docker-compose files will be discussed.
In all of the following, only Docker Compose file format version 2 is considered.
This means that the following are currently not going to work:
- Define environment variables in separate .env file
- Splitting docker-compose file in separate files that extend one another
- Other similar use-cases
In Docker Compose there is an option to specify instructions on how to build a specific image that cannot be found in existing registries by using the build key. In the simplest case, the value of this key is the path to the build context (e.g. directory that contains a Dockerfile). In Admiral building images is not possible as this feature makes more sense for development and testing purposes. The recommended way to deal with compose files the build key is to actually build the images and push them to a registry that is accessible from all Docker hosts.
The current Wordpress docker-compose template can be found on https://hub.docker.com/_/wordpress/:
Original Wordpress docker-compose.yml
version: '2'
services:
wordpress:
image: wordpress
ports:
- 8080:80
environment:
WORDPRESS_DB_PASSWORD: example
mysql:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: example
This template can be successfully imported and even provisioned in Admiral. However, this template implies that wordpress and mysql services are in the same Docker network, so wordpress will be able to connect to mariadb using th mysql hostname. Since Admiral currently does not support creation of implicit networks, one needs to be declared.
Below is shown the modified version of the docker-compose file that can be imported in Admiral and will result in a working provisioned wordpress application. All the mandatory changes are documented with a Added for Admiral comment.
Modified Wordpress docker-compose.yml
version: '2'
services:
wordpress:
image: wordpress
# Mapped to random host port instead of 8080 (optional)
ports:
- 80
environment:
WORDPRESS_DB_PASSWORD: example
# Added for Admiral
networks:
- wpnet
mysql:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: example
# Added for Admiral
networks:
- wpnet
# Added for Admiral
networks:
wpnet: {}
This is a simple multi-container application that can be found on GitHub. Schematic representation is shown (source: GitHub page of the project)
The developers of this application describe the architecture of the application as follows:
- A Python webapp which lets you vote between two options
- A Redis queue which collects new votes
- A Java worker which consumes votes and stores them in…
- A Postgres database backed by a Docker volume
- A Node.js webapp which shows the results of the voting in real time
The example voting application features five containers, three of which are build from sources: vote, worker and result. As we explained before, it is not possible to build images in Admiral. Thus, we need to manually build these images and push them to a registry of our choice before doing any modifications to the docker-compose file.
First of all, we need a registry. It is possible to use Docker hub or any other registry. This has been tested with Docker registry deployed in a container on a virtual host.
Then we need to build the three custom images. Clone the project from GitHub and from the project root execute the following (replace 192.168.99.101:5000 with the IP/hostname and port of your registry. If you are using docker hub, you can omit the address but need to specify your username instead of test):
docker build -t 192.168.99.101:5000/test/vote vote/ && docker build -t 192.168.99.101:5000/test/worker worker/ && docker build -t 192.168.99.101:5000/test/result result/
This will build the images and will also tag them so you can easily push them with the following command (again tweak this according to your registry):
docker push 192.168.99.101:5000/test/vote && docker push 192.168.99.101:5000/test/worker && docker push 192.168.99.101:5000/test/result
Original example-voting-app docker-compose.yml
version: "2"
services:
vote:
image: eesprit/voting-app-vote
command: python app.py
ports:
- "80"
networks:
- front-tier
- back-tier
result:
image: eesprit/voting-app-result
command: nodemon --debug server.js
ports:
- "80"
- "5858"
networks:
- front-tier
- back-tier
worker:
image: eesprit/voting-app-worker
networks:
- back-tier
redis:
image: redis:alpine
container_name: redis
ports: ["6379"]
networks:
- back-tier
db:
image: postgres:9.4
container_name: db
volumes:
- "db-data:/var/lib/postgresql/data"
networks:
- back-tier
volumes:
db-data:
driver: local
networks:
front-tier: {}
back-tier: {}
Since it is not possible to build images with Admiral, every build declaration must be dropped. Here the images that were previously pushed to some private registry can be used instead. Just do the following:
...
# build: ./vote
image: 192.168.99.101:5000/test/vote
...
# build: ./worker
image: 192.168.99.101:5000/test/worker
...
# build: ./result
image: 192.168.99.101:5000/test/result
...
Actually, the original docker-compose.yml file specifies most of the ports that are being in use. Optionally, you may drop the host ports declarations. This way the application will still be working as expected, but it will be possible to provision more than one instance of this application on a single host.
The original docker-compose.yml file sets up a volume mapping that allows the developer to actually change the code that is running in the containers without redeploying the application. This implies that the code is being developed on the same host that the docker daemon runs (or least that there is a filesystem mount over the network). If this is not the case, just comment out the volumes declarations and everything will work fine. If you want to have the volume mappings, specify an absolute path mappings.
All the discussed modifications (including the optional ones) can be seen in this modified docker-compose.yml file Modified example-voting-app docker-compose.yml
version: "2"
services:
vote:
# build: ./vote
image: 192.168.99.101:5000/test/vote
# command: python app.py
command: ["python", "app.py"]
# volumes:
# - ./vote:/app
ports:
- "80"
networks:
- front-tier
- back-tier
redis:
image: redis:alpine
# added host port for test purposes
ports: ["6379"]
networks:
- back-tier
worker:
# build: ./worker
image: 192.168.99.101:5000/test/worker
networks:
- back-tier
db:
image: postgres:9.4
networks:
- back-tier
result:
# build: ./result
image: 192.168.99.101:5000/test/result
# command: nodemon --debug server.js
command: ["nodemon", "--debug", "server.js"]
# volumes:
# - ./result:/app
ports:
- "80"
- "5858"
networks:
- front-tier
- back-tier
networks:
# {} is Added for Admiral
front-tier: {}
back-tier: {}
These changes should result in a template that will be successfully imported in Admiral and will provision working applications. To test the application, click the link on the vote container and vote for your favorite pet. Check your vote by clicking on the results container link.