关于Docker Compose的教程

195 阅读8分钟

在我们的Docker教程系列的这一点上,我们已经学会了如何安装Docker,运行一些Nginx容器,在容器中测试MongoDB,启动一个以上的容器,了解Docker网络、DNS、图像、卷,以及更多。你可能已经注意到,在使用Docker命令行界面时,命令可能有些冗长,需要大量记忆要运行哪些命令来完成前面提到的所有任务。这就是Docker Compose的用武之地。通过利用Docker Compose,你可以定义提供服务的多容器应用程序,所有这些都是通过定义一个YAML文件。一旦你的YAML文件完成,你可以运行一个命令来启动一个可能有多个容器、一个网络和一个或多个卷的应用程序。


为什么使用Docker Compose?

Docker Compose是一个命令行工具的组合,与一个配置文件(上面提到的YAML文件)协同工作。为了使用Docker Compose,你需要熟悉构建镜像、运行容器、创建网络以及如何使用卷。软件服务通常不是孤立的。容器是一个单一的进程,而大多数有用的应用程序需要比单一进程更多的东西来提供有用的服务。一个Node容器需要其他的容器,比如Mongo容器或Redis容器来完成有用的工作。Docker Compose为你提供了一种方法,将解决方案的所有部分连接在一起,同时设置网络和卷,而不必在命令行上运行大量的命令。它通过两种方式工作:Docker Compose YAML文件和Docker Compose CLI。


Docker Compose YAML文件

Docker Compose的第一部分是YAML文件。YAML是Yet Another Markup Language的缩写,它是用于Docker Compose配置文件的格式。在YAML文件中,你会指定几件事。

YAML文件定义了。

docker-compose.yml

docker-compose.yml文件有几个[版本],在撰写本文时,版本3是最新的,也是最值得推荐的。版本声明应该始终是docker-compose.yml文件中的第一行。默认使用的文件名是docker-compose.yml,但如果你必须使用-f标志,你可以指定一个不同的名字。在这个文件中,你定义了应用程序堆栈和堆栈中的组件相互作用的方式。

docker-compose.yml模板样本

version: '3.8' 
# Specify the compose format that this file conforms to.

services: 
# Specify the set of containers that your app is composed of.

    servicename1:
    # Same as 'docker container run'
    # Used as the DNS name inside the network.

        build: 
        # Build an image from a Dockerfile

        image: 
        # Tag or partial image ID. Can be local or remote, Compose will attempt 
        # to pull if it doesn't exist locally.
        # Optional if you use 'build:' command

        command:
        # Override the default command.
        # Optional to replace the default CMD specified by the image

        environment: 
        # Add environment variables. You can use either an array or a dictionary
        # Environment variables with only a key are resolved to their values on 
        # the machine Compose is running on. Same as '-e' in 'docker run'

        volumes: 
        # Same as using '-v' with 'docker container run'

        ports: 
        # Expose ports. Either specify both ports (HOST:CONTAINER)
        # or just the container port (a random host port will be chosen).

    servicename2:
        build: 
        image:
        command: 
        environment: 
        volumes: 
        ports: 
        
volumes: # Optional, same as 'docker volume create'
networks: # Optional, same as 'docker network create'

所以你可以看到为什么你需要熟悉图像、容器、环境变量、网络和卷,因为这些正是你在compose YAML文件中定义的内容。服务 "部分是定义你的应用程序的所有容器的地方。在 "服务 "中,我们看到 "servicename1 "和 "servicename2"。这将代表同一网络上的两个不同的容器。同样,你在这里选择的名字也被用作虚拟网络的DNS名称,所以要仔细选择你的名字。在每个 "servicename "里面,是组成每个容器的东西。当然,这些是像图像、命令、变量和使用中的卷的东西。我们在上面添加了注释,以解释YAML文件中每个键的作用,但通常情况下,该文件看起来会更紧凑。这里是没有注释的文件,你可以看到缩进是如何设置层次结构的。

version:  
services: 
    servicename1:
        build:
        image: 
        command:
        environment: 
        volumes: 
        ports: 
    servicename2:
        build:
        image:
        command: 
        environment: 
        volumes: 
        ports: 
volumes: 
networks:


Docker Compose CLI

Docker Compose的第二部分是 **docker-compose**cli工具。这个工具解析YAML配置文件,在最常见的情况下设置本地开发和测试自动化。请注意,Docker Compose在不断发展,也可能在生产或其他方面找到用途。Docker Compose的CLI大大减少了你需要记忆和输入的命令数量。你可以用两个简单的命令走很长的路。

  • docker-compose up
  • docker-compose down

注意:一定要输入docker-compose而不是docker compose,否则你会得到一个错误,即当前上下文中没有 "compose up "命令(默认)

Docker Compose CLI命令的完整清单在这里列出。

PS C:\code\> docker-compose
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f ...] [options] [--] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  -c, --context NAME          Specify a context name
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent (DEPRECATED)
  --env-file PATH             Specify an alternate environment file

Commands:
  build              Build or rebuild services
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show version information and quit


令人敬畏的合成器

好吧,让我们把橡胶放在道路上。Docker Compose有多强大?嗯,考虑一下这个。假设你想试试Django。有很多先决条件需要处理。你必须在你的系统上安装正确版本的Python,你需要用pip安装Django,你需要配置各种变量,你甚至可能需要设置虚拟环境。有了Docker Compose,这就像几个命令一样简单。一个开始使用Docker Compose的好地方是[Awesome Compose]github资源库。这个资源库是一个精心策划的Docker Compose例子列表,为如何使用Compose文件整合不同的服务并使用Docker Compose管理其部署提供了一个起点。其中包括的一些环境有angular、apache-php、django、flask、Minecraft、nginx、golang、react、node、express、vuejs、traefik、java、WordPress等等。

让我们自己试一试几个例子!

PS C:\code> git clone https://github.com/docker/awesome-compose.git
PS C:\code> cd awesome-compose/django
PS C:\code\awesome-compose\django> docker-compose up
Creating network "django_default" with the default driver
Building web
Step 1/8 : FROM python:3.7-alpine
3.7-alpine: Pulling from library/python
188c0c94c7c5: Pull complete
55578f60cda7: Pull complete
3d0ed0f04a02: Pull complete
98762f4040a9: Pull complete
2eeb36df0351: Pull complete
Digest: sha256:61582ae7cccd4c8e64c79fd559e70ef1dbb5a5bddc8fab51cabfad592e7d5bde
Status: Downloaded newer image for python:3.7-alpine
 ---> 4d91c1ce4cc8
Step 2/8 : EXPOSE 8000
 ---> Running in 5c5ddb2d943e
Removing intermediate container 5c5ddb2d943e
 ---> 915a9a087216
Step 3/8 : WORKDIR /app
 ---> Running in d9fea7cfae35
Removing intermediate container d9fea7cfae35
 ---> d6ec540549fe
Step 4/8 : COPY requirements.txt /app
 ---> 7f0a3dfca478
Step 5/8 : RUN pip3 install -r requirements.txt
 ---> Running in d38b7eee00eb
Collecting Django==3.0.7
  Downloading Django-3.0.7-py3-none-any.whl (7.5 MB)
Collecting environs==7.3.1
  Downloading environs-7.3.1-py2.py3-none-any.whl (11 kB)
Collecting pytz
  Downloading pytz-2020.1-py2.py3-none-any.whl (510 kB)
Collecting sqlparse>=0.2.2
  Downloading sqlparse-0.4.1-py3-none-any.whl (42 kB)
Collecting asgiref~=3.2
  Downloading asgiref-3.3.0-py3-none-any.whl (19 kB)
Collecting python-dotenv
  Downloading python_dotenv-0.15.0-py2.py3-none-any.whl (18 kB)
Collecting marshmallow>=2.7.0
  Downloading marshmallow-3.8.0-py2.py3-none-any.whl (46 kB)
Installing collected packages: pytz, sqlparse, asgiref, Django, python-dotenv, marshmallow, environs
Successfully installed Django-3.0.7 asgiref-3.3.0 environs-7.3.1 marshmallow-3.8.0 python-dotenv-0.15.0 pytz-2020.1 sqlparse-0.4.1
Removing intermediate container d38b7eee00eb
 ---> 658522092c7f
Step 6/8 : COPY . /app
 ---> 7b9155a033ae
Step 7/8 : ENTRYPOINT ["python3"]
 ---> Running in 5c4690dcbf9d
Removing intermediate container 5c4690dcbf9d
 ---> b23991bc8043
Step 8/8 : CMD ["manage.py", "runserver", "0.0.0.0:8000"]
 ---> Running in 82d8e32ead64
Removing intermediate container 82d8e32ead64
 ---> 026aa876dacf

Successfully built 026aa876dacf
Successfully tagged django_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating django_web_1 ... done
Attaching to django_web_1
web_1  | Watching for file changes with StatReloader

一切都已建成并准备就绪。在浏览器中访问http://localhost:8000/。
docker django

哇!如果你以前手动完成过,你可以体会到刚才的工作是多么的容易完成。当我们访问该页面时,容器会将访问记录在控制台中,如下图所示。

web_1  | [28/Oct/2020 18:13:48] "GET / HTTP/1.1" 200 16351
web_1  | [28/Oct/2020 18:13:48] "GET /static/admin/css/fonts.css HTTP/1.1" 200 423
web_1  | [28/Oct/2020 18:13:48] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184
web_1  | [28/Oct/2020 18:13:48] "GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1" 200 85692
web_1  | [28/Oct/2020 18:13:48] "GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1" 200 85876
web_1  | Not Found: /favicon.ico
web_1  | [28/Oct/2020 18:13:48] "GET /favicon.ico HTTP/1.1" 404 1974

让我们试试Angular。

PS C:\code\awesome-compose> cd angular
PS C:\code\awesome-compose\angular> docker-compose up

docker angular

那Vue呢?

PS C:\code\awesome-compose> cd vuejs
PS C:\code\awesome-compose\vuejs> docker-compose up

docker vuejs

我一直想试试Flask...

PS C:\code\awesome-compose> cd flask
PS C:\code\awesome-compose\vuejs> docker-compose up

docker flask

在短短几分钟的时间里,我们只用了很少的精力就能启动几个不同的后端和前端框架。这就是Docker Compose的力量。