Docker-Compose v3 - production ready

As we know docker-compose is one of the most important tools in the Docker toolbox, originally used to set up a development or testing environment for CI, but in these latest releases it has made a significant leap to the production environment, either for Deploy a single server with Docker Machine or use an entire cluster using Docker Swarm, in this post we will see how Docker Compose can be used to deploy production, and prepare the foundation for the development environment and deploy next using docker Stack.
Stack structure
Use docker-compose files is easier to create the structure of your stack, and can be isomorphic between your environments.
Service
Is an app running in a container started from a docker image. Web , admin, and api are the names of the services we are going to use on docker-compose api to run some operations within our stack.
Use case (demo)
Kitten Rank App
Lets say have an app for a while that is starting to have more users and we need a way to move it easily to other faster servers, to speed up the deployment process, and to make the development environment easy.
First of all we are going to move each service code to docker files (Dockerfile) to be able to create images where te code is going to run in production mode.
We have prepared the code for you to use it with docker-compose and will explain the infrastructure, and how to build and run the containers
API source
WEB source
Admin source
A single service example, Run API in docker
Our API is based on Node js we need to use an image with Node js installed and ready to run code.
This configuration uses a node image from docker hub registry and clone the master branch of the api code and then install dependencies and exposes a port we are going to use to communicate to the server.
Build the API service image
An image is the set of layers and configuration where you can run many instances from it called containers.
$ docker build -t api-demo:latest .Docker will build an image named api-demo with the tag latest, think of it as a gihub repo with the branch name. Now that the image have the source code of the API for our service you now can run a container ( or as many as you want ).
$ docker run -it --rm -p "3100:3100" api-demo:latestDocker will start a new container from the image api-demo:latest and will publish port 3100 from inside the container to your host ( usually is loclahost ), to stop the container just press ctrl+c on terminal.
Now you can go to http://localhost:3100 and you may se a response from the API server (the may be some issues if you have another service using the same port).
Obviously this is just an example for this process to actually work we need to run the data base too and connect the network between them, then add each of the services.
Now you get the point, we use docker-compose
We do not want to manually build, run, stop or destroy every service, and add extra configuration to our stack.
The infrastructure of our app can be settled on its own github repository and any kind of production configuration can be updated there.
Infrastructure source
API configuration on docker-compose.yml for production.
First step is to set api as service then tell docker compose to build a new image for us called appdemoinfra_api:latest from the Docker file inside the directory Docker/api inside of the project directory.
$ cd app-demo-infra
$ docker-compose upAfter running docker-compose up, docker will build the image then will start the api container. we can now. Next time we run the same line docker will know an image exists to be used and just will run the api container. If we need to make some other changes on the docker file to update the image where api will run then we need to re build the service.
Rebuild service images
$ docker-compose build --no-cacheStop service containers
$ docker-compose stopdocker-compose will look for the file inside the directory and will stop all the services in docker-compose.yml, be aware of not modify the file before stop or remove the containers or you will need to stop them manually.
Remove service containers
$ docker-compose downWill stop the containers and then will remove every container and network.
At this moment all docker-compose [ up, stop, start, restart, down ] looks by default docker-compose.yml but you can use another .yml file
$ docker-compose -f ./other_directory/other_file.yml upEven better we can mix several docker-compose files, and override configurations of our services from last to first in order.
docker-compose -f docker-compose.yml -f ./other_directory/other_file.yml upNow lets add the rest of services
We added a few extra services to the file like web app, admin site, and the database. We want web app and admin site to be single page apps build in React and be optimized for production so needs an extra configuration to remove all the development code and tools to have light weight containers without garbage files on them.
Added a mongodb database with no ports published and only connected to the api service because we want the database to be private.
Other tags added to the file like depends_on, networks, args to make our stack work properly.
At the end our APP infrastructure repository will look like this.
app-demo-infra
-docker-compose.yml
-Docker
--admin
---Dockerfile
--api
---Dockerfile
--web
---DockerfileThe benefit is that we do not need every service source code and we have a better documentation of how the APP is been designed.
RUN
Lets run the APP, we have the code ready to production.
$ git clone https://github.com/jrsalgado/app-demo-infra.git
$ cd app-demo-infra
$ docker-compose up --buildNEXT
As you will notice there is already an implementation of the development environment and ready to use, it also can be deployed in swarm mode.
I will make another post to explain how to build the development environment, and how to deploy to docker swarm this same code, but feel free to use try it and leave any comments and suggestions, thanks.
# build service images for development environment$ docker-compose -f docker-compose.yml -f develop.yml build api web admin$ docker-compose -f docker-compose.yml -f develop.yml up
