Containers are by default isolated from each other. Docker compose is used to enable communication between different containers
Wraps docker build and run commands. It is useful when we have a long run command and we dont want to execute it everytime.
It can also run multiple containers
Consider the following usecase:
We want a flask app and django app running in different containers in same host machine
We also want a redis server that counts the visitors to both the applications
docker-compose.ymlversion: '3' services: #List of all images redis-server: image: 'redis' #image in docker hub flask1: build: flask1/ #location of Dockerfile corresponding to flask1 ports: - "4000:8000" flask2: build: flask2/ #location of Dockerfile corresponding to flask2 ports: - "4001:8000"
flask1/Dockerfile (for simplicity, the other dockerfile also looks same)FROM python:3.7.1-alpine3.7 RUN pip install flask==1.0.2 RUN pip install redis WORKDIR /home COPY ./ ./ CMD ["python","main.py"]
from flask import Flask import redis #Connecting to redis server r = redis.Redis(host='redis-server') #hostname is the image name in docker-compose.yml #if the server is on different macine, this will be its ip address r.set('visits',0) app = Flask(__name__) app.debug=True @app.route('/') def index(): v = r.get('visits') #increment visits r.set('visits',int(v)+1) #if the container is on different machine, this will be its ip address out = "<h1>Hi Flask1. <a href='http://localhost:4001'>Link To Flask2</a></h1>" out += "<p>Visits : " + str(int(v)) + "</p>" return out if __name__ == '__main__': app.run(host='0.0.0.0',port=8000)
We have a similar flask2/main.py that adds counts of visits to its app
To build the images and rundocker-compose up --build #from the folder conatining docker-compose.yml
Now you can see additional images for Dockerfiles in cache with default tag docker compose [SERVICE_NAME]
To only run the built imagedocker-compose up
Launch in backgrounddocker-compose up -d
Stop containersdocker-compose down
To see status of all containers running corresponding to a docker-compose filedocker-compose ps #from directory containing docker-compose.yml
Often times, we want our server to automatically restart in case of failures. In those cases, we spicify the restart policy in docker-compose.ymlservices: #List of all images flask1: build: flask1/ restart: on-failure #if app stops with error code >0, it automatically restarts ports: - "4000:8000"
"no" : (Default) Never restart
always : Always restart. Used for webservers that are always running
on-failure : Restart when there are common errors, like unable to write to file system
unless-stopped : Stop only when it is forced
Lets say we name the dockerfile as Dockerfile.dev (commonly used convention for development code)services: flask1: build: context: flask1/ dockerfile: Dockerfile.dev
We specify volumns under volumes sectionservices: flask1: volumes: - /home/dep - .:/home #current dir mapped to /home - /home/sank/image_data:/data
Specify under command sectionservices: redis-server: image: redis stdin_open: true # -i (not working) tty: true # -t (not working) command: ["sh"]