使用Docker Compose配置多个服务

文章目录

    • 1.什么是Docker Compose?
    • 2.Docker Compose的优势
    • 3.MySQL准备工作
    • 4.Redis准备工作
    • 5.数据库脚本准备工作
    • 6.编写docker.env配置文件
    • 7.如何选择以下两种方式说明
    • 8.方式一:使用现有镜像运行容器
      • 1.前台准备工作
      • 2.后台准备工作
      • 3.编写docker-compose.yml配置文件
    • 9.方式二:使用 Dockerfile 构建镜像运行容器
      • 1.前台准备工作
      • 4.后台准备工作
      • 5.编写docker-compose.yml配置文件
    • 10.运行容器
    • 11.初始化数据库
    • 12.查看镜像
    • 13.容器命令
    • 14.docker-compose命令
    • 10.总结

本文介绍了如何使用Docker Compose来配置多个服务,包括MySQL数据库、前台应用、Redis缓存和后台应用。我们将详细说明每个服务的准备工作和配置。

1.什么是Docker Compose?

Docker Compose是Docker的一个工具,用于定义和管理多个Docker容器的应用程序。它允许您通过一个单独的文件来定义多个服务、网络和卷,并通过简单的命令来启动、停止和管理整个应用。

Docker Compose使用YAML文件来描述应用程序的组件和配置。在这个YAML文件中,您可以定义每个服务的镜像、端口映射、环境变量、挂载卷、网络设置等。通过使用Docker Compose,您可以将复杂的多容器应用程序定义为一个简单的文本文件,使得应用的部署和维护变得更加方便和可管理。

2.Docker Compose的优势

使用Docker Compose有许多优势,包括:

简化应用定义:通过使用YAML文件来定义整个应用程序,您可以将多个服务和配置集中在一个地方,减少了手动操作和配置的复杂性。

快速部署:一旦您定义了应用程序,只需使用一个命令就可以快速部署整个应用,节省了部署时间和工作量。

依赖管理:Docker Compose允许您定义服务之间的依赖关系,确保各个服务在正确的顺序启动,避免了因依赖问题导致的启动失败。

易于扩展:如果您的应用需要扩展,只需修改YAML文件中的服务定义,再次运行命令即可完成扩展,非常方便。

环境隔离:每个服务在Docker容器中运行,实现了环境隔离,保证了应用之间不会相互干扰,提高了安全性。

3.MySQL准备工作

  • docker-compose.yml配置说明

在docker-compose.yml中,我们使用了mysql:8镜像作为MySQL数据库的基础镜像。在environment部分,我们设置了数据库的初始化参数,包括数据库名称、root用户密码以及允许root用户从任意主机访问。此外,我们挂载了MySQL的数据、配置和日志文件到宿主机,以确保数据持久化和配置的灵活性。

  • 创建目录
mkdir -p /usr/local/mysql/conf
  • 进入mysql 配置文件目录
cd /usr/local/mysql/conf
  • 创建配置文件my.cnf
vim /usr/local/mysql/conf/my.cnf 
  • 以下是配置文件内容
[mysqld]
# MySQL 用户名,指定运行 MySQL 服务的系统用户为 "mysql"。
user=mysql
# 禁用 MySQL 的 DNS 反向解析功能,提高数据库连接性能
skip-name-resolve
# 允许最大连接数
max_connections=1024
# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=100
# 服务端使用的字符集默认为UTF8mb4
character-set-server=utf8mb4
# 设置排序规则为 utf8mb4_general_ci,大小写不敏感的排序规则
collation-server=utf8mb4_general_ci
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 使用“mysql_native_password”插件认证
authentication_policy=mysql_native_password
#是否对sql语句大小写敏感,1表示不敏感 注意此参数在8.0版本后必须在初始化数据库之前配置,即初始化后不允许修改此值
lower_case_table_names = 1
#MySQL连接闲置超过一定时间后(单位:秒)将会被强行关闭 ,导致数据库丢失
#MySQL默认的wait_timeout  值为8个小时, interactive_timeout参数需要同时配置才能生效
interactive_timeout = 28800000
# MySQL 连接闲置超过一定时间后将会被强行关闭,避免数据库丢失。设置为 28800000 毫秒(8 小时)。
wait_timeout = 28800000
#导出
secure_file_priv=/var/lib/mysql-files
# 启用二进制日志功能,用于记录数据库更改, 默认存储在 /var/lib/mysql, 并指定前缀名 mysql-bin
log-bin = mysql-bin
# binlog 文件的过期时间
binlog_expire_logs_seconds=2592000

# SQL 模式配置,包含多个选项,用逗号分隔。
# - STRICT_TRANS_TABLES:严格模式,对于插入错误或警告的值,拒绝而不是警告,包括转换问题。
# - NO_ZERO_IN_DATE:禁止插入零日期,例如 '0000-00-00'。
# - NO_ZERO_DATE:禁止插入零日期,例如 '0000-00-00'。
# - ERROR_FOR_DIVISION_BY_ZERO:在发生除以零的操作时抛出错误,而不是产生 NULL 值。
# - NO_ENGINE_SUBSTITUTION:如果指定的存储引擎不可用,不要自动替换为其他可用的存储引擎。
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
#时区
default-time_zone = '+8:00'
#日志时区
log_timestamps=SYSTEM
# 指定允许的 TLS 版本,这里设置为 TLSv1.2 和 TLSv1.3
tls_version=TLSv1.2,TLSv1.3

#Metadata Lock最大时长(秒), 一般用于控制 alter操作的最大时长sine mysql5.6
#任何给定 MySQL 用户帐户允许的最大同时连接数。值 0(默认值)表示 “没有限制。”
#max_user_connections=0
#SELECT语句 的执行超时 ,以毫秒为单位。如果值为 0,则不启用超时
#max_execution_time=5000
#查询返回数据行数最大值,超过此值则终止查询默认最大值18446744073709551615
#max_join_size=10000
#执行 DML操作时除了增加innodb事务锁外还增加Metadata Lock,其他alter(DDL)session将阻塞
#lock_wait_timeout = 3600
#内部内存临时表的最大值。
#比如大数据量的group by ,order by时可能用到临时表,
#超过了这个值将写入磁盘,系统IO压力增大
#tmp_table_size = 64M
#max_heap_table_size = 64M
 
[mysql]
default-character-set=utf8mb4
 
[client]
default-character-set=utf8mb4

4.Redis准备工作

  • docker-compose.yml配置说明

配置了Redis缓存服务,使用了redis:6-alpine镜像作为基础镜像。我们设置了Redis的配置文件,并挂载了数据目录到宿主机,以便持久化Redis数据。

  • 创建目录
mkdir -p /usr/local/redis/conf
  • 进入mysql 配置文件目录
cd /usr/local/redis/conf
  • 创建配置文件redis.conf
vim /usr/local/redis/conf/redis.conf
  • 以下是配置文件内容
# 将 192.168.1.100 绑定到 10.0.0.1 上(仅限 Linux 内核 3.9+)
#bind 192.168.1.100 10.0.0.1

# 将 127.0.0.1 绑定到 IPv6 ::1 上(仅限 Linux 内核 3.9+)
#bind 127.0.0.1 ::1

# 禁用保护模式,允许外部主机连接
protected-mode no

# 指定 Redis 监听端口
port 6379

# 设置 TCP 连接队列的长度
tcp-backlog 511

# 设置 Redis 访问密码
requirepass 123456

# 设置客户端闲置连接超时时间(秒),0 表示无限制
timeout 0

# 设置 TCP 连接的 keepalive 时间(秒)
tcp-keepalive 300

# 后台运行 Redis 服务器 (不关闭会造成docker-compose启动失败,无错误日志)
daemonize no

# 设置 Redis 运行的模式(no、upstart、systemd)
supervised no

# 设置 Redis 进程 ID 文件路径
pidfile /var/run/redis_6379.pid

# 设置日志级别
loglevel notice

# 设置日志文件路径(空字符串表示不写入日志文件)
logfile ""

# 设置数据库数量
databases 30

# 是否始终显示 Redis 的 ASCII 艺术 LOGO
always-show-logo yes

# 设置数据保存条件,格式为 save  
save 900 1
save 300 10
save 60 10000

# 如果后台保存出错,是否停止写入操作
stop-writes-on-bgsave-error yes

# 是否对 RDB 文件进行压缩
rdbcompression yes

# 是否进行 RDB 文件校验
rdbchecksum yes

# RDB 文件名
dbfilename dump.rdb

# RDB 文件保存目录
dir ./

# 设置从服务器是否提供过期数据的读取
replica-serve-stale-data yes

# 设置从服务器只读
replica-read-only yes

# 是否使用无盘同步
repl-diskless-sync no

# 是否禁用 TCP_NODELAY 算法,提高数据传输效率
repl-disable-tcp-nodelay no

# 从服务器优先级
replica-priority 100

# 是否启用 lazyfree 机制进行数据清理
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no

# 是否开启 AOF 持久化
appendonly yes

# AOF 文件名
appendfilename "appendonly.aof"

# 是否在 AOF 重写时禁用 fsync 操作
no-appendfsync-on-rewrite no

# 触发 AOF 重写的百分比
auto-aof-rewrite-percentage 100

# 触发 AOF 重写的最小文件大小
auto-aof-rewrite-min-size 64mb

# 是否允许载入有损坏的 AOF 文件
aof-load-truncated yes

# 是否使用 RDB 文件的前置宣言
aof-use-rdb-preamble yes

# 设置 Lua 脚本的最大执行时间(毫秒)
lua-time-limit 5000

# 慢查询日志最大长度
slowlog-max-len 128

# key 过期事件的监听
notify-keyspace-events "Ex"

# 设置哈希对象的最大 ziplist 条目数和最大 ziplist value 长度
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

# 设置列表对象的最大 ziplist size 和 compress depth
list-max-ziplist-size -2
list-compress-depth 0

# 设置集合对象的最大 intset 条目数
set-max-intset-entries 512

# 设置有序集合对象的最大 ziplist 条目数和最大 ziplist value 长度
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

# 设置 HyperLogLog 对象的最大 sparse 编码长度
hll-sparse-max-bytes 3000

# 设置 stream 对象的最大 node 长度和最大 entry 数量
stream-node-max-bytes 4096
stream-node-max-entries 100

# 是否开启动态 HZ,根据负载动态调整 serverCron() 函数的执行频率
activerehashing yes

# 设置 serverCron() 函数的执行频率,值越高执行频率越高
hz 10

# 是否开启动态 HZ,动态调整 serverCron() 函数的执行频率
dynamic-hz yes

# 是否在 AOF 重写时使用增量 fsync
aof-rewrite-incremental-fsync yes

# 是否在 RDB 持久化时使用增量 fsync
rdb-save-incremental-fsync yes

5.数据库脚本准备工作

准备好数据库脚本code-safe.sql,在运行后台mysql容器后要初始化数据到数据库中,否则运行后台server容器会报错。执行命令看第11步

6.编写docker.env配置文件

这是一个包含环境变量的配置文件,用于配置docker-compose.yml文件中相关参数。

# --------------------------------------- mysql 配置 ------------------------------------------
# 数据库名称
MYSQL_DATABASE=code_safe

# root用户的密码
MYSQL_ROOT_PASSWORD=abc*@*ABC

# --------------------------------------- server 后台配置 ---------------------------------------
# Spring配置文件
SPRING_PROFILES_ACTIVE=local

# JAR包路径
PROJECT_JAR_PATH=/home/project/code-safe.jar

# logback生成的日志路径
PROJECT_LOG_PATH=/home/project/logs

# JVM虚拟机参数
#JAVA_OPTS=-Xms512m -Xmx512m -Djava.security.egd=file:/dev/./urandom

# 主数据库连接URL
MASTER_DATASOURCE_URL=jdbc:mysql://192.168.225.28:13306/${MYSQL_DATABASE}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true

# 主数据库用户名
MASTER_DATASOURCE_USERNAME=root

# 主数据库密码
MASTER_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}

# Redis地址
REDIS_HOST=192.168.225.28

# Redis数据库
REDIS_DATABASE=6

# Redis密码
REDIS_PASSWORD=123456

在这个配置文件中,我们定义了 MySQL 数据库和后台服务的相关参数,包括数据库名称、root 用户的密码、Spring Boot 的配置文件激活环境、JAR 包路径、日志路径、JVM 虚拟机参数、主数据库连接信息以及 Redis 的相关配置信息。

7.如何选择以下两种方式说明

  • 方式一 : 使用现有镜像运行容器

在 docker-compose.yml 中,例如后台服务 server , 使用现有的镜像 eclipse-temurin:8-jre 来运行容器,没有指定构建过程。
这种方式适用于已经存在可用的镜像,不需要对镜像进行自定义构建,可以快速启动容器。
优点
快速部署:由于直接使用现有镜像,不需要构建过程,所以容器可以快速启动。
简单:不需要关注构建过程和 Dockerfile 的内容,使用现有镜像即可。
内存占用小: 原因是因为它直接使用了现有的镜像,而现有的镜像通常经过优化和精简,只包含了运行应用所需的最小依赖和文件。
缺点
限制:受现有镜像的功能和配置限制,可能无法满足特定的需求。

  • 方式二 : 使用 Dockerfile 构建镜像运行容器

在 docker-compose.yml 中,服务 web 和 server 都使用自定义的 Dockerfile 来构建镜像。
这种方式允许根据需要自定义容器镜像,可以在 Dockerfile 中添加所需的配置和依赖,以满足特定的应用程序需求。
优点
自定义:可以根据应用程序的具体需求,在 Dockerfile 中添加所需的组件、配置和依赖,使镜像更加适合应用程序。
灵活性:可以根据需求定制镜像,减少不必要的镜像层,降低镜像大小。
版本控制:Dockerfile 可以纳入版本控制系统,方便代码和镜像的管理。
缺点
构建时间:由于需要构建镜像,可能会增加部署的时间。
复杂性:需要编写和维护 Dockerfile,对于初学者来说可能会有一定的学习曲线。
内存占用大: 原因是镜像的构建过程中可能包含了较多不必要的依赖和文件,导致最终构建的镜像比较庞大。 运行容器后相当于运行了镜像和服务。

查看docker容器内存使用情况:

 docker stats 

在这里插入图片描述

8.方式一:使用现有镜像运行容器

1.前台准备工作

  • docker-compose.yml配置说明

准备前台应用服务,使用了nginx:alpine镜像作为基础镜像。我们将Nginx的配置文件和静态前端资源挂载到宿主机,以便对Nginx进行配置和静态资源的更新。

  • 前台打dist包
  • 放到docker-compose.yml配置的指定的目录下: /home/project/

使用Docker Compose配置多个服务_第1张图片

  • 创建挂载目录
mkdir -p /usr/local/nginx/conf
  • 进入配置文件目录
cd /usr/local/nginx/conf
  • 创建配置文件nginx.conf
vim /usr/local/nginx/conf/nginx.conf
  • 以下是配置文件内容

以下是一个简单的Nginx配置示例,配置文件要根据自己的项目地址、端口、路径进行配置
, 用于部署一个Vue.js前端项目和代理后端API请求。

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;    #关闭版本号
    client_max_body_size 5120m; #允许用户最大上传数据大小
	
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
    	listen       16001;
        server_name  localhost;
        charset utf-8;
	
	location / {
        root		/project/dist;
        #需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
	    try_files 	$uri 		$uri/ 		@router;
        index  		index.html;
    }

    #对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
    #因此需要rewrite到index.html中,然后交给路由在处理请求资源
	location @router {
		rewrite ^.*$ 	/index.html 	last;
	}

	location /code-safe {
		proxy_pass 		    http://192.168.225.28:16000/code-safe;
		proxy_redirect		off;
		proxy_set_header 	Host			    $host:$server_port;
		proxy_set_header 	X-Real-IP		    $remote_addr;
		proxy_set_header	X-Forwarder-For		$http_x_forwarded_for;
		# enables WS support
		proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_read_timeout 600s;
	}

	error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

nginx.conf配置说明

  1. 在这个Nginx配置示例中,我们定义了一个简单的Nginx服务,监听在端口16001上。该服务用于部署一个Vue.js前端项目,并通过反向代理转发后端API请求。

  2. 首先,我们指定了Nginx的worker进程数为1。然后,设置了一些常用的Nginx配置项,如sendfile、keepalive_timeout等。我们还关闭了Nginx的版本号显示,以增加安全性。

  3. 接下来,我们定义了一个服务器块,监听在端口16001,并将域名设置为localhost。在这个服务器块中,我们定义了两个location块。

  4. 第一个location块用于处理前端Vue.js项目的请求。我们将前台包所在的目录设置为/project/dist,并使用try_files指令处理路由请求,以避免在Nginx中刷新出现404错误。对于无法找到具体文件的路由请求,我们使用rewrite将其指向index.html。

  5. 第二个location块用于反向代理后端API请求。我们将所有以/code-safe开头的请求代理到http://192.168.225.28:16000/code-safe地址,并设置了一些代理的头信息,以支持WebSocket。

  6. 最后,我们定义了一个错误页面,并指定了错误页面的处理方式。

以上就是一个简单的Nginx配置示例,用于部署前端项目并代理后端API请求。希望本文对您有所帮助!

2.后台准备工作

  • docker-compose.yml配置说明

配置后台应用服务,使用了eclipse-temurin:8-jre镜像作为基础镜像。在environment部分,我们设置了Spring配置文件的激活选项和容器的时区。在volumes部分,我们挂载了后台应用的可执行JAR文件和日志目录到宿主机,以便更新应用和查看日志。

  • 后台打jar包
  • 放到docker-compose.yml配置的指定的目录下: /home/project/

使用Docker Compose配置多个服务_第2张图片

3.编写docker-compose.yml配置文件

下面是完整的docker-compose.yml文件,包含了以上所有的准备工作和配置:

version: "3.8"

services:
  mysql:
    image: mysql:8
    container_name: mysql
    restart: unless-stopped
    # 启用伪终端,允许与容器进行交互和调试 , 打开一个交互式 shell, 命令[docker-compose exec mysql sh]
    tty: true
    privileged: true
    ports:
      - "13306:3306"
    environment:
      # 初始化数据库名称。如果 MYSQL_DATABASE 环境变量未设置或为空,则使用默认值 "code_safe"。
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      # 设置 MySQL 的 root 用户密码。如果 MYSQL_ROOT_PASSWORD 环境变量未设置或为空,则使用默认值 "abc*@*ABC"。
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      # 允许 root 用户从任意主机访问
      MYSQL_ROOT_HOST: '%'
#      MYSQL_USER: test           # 创建新用户
#      MYSQL_PASSWORD: test       # 新用户的密码
      # 时区上海
      TZ: Asia/Shanghai
    volumes:
      - /usr/local/mysql/data:/var/lib/mysql          # 挂载数据
      - /usr/local/mysql/conf:/etc/mysql/conf.d       # 挂载配置文件
      - /usr/local/mysql/logs:/var/log/mysql          # 挂载日志
      - /usr/local/mysql/mysql-files:/var/lib/mysql-files #挂载导出的文件
      - /etc/localtime:/etc/localtime:ro              # 挂载宿主机的时区文件到容器的时区文件,并设置为只读模式
    networks:
      - network-one

  web:
    image: nginx:alpine                 # 镜像
    container_name: web                 # 容器名
    restart: unless-stopped             # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
    ports: # 映射端口
      - "8088:80"
      - "16001:16001"
    environment: # 设置环境变量,相当于docker run命令中的-e
      TZ: Asia/Shanghai
      LANG: en_US.UTF-8
    volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
      - /usr/local/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - /usr/local/nginx/conf/conf.d:/etc/nginx/conf.d
      - /usr/local/nginx/log:/var/log/nginx
      - /usr/local/nginx/html:/usr/share/nginx/html
      - /home/project/dist:/home/project/dist # 将宿主机dist目录挂载到Nginx容器
    networks:
      - network-one
    depends_on: # 定义服务之间依赖关系,即先启动定义的服务再执行当前服务
      - server

  redis:
    image: redis:6-alpine
    container_name: redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    environment:
      TZ: Asia/Shanghai
      LANG: en_US.UTF-8
    volumes:
      - /usr/local/redis/conf/redis.conf:/etc/redis/redis.conf
      - /usr/local/redis/data:/data
    logging:
      driver: json-file   # 配置容器的日志驱动为 json-file,记录日志到 JSON 格式的文件中
      options:
        max-size: 100m    # 设置单个日志文件的最大大小为 100 MB
        max-file: 2       # 设置日志文件的最大滚动数为 2,保留最新的两个日志文件
    networks:
      - network-one
    command: redis-server /etc/redis/redis.conf

  server:
    image: eclipse-temurin:8-jre
    container_name: server
    restart: unless-stopped
    ports:
      - "16000:16000"
    #    build:
    #      context: .          # 构建上下文为当前目录,即 Docker Compose 文件所在的目录, 指定使用当前目录下的docker-compose.yml
    environment:
      # 指定活动的 Spring 配置文件
      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE}
      # 设置容器的时区为亚洲/上海时区
      TZ: Asia/Shanghai
      # 定义应用程序的 Java 虚拟机参数
#      JAVA_OPTS:
#        # 设置 Java 堆的初始内存为 512MB
#        # 设置 Java 堆的最大内存为 512MB
#        # 设置随机数生成器的算法为 /dev/./urandom
#        ${JAVA_OPTS:-
#          -Xms512m
#          -Xmx512m
#          -Djava.security.egd=file:/dev/./urandom
#        }
#      ARGS: # 定义应用程序的命令行参数,包含了数据库连接信息和 Redis 配置
#        --spring.datasource.druid.MASTER.url=${MASTER_DATASOURCE_URL:-jdbc:mysql://127.0.0.1:3306/code_safe?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8}
#        --spring.datasource.druid.MASTER.username=${MASTER_DATASOURCE_USERNAME:-root}
#        --spring.datasource.druid.MASTER.password=${MASTER_DATASOURCE_PASSWORD:-123456}
#        --spring.redis.host=${REDIS_HOST:-127.0.0.1}
#        --spring.redis.database=${REDIS_DATABASE:-0}
#        --spring.redis.password=${REDIS_PASSWORD:-123456}
    volumes:
      # 本地jar包路径
      - ${PROJECT_JAR_PATH}:${PROJECT_JAR_PATH}
      # 挂载日志 -v A:B ,A指宿主机位置,B指容器内项目日志存放路径 = logback.xml配置的
      - ${PROJECT_LOG_PATH}:${PROJECT_LOG_PATH}
      # 指定容器时间为宿主机时间
      - /etc/localtime:/etc/localtime
    networks:
      - network-one
    depends_on:
      - mysql
      - redis
    command:
      - java
      - -Xms512m
      - -Xmx1024m
      - -Djava.security.egd=file:/dev/./urandom
      - -jar
      - ${PROJECT_JAR_PATH}
#      - --spring.datasource.druid.MASTER.url=${MASTER_DATASOURCE_URL}
#      - --spring.datasource.druid.MASTER.username=${MASTER_DATASOURCE_USERNAME}
#      - --spring.datasource.druid.MASTER.password=${MASTER_DATASOURCE_PASSWORD}
#      - --spring.redis.host=${REDIS_HOST}
#      - --spring.redis.database=${REDIS_DATABASE}
#      - --spring.redis.password=${REDIS_PASSWORD}

networks:
  network-one: # 自定义一个名为 'code-safe-network' 的网络
    driver: bridge     # 使用 'bridge' 驱动来创建桥接网络

volumes:
  mysql:
    driver: local
  redis:
    driver: local

9.方式二:使用 Dockerfile 构建镜像运行容器

1.前台准备工作

  • 前台打dist包

  • 放到docker-compose.yml配置的指定的目录下: /home/project/
    使用Docker Compose配置多个服务_第3张图片

  • 编写front.Dockerfile

  • 进入Dockerfile目录

cd /home/project
  • 创建镜像构建文件front.Dockerfile
vim /home/project/front.Dockerfile
  • 以下是Dockerfile文件内容
# 指定基础镜像
FROM nginx:alpine

# 复制文件或目录到镜像中。可以将本地文件或目录复制到镜像的指定位置。
COPY ./dist /home/project/dist
# 用本地的nginx配置文件覆盖镜像的Nginx配置
COPY ./nginx.conf /etc/nginx/nginx.conf

# 设置环境变量
# 添加时区环境变量,亚洲,上海
ENV TZ=Asia/Shanghai

# 声明要监听的端口
EXPOSE 16001
  • Dockerfile配置说明

以上是一个简单的Dockerfile示例,用于构建一个基于Nginx的Docker镜像。这个镜像将在容器中运行一个静态网页应用程序。

解释每个指令的作用:

FROM nginx:alpine: 这是指定基础镜像的指令。nginx:alpine是一个官方提供的Nginx镜像,alpine标签表示基于Alpine Linux的轻量版。

COPY ./dist /home/project/dist: 这个指令将本地主机当前目录下的dist目录复制到镜像中的/home/project/dist目录。这里假设dist目录包含网页应用程序的静态文件。

COPY ./nginx.conf /etc/nginx/nginx.conf: 这个指令将本地主机当前目录下的nginx.conf文件复制到镜像中的/etc/nginx/nginx.conf文件。这样可以使用自定义的Nginx配置文件替换镜像中默认的配置。

ENV TZ=Asia/Shanghai: 这个指令设置一个名为TZ的环境变量,并将其值设置为Asia/Shanghai。这里使用Asia/Shanghai时区,方便配置容器中的时间。

EXPOSE 16001: 这个指令声明容器将监听的端口号是16001。虽然在Dockerfile中声明端口不会自动将容器的端口映射到宿主机,但这样做可以提供镜像使用者有关容器内部应用程序所监听端口的信息。

通过以上Dockerfile,当您执行docker build命令时,Docker会根据Dockerfile中的指令构建一个新的Nginx镜像。然后,您可以使用该镜像运行一个Nginx容器,从而将您的网页应用程序部署在Docker容器中。例如,您可以使用以下命令运行该容器:
docker run -d -p 16001:80 <镜像名称或ID>
其中<镜像名称或ID>是您在构建镜像时指定的名称或镜像ID。该命令将把容器内的80端口映射到主机的16001端口,从而使您的网页应用程序可以通过http://localhost:16001访问。
  • 进入配置文件目录
cd /home/project
  • 创建配置文件nginx.conf
vim /home/project/nginx.conf
  • 以下是配置文件内容

以下是一个简单的Nginx配置示例,配置文件要根据自己的项目地址、端口、路径进行配置
, 用于部署一个Vue.js前端项目和代理后端API请求。

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;    #关闭版本号
    client_max_body_size 5120m; #允许用户最大上传数据大小
	
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
    	listen       16001;
        server_name  localhost;
        charset utf-8;
	
	location / {
        root		/project/dist;
        #需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
	    try_files 	$uri 		$uri/ 		@router;
        index  		index.html;
    }

    #对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
    #因此需要rewrite到index.html中,然后交给路由在处理请求资源
	location @router {
		rewrite ^.*$ 	/index.html 	last;
	}

	location /code-safe {
		proxy_pass 		    http://192.168.225.28:16000/code-safe;
		proxy_redirect		off;
		proxy_set_header 	Host			    $host:$server_port;
		proxy_set_header 	X-Real-IP		    $remote_addr;
		proxy_set_header	X-Forwarder-For		$http_x_forwarded_for;
		# enables WS support
		proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_read_timeout 600s;
	}

	error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

nginx.conf配置说明

  1. 在这个Nginx配置示例中,我们定义了一个简单的Nginx服务,监听在端口16001上。该服务用于部署一个Vue.js前端项目,并通过反向代理转发后端API请求。

  2. 首先,我们指定了Nginx的worker进程数为1。然后,设置了一些常用的Nginx配置项,如sendfile、keepalive_timeout等。我们还关闭了Nginx的版本号显示,以增加安全性。

  3. 接下来,我们定义了一个服务器块,监听在端口16001,并将域名设置为localhost。在这个服务器块中,我们定义了两个location块。

  4. 第一个location块用于处理前端Vue.js项目的请求。我们将前台包所在的目录设置为/project/dist,并使用try_files指令处理路由请求,以避免在Nginx中刷新出现404错误。对于无法找到具体文件的路由请求,我们使用rewrite将其指向index.html。

  5. 第二个location块用于反向代理后端API请求。我们将所有以/code-safe开头的请求代理到http://192.168.225.28:16000/code-safe地址,并设置了一些代理的头信息,以支持WebSocket。

  6. 最后,我们定义了一个错误页面,并指定了错误页面的处理方式。

以上就是一个简单的Nginx配置示例,用于部署前端项目并代理后端API请求。希望本文对您有所帮助!

4.后台准备工作

  • 后台打jar包
  • 放到docker-compose.yml配置的指定的目录下: /home/project/

使用Docker Compose配置多个服务_第4张图片

  • 编写back.Dockerfile

  • 进入Dockerfile目录

cd /home/project
  • 创建镜像构建文件back.Dockerfile
vim /home/project/back.Dockerfile
  • 以下是Dockerfile文件内容
# 指定基础镜像
FROM eclipse-temurin:8-jre

# 在镜像中执行命令,创建目录,并使用它作为工作目录
RUN mkdir -p /home/project
# 设置工作目录,即后续命令的默认执行路径
WORKDIR /home/project
# 复制文件或目录到镜像中。可以将本地文件或目录复制到镜像的指定位置。
COPY ./code-safe.jar /home/project/code-safe.jar

# 设置环境变量
# 指定容器的时区
ENV TZ=Asia/Shanghai
# 用于配置 Java 虚拟机的选项,如初始堆大小、最大堆大小和随机数生成器,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV JAVA_OPTS=""
## 应用参数
ENV ARGS=""

# 定义容器启动后执行的命令,启动后端项目
CMD java ${JAVA_OPTS} -jar code-safe.jar $ARGS

# 声明要监听的端口
EXPOSE 16000
  • Dockerfile配置说明

以上是一个简单的Dockerfile示例,用于构建一个基于 Eclipse Temurin 8 的 JRE(Java Runtime Environment)的镜像,并部署后端项目。

解释每个指令的作用:

FROM eclipse-temurin:8-jre: 指定基础镜像为 Eclipse Temurin 8 JRE,这是一个支持 Java 8 的镜像。

RUN mkdir -p /home/project: 在镜像中执行命令,创建目录 /home/project,用作后续命令的工作目录。

WORKDIR /home/project: 设置工作目录为 /home/project,即后续命令的默认执行路径。

COPY ./code-safe.jar /home/project/code-safe.jar: 复制本地的 code-safe.jar 文件到镜像中的 /home/project/code-safe.jar 路径。这是将后端项目的可执行 JAR 文件复制到容器内的操作。

ENV TZ=Asia/Shanghai: 设置容器的时区为亚洲/上海时区,确保容器内的时间与宿主机的时间一致。

ENV JAVA_OPTS="": 设置一个环境变量 JAVA_OPTS,用于配置 Java 虚拟机的选项,如初始堆大小、最大堆大小和随机数生成器。可以通过 docker run -e "JAVA_OPTS=" 命令覆盖该值。

ENV ARGS="": 设置一个环境变量 ARGS,用于定义应用程序的命令行参数。这个环境变量可以用来传递应用程序的配置信息,如数据库连接信息、Redis配置等。

CMD java ${JAVA_OPTS} -jar code-safe.jar $ARGS: 定义容器启动后执行的命令。这里使用 Java 运行后端项目 code-safe.jar,并通过 ${JAVA_OPTS} 和 ${ARGS} 环境变量传递 Java 虚拟机参数和应用程序参数。

EXPOSE 16000: 声明要监听的端口。这里将容器内的端口 16000 暴露出来,使得其他容器或主机可以访问该端口提供的服务。

总的来说,这个 Dockerfile 用于构建一个包含后端项目的容器镜像。它将 Java 8 JRE 和后端项目的可执行 JAR 文件放入镜像中,并在容器启动时执行 JAR 文件,从而启动后端应用。同时,通过环境变量 JAVA_OPTS 和 ARGS,可以动态调整容器中 Java 虚拟机的参数和应用程序的配置。

5.编写docker-compose.yml配置文件

下面是完整的docker-compose.yml文件,包含了以上所有的准备工作和配置:

version: "3.8"

services:
  mysql:
    image: mysql:8
    container_name: mysql
    restart: unless-stopped
    # 启用伪终端,允许与容器进行交互和调试 , 打开一个交互式 shell, 命令[docker-compose exec mysql sh]
    tty: true
    privileged: true
    ports:
      - "13306:3306"
    environment:
      # 初始化数据库名称。如果 MYSQL_DATABASE 环境变量未设置或为空,则使用默认值 "code_safe"。
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      # 设置 MySQL 的 root 用户密码。如果 MYSQL_ROOT_PASSWORD 环境变量未设置或为空,则使用默认值 "abc*@*ABC"。
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      # 允许 root 用户从任意主机访问
      MYSQL_ROOT_HOST: '%'
#      MYSQL_USER: test           # 创建新用户
#      MYSQL_PASSWORD: test       # 新用户的密码
      # 时区上海
      TZ: Asia/Shanghai
    volumes:
      - /usr/local/mysql/data:/var/lib/mysql          # 挂载数据
      - /usr/local/mysql/conf:/etc/mysql/conf.d       # 挂载配置文件
      - /usr/local/mysql/logs:/var/log/mysql          # 挂载日志
      - /usr/local/mysql/mysql-files:/var/lib/mysql-files #挂载导出的文件
      - /etc/localtime:/etc/localtime:ro              # 挂载宿主机的时区文件到容器的时区文件,并设置为只读模式
    networks:
      - network-one

  web:
    container_name: web                 # 容器名
    build:                              # 构建镜像
      context: ./                       # 指定构建上下文的路径,即Docker在构建镜像时查找的目录
      dockerfile: front.Dockerfile      # 指定自定义的Dockerfile文件
    image: web                          # 镜像
    restart: unless-stopped             # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
    ports: # 映射端口
      - "8088:80"
      - "16001:16001"
    environment: # 设置环境变量,相当于docker run命令中的-e
      LANG: en_US.UTF-8
    volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
      - /usr/local/nginx/conf/conf.d:/etc/nginx/conf.d
      - /usr/local/nginx/log:/var/log/nginx
      - /usr/local/nginx/html:/usr/share/nginx/html
    networks:
      - network-one
    depends_on: # 定义服务之间依赖关系,即先启动定义的服务再执行当前服务
      - server

  redis:
    image: redis:6-alpine
    container_name: redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    environment:
      TZ: Asia/Shanghai
      LANG: en_US.UTF-8
    volumes:
      - /usr/local/redis/conf/redis.conf:/etc/redis/redis.conf
      - /usr/local/redis/data:/data
    logging:
      driver: json-file   # 配置容器的日志驱动为 json-file,记录日志到 JSON 格式的文件中
      options:
        max-size: 100m    # 设置单个日志文件的最大大小为 100 MB
        max-file: 2       # 设置日志文件的最大滚动数为 2,保留最新的两个日志文件
    networks:
      - network-one
    command: redis-server /etc/redis/redis.conf

  server:
    container_name: server
    build:                              # 构建镜像
      context: ./                       # 指定构建上下文的路径,即Docker在构建镜像时查找的目录
      dockerfile: back.Dockerfile      # 指定自定义的Dockerfile文件
    image: server
    restart: unless-stopped
    ports:
      - "16000:16000"
    #    build:
    #      context: .          # 构建上下文为当前目录,即 Docker Compose 文件所在的目录, 指定使用当前目录下的docker-compose.yml
    environment:
      # 指定活动的 Spring 配置文件
      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE}
      # 定义应用程序的 Java 虚拟机参数
      JAVA_OPTS: ${JAVA_OPTS}
      ARGS: # 定义应用程序的命令行参数,包含了数据库连接信息和 Redis 配置
#        --spring.datasource.druid.MASTER.url=${MASTER_DATASOURCE_URL:-jdbc:mysql://127.0.0.1:3306/code_safe?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8}
#        --spring.datasource.druid.MASTER.username=${MASTER_DATASOURCE_USERNAME:-root}
#        --spring.datasource.druid.MASTER.password=${MASTER_DATASOURCE_PASSWORD:-123456}
#        --spring.redis.host=127.0.0.1
#        --spring.redis.database=${REDIS_DATABASE:-0}
#        --spring.redis.password=${REDIS_PASSWORD:-123456}
    volumes:
      # 挂载日志 -v A:B ,A指宿主机位置,B指容器内项目日志存放路径 = logback.xml配置的
      - ${PROJECT_LOG_PATH}:${PROJECT_LOG_PATH}
      # 指定容器时间为宿主机时间
      - /etc/localtime:/etc/localtime
    networks:
      - network-one
    depends_on:
      - mysql
      - redis

networks:
  network-one: # 自定义一个名为 'code-safe-network' 的网络
    driver: bridge     # 使用 'bridge' 驱动来创建桥接网络

volumes:
  mysql:
    driver: local
  redis:
    driver: local

10.运行容器

在完成了 docker.env 和 docker-compose.yml 的配置后,
(或者使用的是第二种方式 编写完 Dockerfile文件后),
我们可以使用以下命令来运行容器:

必须在docker-compose.yml文件的同级目录下运行命令才能生效,否则会出现以下错误:

在这里插入图片描述
使用Docker Compose配置多个服务_第5张图片

  • 运行所有容器
docker-compose --env-file docker.env -f /home/project/docker-compose.yml up -d
  • 运行单个容器
docker-compose --env-file docker.env -f /home/project/docker-compose.yml up -d mysql

docker-compose --env-file docker.env -f /home/project/docker-compose.yml up -d redis

docker-compose --env-file docker.env -f /home/project/docker-compose.yml up -d server

docker-compose --env-file docker.env -f /home/project/docker-compose.yml up -d web
  • 命令解析
命令 解释
docker-compose 这是 Docker Compose 命令行工具的名称。
--env-file /home/project/docker.env 这个选项指定了要使用的环境变量文件,即我们之前准备的 docker.env 文件。通过这个选项,我们可以将环境变量配置加载到容器中,以便在容器中使用这些配置。
-f /home/project/docker-compose.yml 这个选项指定了要使用的 Docker Compose 配置文件,即我们之前准备的 docker-compose.yml 文件。通过这个选项,我们告诉 Docker Compose 使用这个配置文件来定义和管理应用程序的服务组件和相关配置。
up 这是 Docker Compose 的一个子命令,用于启动应用程序。当我们运行 up 命令时,Docker Compose 将根据配置文件中定义的服务和配置来创建和运行容器。
-d 这个选项表示以“后台模式”运行容器。即使我们关闭终端或退出 SSH 会话,容器也会继续在后台运行。
server 这是 Docker Compose 配置文件中定义的服务名称。通过指定服务名称,我们告诉 Docker Compose 只运行名为 server 的服务容器,而不运行其他定义的服务。
docker-compose --env-file /home/project/docker.env -f /home/project/docker-compose.yml up -d server 将以上所有选项和参数组合在一起,形成完整的命令。这个命令的含义是:使用 docker.env 文件中的环境变量配置和 docker-compose.yml 文件中的服务定义,创建并在后台运行名为 server 的服务容器。

11.初始化数据库

第一次执行,由于数据库未初始化,因此后台server容器会运行失败。执行如下命令初始化数据库:

通过命令的方式执行效率低, 可以使用 Navicat 或 其他数据库连接工具, 初始化数据。

docker exec -i mysql \
    sh -c 'exec mysql -uroot -pabc*@*ABC code_safe' \
    < ./code_safe.sql

12.查看镜像

docker-compose --env-file /home/project/docker.env images

在这里插入图片描述

13.容器命令

命令 说明 示例
docker ps 列出当前正在运行的容器 docker ps
docker ps -a 列出所有容器,包括已停止的 docker ps -a
docker run 运行一个容器 docker run -it ubuntu bash
docker start 启动一个或多个已经被停止的容器 docker start container_id
docker stop 停止一个或多个正在运行的容器 docker stop container_id
docker build 构建一个新的镜像 docker build -t my_image .
docker pull 从镜像仓库中拉取或者更新指定镜像 docker pull ubuntu
docker push 将本地的镜像上传到镜像仓库 docker push my_image
docker rm 删除一个或多个容器 docker rm container_id
docker rmi 删除一个或多个镜像 docker rmi image_id
docker images 列出本地所有的镜像 docker images
docker exec 在运行的容器中执行命令 docker exec -it container_id /bin/bash
docker logs 获取容器的日志信息 docker logs container_id
docker inspect 获取容器/镜像的元数据 docker inspect container_id
docker cp 在容器与本地之间拷贝文件或者目录 docker cp foo.txt my_container:/foo.txt
docker volume create 创建一个卷 docker volume create my_vol
docker volume ls 列出所有卷 docker volume ls
docker volume rm 删除一个或多个卷 docker volume rm volume_name
docker network create 创建一个新的网络 docker network create my_net
docker network ls 列出所有网络 docker network ls
docker network rm 删除一个或多个网络 docker network rm network_name
docker tag 给镜像添加新的标签 docker tag my_image my_image:v1.0
docker history 查看镜像的历叐记录 docker history my_image
docker login 登录 Docker Hub 或其他 Docker 仓库 docker login
docker logout 从 Docker Hub 或其他 Docker 仓库注销 docker logout
docker save 将镜像保存为 tar 归档文件 docker save -o my_image.tar my_image
docker load 从 tar 归档文件中加载镜像 docker load -i my_image.tar
docker pause 暂停容器中所有的进程 docker pause container_id
docker unpause 恢复容器中的所有进程 docker unpause container_id

14.docker-compose命令

命令 描述 示例
docker-compose --env-file FILE up 使用指定的环境文件启动服务 docker-compose --env-file docker.env up
docker-compose --env-file FILE up -d 使用指定的环境文件以后台模式启动服务 docker-compose --env-file docker.env up -d
docker-compose --env-file FILE down 使用指定的环境文件停止并移除服务 docker-compose --env-file docker.env down
docker-compose --env-file FILE ps 使用指定的环境文件查看服务状态 docker-compose --env-file docker.env ps
docker-compose --env-file FILE logs 使用指定的环境文件查看服务日志 docker-compose --env-file docker.env logs
docker-compose --env-file FILE build 使用指定的环境文件构建服务 docker-compose --env-file docker.env build
docker-compose --env-file FILE config 使用指定的环境文件验证并查看配置 docker-compose --env-file docker.env config
docker-compose --env-file FILE pull 使用指定的环境文件拉取服务的镜像 docker-compose --env-file docker.env pull
docker-compose --env-file FILE push 使用指定的环境文件推送服务的镜像 docker-compose --env-file docker.env push
docker-compose --env-file FILE restart 使用指定的环境文件重启服务 docker-compose --env-file docker.env restart
docker-compose --env-file FILE rm 使用指定的环境文件移除停止的容器 docker-compose --env-file docker.env rm
docker-compose --env-file FILE start 使用指定的环境文件启动已经存在的容器 docker-compose --env-file docker.env start
docker-compose --env-file FILE stop 使用指定的环境文件停止运行中的容器 docker-compose --env-file docker.env stop
docker-compose --env-file FILE top 使用指定的环境文件查看服务中运行的进程 docker-compose --env-file docker.env top
docker-compose --env-file FILE exec 使用指定的环境文件在服务的容器中执行命令 docker-compose --env-file docker.env exec SERVICE COMMAND
docker-compose --env-file FILE scale 使用指定的环境文件设置服务的数量 docker-compose --env-file docker.env scale SERVICE=NUM
docker-compose --env-file FILE pause 使用指定的环境文件暂停服务 docker-compose --env-file docker.env pause
docker-compose --env-file FILE unpause 使用指定的环境文件恢复服务 docker-compose --env-file docker.env unpause
docker-compose --env-file FILE kill 使用指定的环境文件停止服务中的容器 docker-compose --env-file docker.env kill
docker-compose --env-file FILE run 使用指定的环境文件运行一次性命令 docker-compose --env-file docker.env run SERVICE COMMAND
docker-compose --env-file FILE create 使用指定的环境文件创建服务 docker-compose --env-file docker.env create
docker-compose --env-file FILE port 使用指定的环境文件打印服务的公开端口 docker-compose --env-file docker.env port
docker-compose --env-file FILE migrate-to-labels 使用指定的环境文件将现有的网络和卷迁移到使用标签的新结构 docker-compose --env-file docker.env migrate-to-labels

10.总结

在本文中,我们使用Docker Compose配置了多个服务,包括MySQL数据库、前台应用、Redis缓存和后台应用。我们详细介绍了每个服务的准备工作和配置。通过使用Docker Compose,我们可以方便地定义和管理多个服务之间的依赖关系,并快速搭建整个应用的开发和运行环境。希望本文对您有所帮助,谢谢阅读!

你可能感兴趣的:(Linux,docker,容器)