13 使用 Docker 部署苍穹外卖

演示地址 http://106.52.82.222:5501/ 调整项目 由于生产环境和开发环境有所区别,所以需要进行一些调整 数据库 可以使用数据库工具远程链接服务器上面的数据库,运行sql导入数据 成功运行 后端 配置 后端的配置文件一般分为三个 application.yml applicat

演示地址

http://106.52.82.222:5501/

调整项目

由于生产环境和开发环境有所区别,所以需要进行一些调整

数据库

可以使用数据库工具远程链接服务器上面的数据库,运行sql导入数据

成功运行

后端

配置

后端的配置文件一般分为三个

  • application.yml
  • application-dev.yml
  • application-prod.yml

本项目的部分 application.yml 如下:

# 应用服务 WEB 访问端口  
spring:  
  profiles:  
    active: dev # 默认使用开发环境配置  
server:  
  port: 8080

部分 application-prod.yml 如下:

sky:  
  datasource:  
    driver-class-name: com.mysql.cj.jdbc.Driver  
    host: ${DB_HOST}  
    port: ${DB_PORT}  
    database: ${DB_NAME}  
    username: ${DB_USERNAME}  
    password: ${DB_PASSWORD}  
  redis:  
    host: ${REDIS_HOST}  
    port: ${REDIS_PORT}  
    password: ${REDIS_PASSWORD}
    database: ${REDIS_DATABASE}

打包前需要将dev改成prod,使用生产环境的配置

构建

将配置修改好后,使用maven生命周期的package对项目进行打包

target目录下的jar包就是我们需要的

前端

如果是跟着视频学习的话,前端项目用的是提供好的代码,直接使用即可,同时 nginx 配置也是提供好的,后续部署会修改使用

部署

Redis

由于后续项目也可能会使用 Redis,所以先单独部署一个 Redis

通过docker compose 一键部署,参考了 使用 Docker Compose 部署单机版 Redis:简单高效的数据缓存与存储-阿里云开发者社区

services:
  redis:
    image: redis:latest
    container_name: redis
    restart: always
    ports:
      - '6379:6379'
    volumes:
      - ./data:/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf
      - ./logs:/logs
    #配置文件启动
    command: redis-server /usr/local/etc/redis/redis.conf

配置文件 redis.conf

# Redis 服务器的端口号(默认:6379)
port 6379

# 绑定的 IP 地址,如果设置为 127.0.0.1,则只能本地访问;若设置为 0.0.0.0,则监听所有接口(默认:127.0.0.1)
bind 0.0.0.0

# 设置密码,客户端连接时需要提供密码才能进行操作,如果不设置密码,可以注释掉此行(默认:无)
# requirepass foobared
requirepass password

# 设置在客户端闲置一段时间后关闭连接,单位为秒(默认:0,表示禁用)
# timeout 0

# 是否以守护进程(daemon)模式运行,默认为 "no",设置为 "yes" 后 Redis 会在后台运行
daemonize no

# 设置日志级别(默认:notice)。可以是 debug、verbose、notice、warning
loglevel notice

# 设置日志文件的路径(默认:空字符串),如果不设置,日志会输出到标准输出
logfile ""

# 设置数据库数量(默认:16),Redis 使用数据库索引从 0 到 15
databases 16

# 是否启用 AOF 持久化,默认为 "no"。如果设置为 "yes",将在每个写操作执行时将其追加到文件中
appendonly no

# 设置 AOF 持久化的文件路径(默认:appendonly.aof)
# appendfilename "appendonly.aof"

# AOF 持久化模式,默认为 "always"。可以是 always、everysec 或 no
# always:每个写操作都立即同步到磁盘
# everysec:每秒钟同步一次到磁盘
# no:完全依赖操作系统的行为,可能会丢失数据,但性能最高
# appendfsync always

# 设置是否在后台进行 AOF 文件重写,默认为 "no"
# auto-aof-rewrite-on-rewrite no

# 设置 AOF 文件重写触发时,原 AOF 文件大小与新 AOF 文件大小之间的比率(默认:100)
# auto-aof-rewrite-percentage 100

# 设置是否开启 RDB 持久化,默认为 "yes"。如果设置为 "no",禁用 RDB 持久化功能
save 900 1
save 300 10
save 60 10000

# 设置 RDB 持久化文件的名称(默认:dump.rdb)
# dbfilename dump.rdb

# 设置 RDB 持久化文件的保存路径,默认保存在当前目录
# dir ./

# 设置是否开启对主从同步的支持,默认为 "no"
# slaveof <masterip> <masterport>

# 设置主从同步时是否进行数据完整性校验,默认为 "yes"
# repl-diskless-sync no

# 设置在复制时是否进行异步复制,默认为 "yes",可以加快复制速度,但会增加数据丢失的风险
# repl-backlog-size 1mb

# 设置是否开启集群模式(cluster mode),默认为 "no"
# cluster-enabled no

# 设置集群中的节点超时时间(默认:15000毫秒)
# cluster-node-timeout 15000

# 设置集群中节点间通信使用的端口号(默认:0)
# cluster-announce-port 0

# 设置集群中节点间通信使用的 IP 地址
# cluster-announce-ip 127.0.0.1

# 设置是否开启慢查询日志,默认为 "no"
# slowlog-log-slower-than 10000

# 设置慢查询日志的最大长度,默认为 128
# slowlog-max-len 128

# 设置每秒最大处理的写入命令数量,用于保护 Redis 服务器不被超负荷写入(默认:0,表示不限制)
# maxclients 10000

# 设置最大连接客户端数量(默认:10000,0 表示不限制)
# maxmemory <bytes>

# 设置最大使用内存的策略(默认:noeviction)。可以是 volatile-lru、allkeys-lru、volatile-random、allkeys-random、volatile-ttl 或 noeviction
# maxmemory-policy noeviction

# 设置允许最大使用内存的比例(默认:0),设置为 0 表示禁用
# maxmemory-samples 5

上传文件

将打包好的前后端项目上传,目录结构如下

编写后端 Dockerfile 文件

backend/Dockerfile

# 使用官方 Eclipse Temurin Java 17 镜像作为基础镜像
FROM eclipse-temurin:17-jre

# 设置容器内的工作目录
WORKDIR /app

# 将编译好的应用文件(例如jar包)复制到容器内
COPY jar/sky-server-1.0-SNAPSHOT.jar ./

# 容器启动时执行的命令
CMD ["java", "-jar", "sky-server-1.0-SNAPSHOT.jar"]

编写前端 Docker 及其配置文件

frontend/Dockerfile

# 使用官方Nginx镜像作为基础镜像
FROM nginx:stable

# 将本地的nginx配置文件复制到容器内
COPY nginx.conf /etc/nginx/nginx.conf

# 将前端构建文件(例如dist目录)复制到nginx的html目录
COPY dist/ /usr/share/nginx/html/sky/

frontend/nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    
    sendfile        on;
    keepalive_timeout  65;

    map $http_upgrade $connection_upgrade{
        default upgrade;
        '' close;
    }

    upstream webservers{
      server sky-take-out-backend:8080 weight=90 ;
      #server 127.0.0.1:8088 weight=10 ;
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html/sky;
            index  index.html index.htm;
        }

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # 反向代理,处理管理端发送的请求
        location /api/ {
            proxy_pass   http://webservers/admin/;
        }

        # 反向代理,处理用户端发送的请求
        location /user/ {
            proxy_pass   http://webservers/user/;
        }

        # WebSocket
        location /ws/ {
            proxy_pass   http://webservers/ws/;
            proxy_http_version 1.1;
            proxy_read_timeout 3600s;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "$connection_upgrade";
        }
    }
}

/api/ 可以将 api 后面的 url 拼接到 proxy_pass 后面,注意 proxy_pass 中的后端 url 也需要加一道斜杠

构建部署

编写docker compose 文件

services:
  # 定义后端服务
  backend:
    container_name: sky-take-out-backend
    build:
        context: ./backend  # 后端项目路径
        dockerfile: Dockerfile  # Dockerfile 文件路径
    volumes:
        - ./backend/jar/sky-server-1.0-SNAPSHOT.jar:/app/sky-server-1.0-SNAPSHOT.jar
    environment:
        DB_HOST: mysql57
        DB_PORT: 3306
        DB_NAME: sky_take_out
        DB_USERNAME: username
        DB_PASSWORD: password
        REDIS_HOST: redis
        REDIS_PORT: 6379
        REDIS_DATABASE: 0
        REDIS_PASSWORD: password
    networks:
        - sky-take-out
        - mysql # 加入mysql所在的网络
        - redis
    restart: unless-stopped

  # 定义前端服务
  frontend:
    container_name: sky-take-out-frontend
    build:
        context: ./frontend  # 前端项目路径
        dockerfile: Dockerfile  # Dockerfile 文件路径
    ports:
        - "5501:80"  
    volumes:
        - ./frontend/sky:/usr/share/nginx/html/sky/
        - ./frontend/nginx.conf:/etc/nginx/nginx.conf
    networks:
        - sky-take-out
    restart: unless-stopped

networks:
    sky-take-out:
        name: sky-take-out
    mysql:
        external: true
    redis:
        external: true

运行命令

docker compose -f /root/apps/zoo/docker-compose.yaml up -d --build

访问

Comment