docker使用经验总结(三、Docker compose基础应用)
六、Docker compose:Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Docker Compose,用户可以使用一个 YAML 文件来定义应用程序所需的所有服务,然后通过一条命令就可以创建并启动这些服务。Docker Compose 可以极大简化多容器应用的管理和部署流程。
它的原理,Docker Compose 主要依赖于两个核心部分:
-
YAML 文件 (
docker-compose.yml
):这个文件用来描述多容器应用的各个服务以及它们之间的关系。通过定义各个服务的镜像、网络、卷、端口映射等,Compose 可以在本地环境或生产环境中一致性地部署应用。 -
Docker Compose CLI:Docker 提供了一个命令行工具
docker-compose
,用户可以通过它来管理使用docker-compose.yml
定义的服务。这些命令包括启动、停止、重启服务,查看日志等。
1. compose.yml:是 Docker Compose 用来定义多容器应用的核心配置文件。它使用 YAML 语法描述服务、网络、卷和其他配置项。下面是一个典型的 docker-compose.yml
文件结构及其各部分的详细说明。
YAML 文件不必须命名为 docker-compose.yml
,但默认情况下,Docker Compose 会在当前目录下查找名为 docker-compose.yml
的文件作为配置文件。如果想使用其他名称的 YAML 文件,也完全可以,只需要在运行 Docker Compose 命令时显式指定该文件的路径和名称。
version: '3.8' # 指定 Docker Compose 文件的版本 services: # 定义服务 web: # 服务名称,可以是任意名称 image: nginx:alpine # 使用的镜像 ports: - "8080:80" # 端口映射:将主机的8080端口映射到容器的80端口 volumes: - ./html:/usr/share/nginx/html # 挂载本地目录到容器中的路径 networks: - webnet # 指定服务使用的网络 depends_on: - app # 指定依赖的服务,确保app服务在web服务之前启动 app: # 另一个服务 build: ./app # 使用本地的Dockerfile构建镜像 command: python app.py # 覆盖默认命令 volumes: - ./app:/app # 挂载本地目录到容器中 environment: - DEBUG=1 # 设置环境变量 networks: - webnet # 指定服务使用的网络 volumes: # 定义数据卷 db_data: # 卷名称,可以在 services 中引用 driver: local # 指定驱动类型,这里是本地驱动 networks: # 定义网络 webnet: # 网络名称 driver: bridge # 指定网络驱动类型
version
version
定义了 docker-compose.yml
文件的版本,版本决定了可以使用的语法和功能。常见版本包括 '3.8'
、'3'
、'2'
等。一般建议使用较新的版本以确保兼容最新功能。
services
services
是最核心的部分,定义了应用中所有的服务。每个服务包含以下常用配置项:
image
: 指定要使用的 Docker 镜像。如果该镜像不存在,Compose 会自动从 Docker Hub 拉取。build
: 如果你希望构建自己的镜像,可以使用build
选项,通常指定一个包含Dockerfile
的路径。ports
: 端口映射,HOST:CONTAINER
格式,将主机的端口映射到容器内的端口。volumes
: 卷挂载,HOST_PATH:CONTAINER_PATH
格式,将主机的目录或文件挂载到容器内。networks
: 指定服务使用的网络。可以在下面的networks
部分定义这些网络。environment
: 设置环境变量,可以在容器内访问这些变量。depends_on
: 指定服务之间的依赖关系,确保某些服务在其他服务启动之前启动。command
: 覆盖默认的容器启动命令。restart
: 定义容器的重启策略(如always
、on-failure
)。
volumes
volumes
用于定义和管理数据卷。数据卷用于持久化数据,即使容器被删除,数据仍然存在。
driver
: 定义卷的驱动类型,默认是local
。
卷可以在 services
中引用,作为数据存储的路径。
networks
networks
用于定义服务之间的网络配置。
driver
: 指定网络驱动类型,常见的有bridge
、overlay
等。
网络可以被多个服务共享,用于服务之间的通信。
2.常用基础命令:Docker Compose 的命令大多数是在项目的根目录下执行的,该目录包含 docker-compose.yml
文件。Docker Compose 会自动在当前目录查找 docker-compose.yml
文件,并根据其中定义的内容执行相关操作。
# 启动应用:命令会读取当前目录下的 docker-compose.yml
文件,并启动所有定义的服务。如果服务所需的镜像不存在,Compose 会自动构建或拉取镜像。如果想在后台运行,可以加上 -d 参数
docker compose up -d
# 启动已经存在的容器,而不会重新创建它们。如果容器已经存在但未运行,此命令可以用来重新启动它们。
docker compose start
# 命令会停止所有正在运行的服务
docker compose stop
# 重启服务,且在不指定服务名称,docker-compose 将重启所有服务
docker compose restart [SERVICE_NAME]
# 列出当前所有服务的状态
docker compose ps
# 看指定服务的日志。如果不指定服务名称,则会查看所有服务的日志
docker compose logs [SERVICE_NAME]
# 运行一次性命令
docker compose run SERVICE_NAME COMMAND
# 在正在运行的容器中执行命令
docker compose exec
# 在 docker-compose.yml 中定义了 build 选项,可以用这个命令来构建镜像
docker compose build
# 停止并删除所有在 docker-compose.yml
中启动的服务、网络和挂载的卷。如果你想删除服务但保留卷数据,可以加上 --volumes
选项
docker compose down --volumes
其中,docker compose up有几个参数要重点讲下
# --scale SERVICE=NUM:指定服务的容器数量,例如可以扩展 web 服务到 3 个副本。 docker compose up --scale web=3 # 制构建服务镜像,即使镜像已经存在 docker compose up --build # 删除不在 docker-compose.yml 文件中的多余容器 docker compose up --remove-orphans
2. 使用流程
- 定义应用环境:在
docker-compose.yml
文件中定义应用程序所需的各个服务。 - 启动应用:使用
docker-compose up
命令启动整个应用,Compose 会根据docker-compose.yml
文件创建并启动所有服务。 - 管理服务:使用
docker-compose
提供的其他命令,如stop
,start
,restart,scale
等来管理已经启动的服务。 - 删除应用:通过
docker-compose down
命令停止并删除所有服务及其相关资源。
3.实践
假设有一个前后端分离的 Python + Django + MySQL + Redis + Vue + Nginx 项目,我们需要为各个组件编写Dockerfile,并在 docker-compose.yml
文件中配置服务。
目录结构:
myproject/ ├── backend/ │ ├── Dockerfile │ ├── myproject/ │ ├── manage.py │ ├── requirements.txt ├── frontend/ │ ├── Dockerfile │ ├── package.json │ ├── src/ │ └── ... ├── nginx/ │ ├── Dockerfile │ ├── nginx.conf ├── docker-compose.yml
3.1 Backend(Django)部分
backend/Dockerfile:
# 使用官方的 Python 镜像作为基础镜像 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 复制依赖文件并安装 COPY requirements.txt /app/ RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . /app/ # 暴露应用端口 EXPOSE 8000 # 运行 Django 开发服务器(你可能需要使用 gunicorn 或者其他 WSGI 服务器在生产环境中) CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]
backend/requirements.txt,
在这个文件中,列出 Django 项目所需的所有 Python 包,如:
Django>=3.2,<4.0
mysqlclient
redis
gunicorn
3.2 Frontend(Vue.js)部分
frontend/Dockerfile:
# 使用 Node.js 镜像作为基础镜像 FROM node:14-alpine # 设置工作目录 WORKDIR /app # 复制依赖文件并安装 COPY package.json yarn.lock /app/ RUN yarn install # 复制源代码 COPY . /app/ # 构建 Vue.js 应用 RUN yarn build # 运行 Vue.js 应用(在开发时可能用 npm run serve;在生产环境中通常用 nginx 或 serve 静态资源) EXPOSE 8080 CMD ["yarn", "serve"]
3.3 Nginx 部分
nginx/Dockerfile:
# 使用官方 Nginx 镜像作为基础镜像 FROM nginx:alpine # 删除默认的配置文件 RUN rm /etc/nginx/conf.d/default.conf # 复制自定义的 Nginx 配置文件 COPY nginx.conf /etc/nginx/conf.d/ # 复制前端构建的静态文件到 Nginx 容器 COPY --from=frontend /app/dist /usr/share/nginx/html # 暴露端口 EXPOSE 80
nginx/nginx.conf: 这是一个 Nginx 配置文件的示例,反向代理到 Django 和 Vue.js 应用
server { listen 80; # 静态文件处理(Vue.js) location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } # 代理请求到 Django 应用 location /api/ { proxy_pass http://backend:8000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
3.4 Docker Compose 文件
docker-compose.yml:
version: '3.8' services: db: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: mydatabase MYSQL_USER: myuser MYSQL_PASSWORD: mypassword volumes: - db_data:/var/lib/mysql networks: - backend redis: image: redis:alpine restart: always networks: - backend backend: build: ./backend command: ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"] volumes: - ./backend:/app ports: - "8000:8000" environment: - DATABASE_HOST=db - DATABASE_PORT=3306 - DATABASE_NAME=mydatabase - DATABASE_USER=myuser - DATABASE_PASSWORD=mypassword - REDIS_HOST=redis - REDIS_PORT=6379 depends_on: - db - redis networks: - backend frontend: build: ./frontend volumes: - ./frontend:/app ports: - "8080:8080" networks: - frontend nginx: build: ./nginx ports: - "80:80" depends_on: - frontend - backend networks: - frontend - backend volumes: db_data: networks: frontend: backend:
启动项目:在 myproject/
目录下运行命令:docker compose up --build -d. 启动所有服务。通过 http://localhost
访问前端应用,后端 API 在 http://localhost/api/
路径下。