docker容器编排(Compose)

概念

docker-compose是官方开源项目,里面有两个很重要的概念,第一个是服务(一个应用的容器,实际上可以包含若干个运行相同镜像的容器实例),第二个是项目(由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml中定义)。

docker是一个轻量化程序,官方推荐每一个docker容器中只运行一个进程,如果一个应用涉及到MySQL,nginx等环境,那我们需要分别为应用,数据库和nginx创建单独的docker容器,然后分别启动容器。但每次启动应用,都需要docker run多次,或者写一些脚本实现,比较繁琐,也不方便镜像管理,所以就产生了docker-compose来解决此问题。

docker-compose文件

image

此字段用于指定容器运行的镜像,以下格式均可以:

bash 复制代码
image: redis
image: redis:5
image: redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7
image: library/redis
image: docker.io/library/redis
image: my_private.registry:5000/redis

command

是给主程序传的参数,可以灵活修改主程序运行的配置。

bash 复制代码
command: ["bundle","exec","thin","-p","3000"]
command: bundle exec thin -p 3000

entrypoint

entrypoint指的是容器的入口程序,比如说redis默认要启动redis-server,busybox默认要启动sh,此字段用于覆盖容器默认的entrypoint。

bash 复制代码
entrypoint: /code/entrypoint.sh
bash 复制代码
entrypoint:
	- php
	- -d
	- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
	- -d
	- memory_limit=-1
	- vendor/bin/phpunit

environment

用于添加环境变量,可以使用数组或者字典,或者布尔值(布尔值需要带引号,否则yml会将其解析为True或者False)。

bash 复制代码
#map语法
environment:
	RACK_ENV: development
	SHOW: "true"
	....
#数组语法
environment:
	- RACK_ENV: development
	- SHOW: "true"
	....

networks

用于指定容器运行的网络。

  • 配置容器网络:这里总共有三个网络,分别为front-tier,back-tier和admin,frontend(前端服务)中有front-tier和back-tier两个网络里的服务进行通信,monitoring(监控服务)只能和admin网络里的服务进行通信,backend(后端服务)可以和back-tier和admin两个网络里的服务进行通信,aliases是取别名,同网络的服务可以通过database来访问backend服务。
bash 复制代码
services:
	 frontend:
		 image: awesome/webapp
		 networks:
			 - front-tier
			 - back-tier
	 monitoring:
		 image: awesome/monitoring
		 networks:
		 	- admin
	 backend:
		 image: awesome/backend
		 networks:
			 back-tier:
			 	aliases:
			 		- database
			 admin:
			 	aliases:
			 		- mysql
networks:
 front-tier:
 back-tier:
 admin:
  • 配置网络驱动和子网信息:这里frontend服务加入了front-tier网络里,并且指定了IP,于是,无论容器重启了多少次,frontend服务在front-tier网络里的IP永远都是172.16.238.10。下方的network是在配置front-tier网络的网段信息,如果ipv4_address没有指定IP,那么要分配的IP就在这个网段里面取。
bash 复制代码
services:
 frontend:
	 image: awesome/webapp
	 networks:
	 	front-tier:
	 		ipv4_address: 172.16.238.10
networks:
 front-tier:
 	ipam:
 		driver: default
 		config:
 			- subnet: "172.16.238.0/24"

volumes

用于将主机的数据卷或者文件挂载到容器里,格式为源路径:目标容器里的路径,这只能指定绑定卷。在完整语法下,是需要用type指定是绑定卷还是命名卷。

bash 复制代码
#短语法
services:
 db:
 	image: postgres:latest
 	volumes:
 		- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
 		- "/localhost/data:/var/lib/postgresql/data"
 
#完整语法
services:
 backend:
 	image: awesome/backend
 	volumes:
 		- type: volume
 #命名卷
 		source: db-data
 		target: /data
 		volume:
 			nocopy: true
 #绑定卷
 		- type: bind
 			source: /var/run/postgres/postgres.sock
 			target: /var/run/postgres/postgres.sock
volumes:
 db-data:

ports

用于指定端口映射。

  • 完整语法:target表示容器内部的端口,host_ip表示宿主机绑定的IP,published表示宿主机对外暴露的端口,protocol表示协议类型,mode表示端口模式(host表示单机直接绑定)。
  • 短语法:"3000"表示容器里的3000端口映射到宿主机随机端口,"3000-3005"表示容器的3000-3005端口映射到宿主机同范围随机端口,"8000:8000"表示容器的8000端口映射到宿主机的8000端口,"9090-9091:8080-8081"表示宿主机9090映射到容器的8080,9091映射到容器的8081,"127.0.0.1:8001:8001"表示仅绑定到宿主机本地的8001,外部无法访问。
bash 复制代码
#完整语法
ports:
 - target: 80
	 host_ip: 127.0.0.1
	 published: 8080
	 protocol: tcp
	 mode: host
 - target: 80
	 host_ip: 127.0.0.1
	 published: 8000-9000
	 protocol: tcp
	 mode: host
#短语法
ports:
 - "3000"
 - "3000-3005"
 - "8000:8000"
 - "9090-9091:8080-8081"
 - "49100:22"
 - "127.0.0.1:8001:8001"
 - "127.0.0.1:5000-5010:5000-5010"
 - "6060:6060/udp"

expose

用于暴露端口,但不映射到宿主机,只有在同网络下其他容器用容器名+这些端口进行访问。

bash 复制代码
expose:
	- "3000"
	- "8000"

build

用于指定为构建镜像的上下文路径。

  • 短语法:构建上下文路径为./dir,docker会自动在./dir目录下查找默认名为Dockfile的文件来构建镜像。
bash 复制代码
version: "3.7"
services:
 webapp:
 	build: ./dir
  • 完整语法:context用于指定上下文路径,dockerfile用于指定构建镜像的Dockerfile文件名,args是传递给dockerfile的构建参数,labels为镜像添加元数据标签,用于标识镜像用途,归属等信息,方便管理和检索。
bash 复制代码
version: "3.7"
services:
 webapp:
	 build:
		 context: ./dir
		 dockerfile: Dockerfile-alternate
		 args:
		 	buildno: 1
		 labels:
			 - "com.example.description=Accounting webapp"
			 - "com.example.department=Finance"
			 - "com.example.label-with-empty-value"

depends_on

用于设置依赖关系。

  • docker compose up是指以依赖性顺序启动服务,在下列例子中,会先启动db和redis,才会启动web。docker compose up server自动包含server的依赖项。比如说docker compose up web还将创建并且启动db和redis。docker compose stop是指按依赖关系停止服务,在下列例子中,web在db和redis之前停止。
bash 复制代码
version: "3.7"
services:
	web:
	 build: .
	 depends_on:
	 	- db
 		- redis
	redis:
		image: redis
	db:
 		image: postgres
services:
	web:
		build: .
		depends_on:
			db:
				condition: service_healthy
			redis:
				condition: service_started
	redis:
		image: redis
	db:
		image: postgres
  • health check:会确保MySQL服务完全启动以后,才会启动web服务,test是健康检查的命令,尝试使用root账号多路并执行select 1,如果命令成功返回,就认为服务健康,interval是指每10s执行一次健康检查,timeout是指单次检查超时时间为5s,retries表示最多尝试10次,如果10次都失败,将服务标记为不健康。
bash 复制代码
version: "3.8"
services:
	web:
		image: nginx:1.24.0
		environment:
			TEST: 1
		depends_on:
			mysql:
				condition: service_healthy 
	mysql:
		image: mysql:5.7
		environment:
			MYSQL_ROOT_PASSWORD: "bit@123"
		volumes:
			- /data/maxhou/mysqldata/varlib/:/var/lib/mysql
		healthcheck:
			test: mysql --user=root --password='bit@123' -e "SELECT 1;"
			interval: 10s
			timeout: 5s
			retries: 10

env_file

用于从文件添加环境变量,可以是单个值或者列表的多个值。

  • 用于加载单前目录下名为.env的文件,将文件中所有键值对作为环境变量注入容器。
bash 复制代码
env_file: .env
  • 按顺序加载多个.env文件,后加载的同名环境变量会覆盖先加载的同名变量。
bash 复制代码
env_file:
	- ./common.env
	- ./apps/web.env
	- /opt/secrets.env

命令

对于compose来说,基本的使用格式是:

bash 复制代码
docker compose [options] command [args]

-f或者--file指定使用的compose模板文件,默认为docker-compose.yml,可以进行多次指定,默认会用后面的文件覆盖前面文件的同名配置。

-p或者--project-name指定项目名称,默认将当前执行命令所在目录名称作为项目名称。

up

用于自动构建镜像,创建 / 重建容器,启动服务并关联依赖,一键启动整个项目。

bash 复制代码
docker compose up [options] [service...]

-d表示在后台运行服务器

--force-recreate强制重新创建容器,不能与--no-recreate同时使用

--no-recreate如果容器存在了,则不能重新创建

down

用于停止所有容器,并删除出容器和网络

bash 复制代码
docker compose down [options] [service...]

-v或者--volumes删除容器同时删除目录映射

run

用于在指定服务容器上执行相关的命令,例如启动了一个Ubuntu服务器,执行ping docker.com的命令。

bash 复制代码
docker compose run ubuntu ping docker.com
bash 复制代码
docker composerun [ooptions] service [command[args]]

-d表示在后台运行容器

--name 名字 用于为容器指定一个名字

--entrypoint cmd默认覆盖容器的启动命令

-e key=val用于设置环境变量值,可多次使用选项来设置多个环境变量

-u用于指定运行容器的用户名或者id

--rm表示运行命令后自动删除容器

-p映射容器端口到本地主机

操作

基本操作

  • 创建compose目录。
bash 复制代码
mkdir -p /data/mydir/compose/base
cd /data/mydir/compose/base
  • 进入base目录创建docker-compose.yml文件
bash 复制代码
vim docker-compose.yml
  • 输入内容
bash 复制代码
version: 3.8
services:
	web:
		image: nginx:1.24.0
		environment:
			TEST: 1
	ports:
		- 8979:80
	networks:
		- mytestnet
 	volumes:
 		- ./mynginxhome:/usr/share/nginx/html
 	depends_on:
 		mysql:
 			condition: service_healthy 
 		redis:
 			condition: service_healthy
 	mysql:
	 image: mysql:5.7
	 environment:
	 	MYSQL_ROOT_PASSWORD: "bit@123"
	 networks:
	 	- mytestnet
	 volumes:
	 	- /data/maxhou/mysqldata/varlib/:/var/lib/mysql
	 healthcheck:
		 test: mysql --user=root --password='bit@123' -e "SELECT 1;"
		 interval: 10s
		 timeout: 5s
		 retries: 10
 redis:
	 image: redis:7
	 networks:
	 	- mytestnet
	 healthcheck:
		 test: redis-cli ping
		 interval: 10s
		 timeout: 5s
		 retries: 10
networks:
 mytestnet:
  • 检查语法格式,修改错误信息
bash 复制代码
docker compose config
  • 创建首页目录,编辑首页内容
bash 复制代码
mkdir -p ./mynginxhome
cd mynginxhome
echo "hello world" > index.html
cd ..
  • 启动服务,通过浏览器页面访问
bash 复制代码
docker compose up -d


  • 停止服务,启动服务,删除服务
bash 复制代码
docker compose stop 
docker compose start
docker compose down

部署自定义服务

  • 创建一个项目文件夹demojdbc
  • 设计一个表,写入两条数据,在demojdbc文件夹下插入新文件为init.sql,将文件导入数据库里使用
bash 复制代码
drop database if exists test;
create database test default character set utf8mb4;
use test;
create table users(
	sno int(11) default null,
	sname varchar(50) default null
)engine=InnoDB default charset=utf8mb4;
insert into users (sno,sname) values (1,'zhangsan'),(2,'lisi');
bash 复制代码
mysql -u root -p < init.sql
  • 在demojdbc文件夹下创建一个pox.xml,配置maven项目。
bash 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
        <relativePath/>
    </parent>

    <groupId>com.bit</groupId>
    <artifactId>demojdbc</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demojdbc</name>
    <description>demojdbc</description>

    <properties>
        <java.version>8</java.version>
    </properties>

    <dependencies>
        <!-- Spring Boot JDBC -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- MySQL 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 创建java目录文件结构
bash 复制代码
mkdir -p src/main/java/com/bit/demojdbc
mkdir -p src/main/resources
  • 添加启动类
bash 复制代码
vim src/main/java/com/bit/demojdbc/DemojdbcApplication.java
java 复制代码
package com.bit.demojdbc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemojdbcApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemojdbcApplication.class, args);
    }
}
  • 配置数据库信息
bash 复制代码
vim src/main/resources/application.properties
bash 复制代码
server.port=8080
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=你的密码
  • 配置用户控制器,不再设计mapper内容,而是通过jdbc直接完成操作。
java 复制代码
package com.bit.demojdbc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @RequestMapping("/list")
    @ResponseBody
    public Object Users(){
        return jdbcTemplate.queryForList("select * from users");
    }
}
  • maven打包
bash 复制代码
mvn clean package -Dmaven.test.skip=true
  • 运行包,在浏览器中访问8080端口正常访问
bash 复制代码
java -jar target/demojdbc-0.0.1-SNAPSHOT.jar


  • 编写docker-compose.yml
bash 复制代码
version: "3.8"

services:
  web:
    image: nginx:1.24.0
    ports:
      - "8112:80"
    networks:
      - myhellonet
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      mysys:
        condition: service_started

  mysys:
    image: openjdk:8
    depends_on:
      mysql:
        condition: service_healthy
    command: java -jar /app/demojdbc-0.0.1-SNAPSHOT.jar
    volumes:
      - ./app/:/app/
    networks:
      - myhellonet

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: "root"
    networks:
      - myhellonet
    volumes:
      - ./mysql/varlib/:/var/lib/mysql
      - ./mysql/init/:/docker-entrypoint-initdb.d/
    healthcheck:
      test: mysql --user=root --password='root' -e "SELECT 1;"
      interval: 10s
      timeout: 5s
      retries: 10

networks:
  myhellonet:
  • 创建工程和卷目录
bash 复制代码
mkdir -p /data/maxhou/mycompose/prj16
cd /data/maxhou/mycompose/prj16
mkdir -p ./nginx/conf.d
mkdir -p ./app
mkdir -p ./mysql/varlib/
mkdir -p ./mysql/init/
  • 将nginx反向代理配置bit.conf放入到./nginx/conf.d
bash 复制代码
server {
    listen 80;
    location / {
        # 转发到 mysys 容器的 8080 端口
        proxy_pass http://mysys:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
  • 将数据库初始化文件init.sql放入mysql/init目录,把应用jar包放到./app目录
  • 启动项目,用浏览器访问nginx,可以看到用户信息正常返回。

部署WordPress服务

  • 编写docker-compose.yml
bash 复制代码
version: '3.8'

services:
  db:
    image: mysql:5.7
    volumes:
      - ./db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: mywordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    healthcheck:
      test: mysql --user=root --password='mywordpress' -e "SELECT 1;"
      interval: 10s
      timeout: 5s
      retries: 10

  wordpress:
    depends_on:
      db:
        condition: service_healthy
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    volumes:
      - ./wordpress:/var/www/html
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
  • 运行站点,访问web界面
bash 复制代码
docker compose up -d
  • 删除,释放空间
bash 复制代码
docker compose down
相关推荐
小陈工2 小时前
Python开源代码管理避坑实战:从Git高级操作到Docker环境配置
开发语言·git·python·安全·docker·开源·源代码管理
kft13142 小时前
Docker 部署 3 节点 Consul 集群
docker·容器·consul
dustcell.2 小时前
企业级高可用电商平台实战项目设计
运维·redis·nginx·docker·web·lvs·haproxy
AI服务老曹2 小时前
异构计算时代的架构突围:基于 Docker 的 AI 视频平台如何实现 X86/ARM 与 GPU/NPU 全兼容(源码交付)
人工智能·docker·架构
returnthem4 小时前
K8S核心组件
云原生·容器·kubernetes
AI自动化工坊11 小时前
DeerFlow 2.0实战指南:生产级AI Agent框架的Docker化部署与并行编排
人工智能·docker·ai·容器·开源
行者-全栈开发13 小时前
容器化时代来临 - Docker 技术演进与核心价值
运维·docker·容器·cicd·自动化构建·容器化时代
AI自动化工坊13 小时前
GitAgent实战解析:用Docker思想解决AI Agent框架碎片化问题,降低80%迁移成本
人工智能·docker·ai·容器·开源
成为你的宁宁16 小时前
【Docker 与 Docker-Compose 实战:从零开始容器化部署若依项目,从单容器分步运行到 Compose 一键编排】
运维·docker·容器·docker-compose