什么是Docker-Compose?

案例下载

Compose 是一个用于定义和运行多容器 Docker 应用程序的工具,俗称容器编排。使用 Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用一个命令,您可以从您的配置中创建并启动所有服务。要了解有关 Compose 的所有功能的更多信息,请参阅功能列表

Compose 适用于所有环境:生产、登台、开发、测试以及 CI 工作流程。您可以在常见用例中了解有关每个案例的更多信息。

使用 Compose 基本上是一个三步过程:

  1. 使用 a 定义您的应用程序的环境,Dockerfile以便可以在任何地方复制它。
  2. 定义构成您的应用程序的服务,docker-compose.yml 以便它们可以在隔离环境中一起运行。
  3. 运行docker compose upDocker compose 命令启动并运行您的整个应用程序。您也可以docker-compose up使用 Compose Standalone(docker-compose二进制)运行。
docker-compose.yml文件开起来像这样
version: "3.9"  # optional since v1.27.0
services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    depends_on:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

安装Docker-Compose

Debin/Ubuntu
 sudo apt-get update
 sudo apt-get install docker-compose-plugin
 
 #卸载
 sudo apt-get remove docker-compose-plugin
Centos
 sudo yum update
 sudo yum install docker-compose-plugin
 
 #卸载
 sudo yum remove docker-compose-plugin
Alpine
apk update
apk add docker-compose

#卸载
apk del docker-compose
其他Linux下载二进制文件安装
curl -SL https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

#卸载
rm /usr/local/lib/docker/cli-plugins/docker-compose
验证是否安装成功 docker-compose version
docker-compose
localhost:~# docker-compose version
docker-compose version 1.29.2, build unknown
docker-py version: 5.0.3
CPython version: 3.10.5
OpenSSL version: OpenSSL 1.1.1q  5 Jul 2022

Demo演示

创建项目文件夹
#为项目创建一个文件夹并进入
mkdir composetest
cd composetest
编写一个程序文件 app.py
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=5000)
编写依赖文件 requirements.txt
flask
redis
编写Dockerfile
# syntax=docker/dockerfile:1
#导入python:3.7
FROM python:3.7
#设置工作路径为/code
WORKDIR /code
#拷贝依赖列表
COPY requirements.txt requirements.txt
#安装依赖
RUN pip install -r requirements.txt-i "http://mirrors.aliyun.com/pypi/simple" --trusted-host "mirrors.aliyun.com"
#公开端口
EXPOSE 5000
#复制当前目录下所有文件
COPY . .
#运行
CMD ["python","app.py"]
编写 docker-compose.yml
version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
  redis:
    image: "redis:alpine"
    
#version: "3.9"		指定Docker-compose最低运行版本
#services:			定义服务 web 和 redis
#web 服务又当前目录下的Dockerfile文件构建并将5000端口映射到主机8000端口并将工作目录挂载到主机
#redis	指定镜像为 redis:alpine

在您的项目目录中,通过运行docker compose up
localhost:~/test# docker-compose up
Creating network "test_default" with the default driver
Creating test_web_1   ... done
Creating test_redis_1 ... done
Attaching to test_web_1, test_redis_1
redis_1  | 1:C 14 Sep 2022 05:31:15.221 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 14 Sep 2022 05:31:15.221 # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 14 Sep 2022 05:31:15.221 # 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 14 Sep 2022 05:31:15.222 * monotonic clock: POSIX clock_gettime
redis_1  | 1:M 14 Sep 2022 05:31:15.223 * Running mode=standalone, port=6379.
redis_1  | 1:M 14 Sep 2022 05:31:15.223 # Server initialized
redis_1  | 1:M 14 Sep 2022 05:31:15.223 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1  | 1:M 14 Sep 2022 05:31:15.223 * Ready to accept connections
web_1    |  * Serving Flask app 'app'
web_1    |  * Debug mode: off
web_1    | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
web_1    |  * Running on all addresses (0.0.0.0)
web_1    |  * Running on http://127.0.0.1:5000
web_1    |  * Running on http://172.21.0.3:5000
web_1    | Press CTRL+C to quit
#启动成功
在后台运行 docker-compose up -d
localhost:~/test# docker-compose up -d
Starting test_redis_1 ... done
Starting test_web_1   ... done
停止运行
localhost:~/test# docker-compose down
Stopping test_web_1   ... done
Stopping test_redis_1 ... done
Removing test_web_1   ... done
Removing test_redis_1 ... done
Removing network test_default

docker-compose项目 快捷指令

docker-compose up -d			#启动并后台运行
docker-compose stop				#停止
docker-compose strat			#开始
docker-compose restart			#重启项目
docker-compose down				#停止并删除容器
docker-compose down --volumes	#删除挂载卷

Docker-Compose文件 编写规则

Docker-Compose文件编写规则繁琐且关键字繁多,核心为三层结构

#1.version 定义版本信息,根据服务器Docker引擎版本填写
version: '3.8'
#2.service 用于定以容器信息
service:
  web-Core:											#定义一个服务
    container_name: my-web-container		 		#容器名称
    image:python:3.8.10								#使用镜像
    restart: always									#容器重启策略 
    ports:											#公开端口
      - "8000:5000"
    volumes:										#挂载卷,可以匿名挂载
      - web-Core:/root/app
    							#容器启动后运行命令,可覆盖Dockerfile内的CMD
	command: uwsgi --ini uwsgi.ini  #等同command: ["uwsgi","--ini","uwsgi.ini"]
	devices:										#映射设备
      - "/dev/ttyUSB0:/dev/ttyUSB0"
      - "/dev/sda:/dev/xvda:rwm"
    dns:											#设置容器内DNS地址					
  	  - 114.114.114.114
  	  - 8.8.8.8
  	extends:										#延迟启动,等待别的容器启动完成
      service: 
        - mysql
    environment:									#设置容器内环境变量
      - RACK_ENV=development
  	  - SHOW=true
      - USER_INPUT
    external_links:									#链接外部容器
  	  - redis
  	  - database:mysql
  	  - database:postgresql
  	extra_hosts:									#链接外部服务器
 	  - "somehost:162.242.195.82"
  	  - "otherhost:50.31.209.229"
  	
  mysql:
    image:mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=passwd
    volumes:
      - mysql:/var/lib/mysql
    
    
#3.其他配置,项目不需要也可以不填写
volumes:	#定义挂载卷信息
  mysql:
  web-Core:
  
networks:	#定义网络信息
configs:	#定义配置信息

Docker-Compose文件 其他撰写操作

静态分配IP地址
services:
  frontend:
    image: awesome/webapp
    networks:		#指定网络名称并设置ip地址
      front-tier:
        ipv4_address: 172.16.238.10
        ipv6_address: 2001:3984:3989::10

networks:			#定义一个名为front-tier的网络
  front-tier:
    ipam:
      driver: default
      config:
        - subnet: "172.16.238.0/24"
        - subnet: "2001:3984:3989::/64"
桥接到物理网卡
services:
  app:
    image: busybox
    command: top
    networks:
      app_net:
        link_local_ips:
          - 57.123.22.11
          - 57.123.22.13
networks:
  app_net:	#bridge	#网桥模式
    driver: bridge

Docker-Compose 案例讲解

owncloud + mariadb
version: '3.1'

services:

  owncloud:
    image: owncloud
    restart: always
    ports:
      - 8080:80

  mysql:
    image: mariadb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: passwd

#定义一个owncloud服务,镜像为owncloud最新版,容器始终启动,映射容器80端口到主机8080。
#定义一个mysql服务,镜像为mariadb最新版,容器始终启动,设置一个环境变量为数据库密码。
werdpress + mysql
version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

#定义两个服务wordpress和db
#wordpress映射80端口到主机8080,设置环境变量为数据库信息挂载/var/www/html目录到wordpress挂载卷
#db设置环境变量为数据库名称/用户名/数据库密码/root密码//var/lib/mysql目录到db挂载卷
 
nextcloud+mariadb+nginx
version: '2'

volumes:
  nextcloud:
  db:

services:
  db:
    image: mariadb:10.5
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=
      - MYSQL_PASSWORD=
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    image: nextcloud:fpm
    restart: always
    links:
      - db
    volumes:
      - nextcloud:/var/www/html
    environment:
      - MYSQL_PASSWORD=
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db

  web:
    image: nginx
    restart: always
    ports:
      - 8080:80
    links:
      - app
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    volumes_from:
      - app
mysql+adminer
# Use root/example as user/password credentials

version: '3.1'

services:

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

  db:
    image: mysql:5.6
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
      
#数据库设置环境变量 ROOT密码
#adminer 容器自动启动
mariadb+phpmyadmin
version: '3.1'

services:
  db:
    image: mariadb:10.3
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: passwd

  phpmyadmin:
    image: phpmyadmin
    restart: always
    ports:
      - 38080:80