Deployment with docker compose - HashedIn Technologies

Deployment with docker compose

Technology - 27 Dec 2017
Vinit Kumar

An application can consists of multiple tiers or sub-components. In containerized deployment these components needs to be deployed as individual unit. For an example if a application consists of database & caching server, then database & caching server should be considered as individual components and should be deployed as separate component. A very simple philosophy is, “Each container should run only one process”.

Running multiple containers using docker CLI is possible but really painful. Also, scaling any individual component might be a requirement but this adds more complexity in management of containers. Docker-Compose is a tool which addresses this problem very efficiently. It uses simple YML file to describe complete application and dependency between them. It also provides convenient way to monitor and scale individual components, which it termed as services. In the following section we will see how to use docker-compose for managing charcha's production ready deployment.

In the previous (post)[/2017/05/02/create-production-ready-docker-image], we have created a production ready docker images of charcha. We are going to use the same image in this discussion. Let’s start with simple compose file. For production system we need following things;

  1. Database: As per our settings file, we need postgres.
  2. App Server: A production ready app server to serve our django app. We are going to use gunicorn for this.
  3. Reverse Proxy WebServer: Our app server should be running behind a reverse proxy to prevent it from denial of service attack. Running gunicron behind a reverse proxy is recommended. This reverse proxy will also perform few additional things such as;3.1. Serve pre-gzipped static files from the application3.2 SSL offloading/termination. Read this to understand the benefits.

Let’s build each service step by step in docker-compose.yml file created at the root of project. For brevity, every step will only add configs related to that step.

  1. Create service for database YAML version: ‘2’ services: db: # Service name # This is important, always restart this service if it gets stopped restart: always # Use postgres official image image: postgres:latest # Expose postgres port to be used by Web service expose:
    • 5432 environment: # Some environment variables accepted by postgres image
    • POSTGRES_PASSWORD=password
    • POSTGRES_USER=user
    • POSTGRES_DB=charcha This is simple docker-compose file to create a database as the service.
  2. Create service for app: To create our app service we are going to use previously discussed (Dockerfile)[/2017/05/02/create-production-ready-docker-image] for charcha. This service will run, db migration(and hence need to linked with database service) and run gunicorn application at 8000.

Here is the app config which needs to be added in previously created docker-compose file.

  1. Create reverse proxy service: To create reverse proxy service we are going to use official nginx image and will mount charcha/staticfiles folder into the nginx container.Before proceeding to create docker-compose config for this service we need following things.3.1 A SSL certificate: Charcha production settings has been configured to only accept HTTPS requests. Now, instead of adding SSL certificate at App server, we will add certificate at nginx to offload SSL here. This will add performance gain. Follow these steps to create SSL certificate.

    3.2 An nginx config file:

Now, let’s define nginx service in docker-compose.

Great, so we have completed our docker-compose and all required configuration and ready to start production like environment on dev box. You can run following steps to start playing with it.

  1. Run services: docker-compose up -d
  2. Verify all services are in running state docker-compose ps, you should out like;

Now, you can start accessing the application at

IMP: as hostname is checked from application, so you can’t access it from localhost. Also, at this point you didn’t have any DNS entry for this. To workaround a simple trick is to use your /etc/hostsfile to do the local name resolution. sudo echo " >> /etc/hosts"

Additional stuffs to help in debugging

  1. To see logs for all services use docker-compose logs
  2. To see logs for a particular service use docker-compose logs <service-name> eg. docker-compose logs web
  3. To Login into running container docker exec -it <bash/sh(depends on image used)>

Here is the final docker-compose file


In deployment with docker compose series, till now we read how to create production ready docker image and use it with docker-compose. You can try this in production with little changes(like reading environment variables instead of hard-coding in compose file) on a single large VM.

In coming blogs we will further discuss about gaps with docker-compose and using ECS / Swarm /Kubernets like container management services, in production environment to fill those gaps.


E-book on Digital Business Transformation