background
Before deploying applications, various environment configurations were needed, and various shell operations were needed to build a set of available services. Now with Docker, deployment is easier, configuration errors are less likely, and environment inconsistencies are less likely. It solves the problems of running in the local environment and migrating to the online environment. Most of these problems occur in different online and local environments, and configuration is prone to errors. So what is the relationship between docker-compose and docker?
Let's first look at the definition of docker-compose: Defining and running multi-container Docker applications
We know that docker can define an application container through a Dockerfile template file. In practical application, it is often encountered that multiple containers cooperate to run a set of applications. For example, in order to implement a Flask application, besides Flask service itself, some database service containers are needed. Compose satisfies this requirement. It allows users to define a set of associated application containers as a project through a separate docker-compose.yml template file (YAML format).
_Through Docker-Compose users can easily define a multi-container application with a configuration file, and then install all the dependencies of the application with a single instruction to complete the construction. Docker-Compose solves the problem of how to manage the layout between containers.
Implementation steps
Using Dockerfile to customize the image
Mirror customization is actually customizing the configuration and files added to each layer, because Flask applications need some environment dependency to run. So to run Flask applications in a Docker container, the container must install all the environment dependencies of the application. Dockerfile provides us with operations such as configuring environment dependencies. Dockerfile is a text file, which contains instructions. Each instruction builds a layer, so the content of each instruction is to describe how the layer should be constructed.
Here's my GitHub project flask-v2ex For example, the application Dockerfile file:
FROM daocloud.io/python:3.5 MAINTAINER Guoweikuang <guoweikuang2015@gmail.com> RUN mkdir -p /home/guoweikuang/app WORKDIR /home/guoweikuang/app ADD ./requirements.txt /home/guoweikuang/app/requirements.txt RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt ADD . /home/guoweikuang/app CMD python manage.py runserver -h 0.0.0.0 FROM: Specifies the base image on which to customize the operation MAINTAINER: Used to specify image creator information RUN: Created **/home/guoweikuang/app** Folder (behind RUN pip3 install Python expanded memory bank) WORKDIR: Switch directories, you can switch multiple times(Amount to cd command) ADD: Copy files from local directory to container path CMD: Set up container Operations performed at startup, run Flask Apply and set host For 0.0.0.0
Write docker-compose.yml file
The docker-compose.yml file will associate everything. It describes the composition of the application (a web service and a database), the Docker image used, the connection between the images, the volume mounted to the container, and the open ports of the service.
Here's my GitHub project flask-v2ex Take the docker-compose.yml file as an example:
version: '2' services: web: build: . container_name: flask_v2ex ports: - "5000:5000" redis: image: "redis:alpine"
Two service web and redis are defined in compose.
-
web Services
- Build: Mirror the Docker file build using the current directory
- Ports: Mapping host 5000 ports to container 5000 ports
- container_name: Specifies the name of the container
-
redis services
- Image: Using the redis image in Docker Hub
Build and run Flask applications using compose
Before running docker-composeup, you need to make some changes to the redis connection configuration in the project
r = redis.Redis(host='localhost', port=6379, decode_responses=True) //Revised to: r = redis.Redis(host='redis', port=6379, decode_responses=True)
Use the docker-compose up command in the root directory of the flask-v2ex project, as follows:
$ docker-compose up Starting flask_v2ex ... done Starting flask_v2ex_redis_1 ... done Attaching to flask_v2ex_redis_1, flask_v2ex redis_1 | 1:C 01 Jul 07:46:52.053 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo redis_1 | 1:C 01 Jul 07:46:52.053 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=1, just started redis_1 | 1:C 01 Jul 07:46:52.053 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf redis_1 | 1:M 01 Jul 07:46:52.064 * Running mode=standalone, port=6379. redis_1 | 1:M 01 Jul 07:46:52.064 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. redis_1 | 1:M 01 Jul 07:46:52.064 # Server initialized redis_1 | 1:M 01 Jul 07:46:52.065 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. redis_1 | 1:M 01 Jul 07:46:52.065 * DB loaded from disk: 0.000 seconds redis_1 | 1:M 01 Jul 07:46:52.065 * Ready to accept connections flask_v2ex | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) flask_v2ex | * Restarting with stat flask_v2ex | * Debugger is active! flask_v2ex | * Debugger PIN: 742-073-002
You can see that the Docker daemon is listening for 5000 ports. Can pass http://localhost 5000 access Flask applications.
docker-compose uses
- Docker-compose up-d: Background running
- docker-compose stop: Stop running services
- docker-compose down: Close all containers and delete them, leaving data volumes by default
- docker-compose ps: Lists the current running service status and related information
$ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------ flask_v2ex /bin/sh -c python manage.p ... Up 0.0.0.0:5000->5000/tcp flask_v2ex_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
- docker-compose run: One-time command. For example, look at the environment variables of web services:
$ docker-compose run web env PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=e4b6b17f39dc TERM=xterm LANG=C.UTF-8 GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D PYTHON_VERSION=3.5.4 PYTHON_PIP_VERSION=9.0.1 HOME=/root
If you need to stop a running service, you can stop the service by ctrl + c or docker-compose stop.
Reference resources
Docker from Introduction to Practice--Actual Django
Building Docker Image with Dockerfile