Linux中Docker Compose介绍和使用

一、Compose 介绍

1.1 基础知识

思考: 现有 docker 进行项目部署存在的问题?

对于现代应用来说,大多都是通过很多的微服务互相协同组成的一个完整应用。

例如,订单管理、用户管理、品类管理、缓存服务、数据库服务等,它们构成了一个电商平台的应用。

而部署和管理大量的服务容器是一件非常繁琐的事情。而 Docker Compose 就是解决这类问题的。

docker 容器提供了一种封装格式,可以将应用和其运行环境封装在一起,但是在线上实践过程中,应用和应用之间难免要产生依赖,一个上游的应用,可能会依赖于下游的一个或者几个应用给其提供数据。

正所谓一个好汉三个帮,现实情况中,一个服务部署完成之后,对外不产生依赖的情况还是比较少的,但是 docker 在开始设计的时候没有过多考虑到容器之间依赖关系的处理。

1、为了完成一个完整项目势必用到N多个容器(一个容器只运行一个进程)配合完成项目中业务开发。

一旦引入N多个容器,容器之间就会形成某种依赖,也就意味某个容器或某些容器的运行需要其他容器优先启动之后才能正常运行。

容器的编排显得至关重要,容器的运行一定要有先后顺序。

2、现在这种方式使用容器,没有办法站在项目的角度将一个项目用到的一组容器划分到一起,日后难点在于项目的多服务器部署。

比如项目在当前服务器上运行成功,需要将项目再部署到另一台服务器上,但我们不清楚哪组容器是项目引用的,哪组容器是别的引用的。

Docker Compose 是一个需要在 Docker 主机上进行安装的 Docker 容器编排外部工具。

其并不是通过脚本或各种冗长的 Docker 命令来将应用组件组织起来,而是通过一个声明式的配置文件描述整个应用,然后通过一条命令完成应用部署。

部署成功后,还可通过一系列简单命令实现对其完整生命周期的管理。

1.2 Compose 安装

注意:只有 Linux 平台上在安装docker时没有安装docker-compose,windows、macos平台安装docker时会自动安装docker-compose。

下载 docker-compose文件:

官网下载地址:

复制代码
wget https://github.com/docker/compose/releases/download/v2.36.2/docker-compose-linux-x86_64

更改名字将其放入进bin目录中,使用时就不用全路径

复制代码
mv docker-compose-linux-x86_64 docker-compose

mv docker-compose /usr/local/bin/docker-compose

赋予执行权限:

复制代码
sudo chmod +x /usr/local/bin/docker-compose

使用命令 docker-compose -v 查看 compose 版本:

1.3 Compose 文件内容

文件简介

Docker Compose 使用 YAML 文件来定义服务。官方推荐的默认文件名为 compose.yml ,但同时也支持 docker-compose.yml。

由于一个 compose 文件中定义的为一个项目的所有服务,所以一般为在创建 compose 文件之前先新建一个目录,目录名称一般为项目名称,然后再将项目所需的所有镜像、微服务的 Dockerfile 放入该目录,并在该目录中新建 compose 文件。

docker-compose.yml

├── version: '指定文件格式版本'

├── services:

│ │

│ ├── service_name_1:

│ │ ├── build: ./dir_or_dockerfile_details

│ │ ├── image: "镜像名或路径"

│ │ ├── ports:

│ │ │ └── "主机端口:容器端口"

│ │ ├── networks:

│ │ │ └── network_name

│ │ ├── volumes:

│ │ │ └── "/宿主机路径:/容器内路径"

│ │ ├── environment:

│ │ │ └── ["环境变量名=值", ...]

│ │ └── deploy: (仅适用于 Docker Swarm)

│ │ ├── replicas: 数量

│ │ └── mode: 设置模式(global/replicated)

│ │

│ └── service_name_2:

├── networks:

│ ├── network_name_1:

│ └── network_name_2:

└── volumes:

├── volume_name_1:

└── volume_name_2:

version

用于指定 Docker Compose 文件格式的版本。不同的版本可能支持不同的特性集。

选择合适的版本可以确保使用到特定的功能或语法。

用于指定当前 docker-compose 文件遵循的规范版本。这决定了哪些功能和配置选项是可用的。

version: '3'
version: '2.4'

从 Docker Compose v2 开始(尤其是 v2.20+),官方已经 不再推荐使用 version: 字段。

因为这个字段现在已经被 Compose CLI 插件自动处理,不再是必须的了。

services

定义了应用服务的集合。

每个服务都代表了一个容器,这些服务可以通过 Docker Compose 来管理它们的生命周期、网络、存储等。

用于定义一个或多个服务,每个服务对应于一个独立运行的容器。

复制代码
services:
  web:
    image: "nginx"

services:
  db:
    build: ./dir
build

用于指定一个 Dockerfile 的路径。

而该 Dockerfile 则是用于创建当前服务镜像的。

这个路径可以是以斜杠(/)开头的绝对路径,也可以是相对于当前 compose 文件的、以点(.)号开头的相对路径。

如果 Dockerfile 文件名不是默认名称,则需要通过 build 下的 context 属性指定路径,dockerfile 属性指定文件名。

build: /test
build:

context: /test

dockerfile: a.dockerfile

image

用于指定要使用的 Docker 镜像。

这个镜像可以是从本地获取的,也可以是从远程仓库拉取的。

使用已经构建好的镜像能够快速部署服务。

如果使用现成的镜像(通过 image 指定),而不需要从 Dockerfile 构建镜像,那么不需要写 build 这个属性。
image: "ubuntu"
image: "myregistry.com/myapp/myimage:v1"

ports

用于映射端口,使得容器内的服务可以通过主机访问。

这种映射允许外部流量到达容器内部的服务。

复制代码
ports:
 - "5000:5000"

ports:

  • "8000-8010:9000-9010"
networks

用于定义服务所属的网络。

这允许不同的服务相互通信,同时也控制了服务之间的可见性和隔离性。

networks:

  • some-network
    networks:

  • front-tier

  • back-tier

volumes

用于挂载路径作为卷,使得数据持久化或者在不同容器间共享数据。

这种方式对于保存数据库或者其他需要长期保存的数据特别有用。

volumes:

  • /var/lib/mysql:/data
    volumes:

  • ./cache:/tmp/cache

environment

用于设置环境变量,可以用来配置应用程序的行为而不必修改代码。

这对于根据不同的部署环境调整配置非常有用。

environment:

  • MYSQL_ROOT_PASSWORD=my-secret-pw
    environment:

POSTGRES_USER: user

POSTGRES_PASSWORD: pass

deploy

仅适用于使用 docker stack deploy 命令的情况,它配置了服务如何在 swarm 集群中部署。

这包括副本数量、更新策略等高级配置。

deploy:

replicas: 5
deploy:

mode: global

depends_on

它确保某些服务在其他服务启动之前已经被启动。

启动顺序:Docker Compose 会按照 depends_on 中指定的顺序来启动服务。

不等待就绪状态:仅保证被依赖的服务先启动,但不会等待该服务的应用程序完全就绪(如数据库服务完全初始化完成)。

这意味着如果一个服务依赖于另一个服务的数据准备情况,需要使用其他机制来确保服务间的正确性,比如健康检查或自定义脚本。

version: '3'

services:

web:

build: .

depends_on:

  • db

ports:

  • "80:80"

db:

image: mysql:8.0

environment:

MYSQL_ROOT_PASSWORD: example

volumes

volumes 元素用于定义 Docker 卷。

使用卷可以让你的数据持久化,并且可以在多个容器之间共享或重用这些数据。

此外,卷还可以帮助你绕过 Union File System 的文件系统层限制,从而提高性能。

version: '3'

services:

db:

image: "mysql:5.7"

volumes:

  • db-data:/var/lib/mysql

volumes:

db-data: # 命名卷

这里我们定义了一个名为 db-data 的命名卷,并将其挂载到容器的 /var/lib/mysql 路径下。

networks

networks 元素用于定义自定义网络,使得服务能够通过网络相互通信。

默认情况下,Docker Compose 自动创建一个网络来允许你的服务互相通信,在这种情况下,所有服务都将加入到默认网络中,并且可以通过服务名称相互访问。

version: '3'

services:

web:

build: .

ports:

  • "5000:5000"

redis:

image: "redis:alpine"

networks:

default:

但是有时可能想要更多控制或者创建多个隔离的网络。

version: '3'

services:

proxy:

build: ./proxy

networks:

  • frontend

app:

build: ./app

networks:

  • frontend

  • backend

db:

image: "mysql:5.7"

networks:

  • backend

networks:

frontend:

driver: bridge

backend:

driver: bridge

1.4 Compose 命令

常用命令

创建一个test文件夹,在里面vim一个docker-compose.yml文件

复制代码
services:
  web1:
    image: nginx:latest
    container_name: web1
    ports:
      - "8080:80"
    volumes:
      - ./web1/html:/usr/share/nginx/html
    networks:
      - app-network
  web2:
    image: nginx:latest
    container_name: web2
    ports:
      - "8081:80"
    volumes:
      - ./web2/html:/usr/share/nginx/html
    networks:
      - app-network
  db1:
    image: mysql:8.0
    container_name: db1
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "3306:3306"
    volumes:
      - db1_data:/var/lib/mysql
    networks:
      - app-network
  db2:
    image: mysql:8.0
    container_name: db2
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "3307:3306"
    volumes:
      - db2_data:/var/lib/mysql
    networks:
      - app-network
volumes:
  db1_data:
  db2_data:
networks:
  app-network:
    driver: bridge

创建并启动容器

复制代码
docker-compose up

使用 docker-compose.yml 文件中的配置创建并启动所有服务。加上 -d 参数可以在后台运行。

复制代码
docker-compose up -d

停止服务

复制代码
docker-compose stop

停止正在运行的服务而不删除它们。

停止并移除容器、网络

复制代码
docker-compose down

停止并移除由 docker-compose.yml 定义的所有容器、网络以及默认情况下不会移除卷。

查看服务状态

复制代码
docker-compose ps

显示由 docker-compose.yml 文件定义的所有服务的状态。

列出镜像

复制代码
docker-compose images

列出 Compose 文件中服务使用的镜像。

日志相关命令
复制代码
docker-compose run [SERVICE] [COMMAND]

查看服务日志

复制代码
docker-compose logs <服务名>

显示由 docker-compose.yml 文件定义的所有服务的日志输出。加上 -f 参数可以实时跟踪日志更新。

复制代码
docker-compose logs -f
运行一次性命令
复制代码
docker-compose run [SERVICE] [COMMAND]

在服务的容器内执行一个命令。这对于调试非常有用。

复制代码
docker-compose run web bash
网络与卷管理

创建网络

复制代码
docker-compose create

只创建网络和卷,但不启动服务。

重启服务

复制代码
docker-compose restart
高级命令

拉取服务镜像

复制代码
docker-compose pull

拉取服务依赖的所有镜像。

执行命令

复制代码
docker-compose exec [SERVICE] [COMMAND]

进入正在运行的服务容器,并执行命令。这类似于 docker exec 命令。

示例:

复制代码
docker-compose exec web sh

检查配置

复制代码
docker-compose config

验证并查看 docker-compose.yml 文件的有效配置。

指定文件:使用 -f 参数指定不同的 Compose 文件名。

复制代码
docker-compose -f alternate-compose.yml up

1.5 配置一主两从架构

复制代码
services:
  master:
    image: mysql:8.0
    container_name: mysql_master
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - /data/mysql/master/conf/my.cnf:/etc/my.cnf
      - /data/mysql/master/data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - mysql-network

  slave1:
    image: mysql:8.0
    container_name: mysql_slave1
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - /data/mysql/slave1/conf/my.cnf:/etc/my.cnf
      - /data/mysql/slave1/data:/var/lib/mysql
    ports:
      - "3307:3306"
    depends_on:
      - master
    networks:
      - mysql-network

  slave2:
    image: mysql:8.0
    container_name: mysql_slave2
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - /data/mysql/slave2/conf/my.cnf:/etc/my.cnf
      - /data/mysql/slave2/data:/var/lib/mysql
    ports:
      - "3308:3306"
    depends_on:
      - master
    networks:
      - mysql-network

networks:
  mysql-network:
    driver: bridge

1.6 配置nginx与后端集群

我们使用 Docker Compose 来实现以下架构:

  • 1 个 Nginx 容器:负责反向代理和负载均衡;

  • 3 个 Java 后端服务容器(backend1, backend2, backend3);

  • 所有服务都在同一个自定义 Docker 网络中通信;

  • 不需要构建自定义 Nginx 镜像,直接使用官方镜像 + 挂载配置文件;

  • 使用 openjdk:8 构建后端服务镜像。

文件结构:

test/

├── docker-compose.yml

├── dockerfile

├── html

├── java

│ └── msg.jar

└── nginx

└── default.conf

可以先将80端口的防火墙打开或者直接关闭防火墙

第一步:将前端压缩包解压到html文件夹中

复制代码
unzip html.zip -d ./html

第二步:创建文件夹java,进入 java 文件夹

将后端文件放到 java 文件夹中

第三步:创建nginx文件夹,进入nginx文件夹

复制代码
vim default.comf

-- 放入下面的
upstream tomcatList {
    server backend1:8081 weight=1;
    server backend2:8081 weight=1;
    server backend3:8081 weight=1;
}

server {

    listen  80;
    server_name  localhost;

    location / {
        root   /etc/nginx/html/;
        index  index.html index.htm;
    }

    location ~^/api/ {
        rewrite ^/api/(.*)$ /$1 break;
        proxy_pass  http://tomcatList;
        proxy_redirect default;
    }

}

第四步:在 test 文件夹,编辑vim dockerfile

复制代码
FROM openjdk:8-jdk-alpine

WORKDIR /app

COPY ./java/msg.jar app.jar

-- 这句可以删掉
EXPOSE 8081

ENTRYPOINT ["java", "-jar", "app.jar"]

第五步:编写docker-compose.yml,在test文件夹中

复制代码
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      - /test/nginx/default.conf:/etc/nginx/conf.d/default.conf
      - /test/html:/etc/nginx/html
    depends_on:
      - backend1
      - backend2
      - backend3
    networks:
      - app-network

  backend1:
    build:
      context: .
      dockerfile: dockerfile
    container_name: backend1
    networks:
      - app-network

  backend2:
    build:
      context: .
      dockerfile: dockerfile
    container_name: backend2
    networks:
      - app-network

  backend3:
    build:
      context: . 
      dockerfile: dockerfile
    container_name: backend3
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

第六步:启动容器

复制代码
docker-compose up -d

第七步:查看创建的网络

复制代码
docker network ls

第八步:查看该网络的详情信息

复制代码
docker inspect 【网络name】

第九步:访问nginx

复制代码
curl 【ip】

1.7 compose重启策略

Docker Compose 支持几种不同的重启策略,可以根据的需求选择合适的策略。

常用的重启策略

  • no:默认策略,不自动重启容器。

  • always:无论退出状态如何,总是尝试重启容器。如果 Docker 守护进程重启,也会尝试重启容器。

  • on-failure:仅当容器以非零退出代码终止时才重启容器。可以指定最大重试次数,例如 on-failure:5

  • unless-stopped:总是重启容器,除非容器被手动停止(使用 docker stop 或通过 Docker API 停止)。

    services:
    nginx:
    image: nginx:latest
    container_name: nginx
    ports:
    - "80:80"
    volumes:
    - /data/project/nginx/default.conf:/etc/nginx/conf.d/default.conf
    - /data/project/html:/etc/nginx/html
    depends_on:
    - backend1
    - backend2
    - backend3
    networks:
    - app-network
    restart: always # 设置重启策略

    复制代码
    backend1:
      build:
        context: .
        dockerfile: java.Dockerfile
      container_name: backend1
      expose:
        - "8081"
      networks:
        - app-network
      restart: unless-stopped  # 另一种重启策略
    
    backend2:
      build:
        context: .
        dockerfile: java.Dockerfile
      container_name: backend2
      expose:
        - "8081"
      networks:
        - app-network
      restart: unless-stopped
    
    backend3:
      build:
        context: . 
        dockerfile: java.Dockerfile
      container_name: backend3
      expose:
        - "8081"
      networks:
        - app-network
      restart: unless-stopped

    networks:
    app-network:
    driver: bridge

相关推荐
代码AC不AC7 分钟前
【Linux】基本指令学习1
linux·学习·指令
Mr.小海27 分钟前
Linux运维常用命令大全
linux·运维·chrome
biubiubiu070628 分钟前
Racknerd服务器Ubuntu
运维·服务器
瞅小孩30 分钟前
服务器、花生壳一个端口部署前后端分离项目
linux·运维·服务器
Spring-wind31 分钟前
【docker】将本地镜像打包部署到服务器上
服务器·docker·容器
kura_tsuki31 分钟前
[Linux入门] Linux 账号和权限管理入门:从基础到实践
linux·运维
武子康1 小时前
Java-74 深入浅出 RPC Dubbo Admin可视化管理 安装使用 源码编译、Docker启动
java·分布式·后端·spring·docker·rpc·dubbo
是阿建吖!1 小时前
【Linux | 网络】应用层(HTTP)
linux·网络·http
宇钶宇夕1 小时前
S7-1200 数字量模块接线:从源型 / 漏型到信号板扩展全解析
运维·服务器·数据库·程序人生·自动化
石小千1 小时前
Linux部署Minio集群
linux·运维