Dev Ops Docker

5 Docker Compose Examples

Docker compose is an efficient and easy way of deploying docker containers on a host. Compose takes in a YAML file and creates containers according to its specifications. The specification includes what images are needed to be deployed, which specific ports are needed to be exposed, volumes, cpu and memory usage limits, etc.

It is an easy way to set up automated application deployment with a frontend, a database and a few passwords and access keys thrown in for good measure. Everytime you run docker-compose up from inside a directory that contains a docker-compose.yml it goes through the file and deploys your application as specified.

To help you write your own docker-compose.yml here are 5 simple and, hopefully, helpful YAML snippets that you can mix and match.

1.  Nginx Reverse Proxy

Probably the most common application to be deployed as a Docker container is Nginx. Nginx can serve as reverse proxy server and as SSL termination point for your web applications. Different content management systems like Ghost and WordPress can be hosted behind a single Nginx reverse proxy server and thus it makes sense to have an nginx server snippet handy at all times. The first thing you would need is an nginx configuration file. If you choose not to create one, the default HTTP server is what you will get.

For example, I would create a folder nginx-configuration in my home folder. The configuration file nginx.conf will be present inside this folder, along with other files directories that nginx would expect at /etc/nginx. This includes SSL certs and keys, and host names for the backend servers where the traffic needs to be forwarded.

This folder can then be mounted inside nginx container at /etc/nginx (with read-only permission if you prefer extra precaution) and you can run the server as a container, but you can configure it locally from your home directory without having to log into the container.

This is  a sample:

version: '3'
services:
nginx:
image: nginx:latest
volumes:
- /home/USER/nginx-configuration:/etc/nginx
ports:
- 80:80
- 443:443

2.  Ghost Blog

Ghost is a CMS written mostly in Node.js and is simplistic, fast and elegant in design. It relies on Nginx to route traffic to it and uses MariaDB or sometimes SQLite to store data. You can deploy a quick and dirty Docker image for Ghost using a simple snippet as shown below:

version: '3'
services:
ghost:
image: ghost:latest
ports:
- 2368:2368
volumes:
- ghost-data:/var/lib/ghost/content/

volumes:
Ghost-data:

This creates a new volume and mounts it inside the container to store the website’s content persistently. You can add the previous nginx reverse proxy service to this compose file and have a production grade Ghost Blog up and running in the matter of minutes, provided you have configured Nginx to route the relevant traffic from port 80 or 443 to port 2368 on the ghost container.

3.  MariaDB

MariaDB is quite a useful piece of software to not be available at a moment’s call on your server. However, databases create a lot of logs, the actual data tends to get spread all over the place and setting up database servers and/or clients never goes smoothly. The carefully crafted docker-compose file can mitigate some of the problems by trying to store all the relevant data in a single Docker volume, while the database software and its complexities are tucked away in the a container:

version: '3'
services:
mydb:
image: mariadb
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw

You can create a new database container for each new application, instead of creating more users on the same database, setting up privileges and going through a painful rigmarole of ensuring every app and user stays on its own turf. You also won’t have to open ports on the host system since the database container will run on its own isolated network and you can have it so that only your application can be a part of that network and thus access the database.

4. WordPress Stack

A culmination of all the various parts from the use of environment variables to running a frontend web server and a backend database can be combined in a docker-compose file for a WordPress website, as shown below:

version: '3.3'
 
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
 
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:

This is the most popular example and is also mentioned in the official Docker-Compose documentation. Chances are you won’t be deploying WordPress, but the compose file here can still serve as a quick reference for similar application stacks.

5.  Docker-Compose with Dockerfiles

So far we have only been dealing with the pure deployment side of docker-compose. But chances are you will be using Compose to not just deploy but develop, test and then deploy applications. Whether running on your local workstation, or on a dedicated CD/CI server, docker-compose can build an image by using the Dockerfile present at the root of the repository concerning your application or part of the application:

version: ‘3
services:
front-end:
build: ./frontend-code
back-end:
image: mariadb

You will have noticed that while the backend service is using a pre-existing image of mariadb, the frontend image is first built from the Dockerfile located inside ./frontend-code directory.

Lego blocks of Docker-Compose

The entire functionality of Docker-Compose is pretty easy to grasp if only we first ask ourselves what it is that we are trying to build. After a few typos and failed attempted, you will be left with a set of snippets that work flawlessly and can be put together like lego building blocks to define your application deployment.

I hope the above few examples will give you a good head start with that. You can find the complete reference for writing compose file here.

About the author

Ranvir Singh

Ranvir Singh

I am a tech and science writer with quite a diverse range of interests. A strong believer of the Unix philosophy. Few of the things I am passionate about include system administration, computer hardware and physics.