部署流程主要是先在服务器上构建基础环境:Docker, Docker-Compose, Portainer用于后续拉取镜像等。然后还需要在服务器构建应用环境,包括数据库MySQL, 缓存Redis。接下来是在本地把前后端分别打包镜像文件并推送到Docker Hub中由服务器拉取两个镜像完成部署。
1. 服务器环境配置 1.1 Docker安装 更新yum包,安装Doker依赖包
1 2 3 sudo yum update sudo yum install -y yum-utils device-mapper-persistent-data lvm2
更新doker yum源到阿里云
1 2 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
查看可以安装的Doker版本并安装指定版本
1 2 yum list docker-ce --showduplicates | sort -r yum install -y docker-ce-25.0.5 docker-ce-cli-25.0.5 containerd.io
1.2 安装Docker-Compose 从国内镜像地址安装,并设置权限。安装完成后验证一下版本。
1 2 3 4 sudo curl -L https://gitee.com/fustack/docker-compose/releases/download/v2.24.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose -v
1.3 启动Docker并添加开机自动启动 1 2 sudo systemctl start docker systemctl enable docker
1.4 设置Docker镜像源 国内现在访问不了Docker Hub,设置一下镜像源就可以成功拉取镜像了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://docker.1panel.live", "https://dc.j8.work", "https://docker.m.daocloud.io", "https://dockerproxy.com", "https://docker.mirrors.ustc.edu.cn", "https://docker.nju.edu.cn" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
1.5 Portainer Portainer 是一款用于管理 Docker 环境的图形化工具。它通过提供友好的 Web 界面,使用户可以更方便地管理 Docker 容器、镜像、网络、卷和服务等资源,而无需直接使用命令行操作。
拉取Portainer镜像,并启动Portainer
1 2 docker pull portainer/portainer docker run -d --restart=always --name portainer -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
1.6 安装JDK, Maven 本地下载好JDK和Maven tar包,写了一个脚本直接在服务器上安装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 # !/bin/sh # 定义JDK源文件和目标目录 JDK_SRC="/dev-ops/java/jdk-8u202-linux-x64.tar.gz" JDK_DST="/usr/local/java" # 检查JDK源文件是否存在 if [ ! -f "$JDK_SRC" ]; then echo "JDK 安装文件不存在: $JDK_SRC" exit 1 fi # 创建目标目录 mkdir -p "$JDK_DST" # 复制JDK压缩包到目标目录 cp "$JDK_SRC" "$JDK_DST" # 进入目标目录 cd "$JDK_DST" # 解压JDK压缩包 tar -zxvf "jdk-8u202-linux-x64.tar.gz" # 获取解压后的JDK目录名称 JDK_DIR=$(tar -tzf "jdk-8u202-linux-x64.tar.gz" | head -1 | cut -f1 -d"/") # 配置环境变量 echo "export JAVA_HOME=$JDK_DST/$JDK_DIR" >> /etc/profile echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> /etc/profile echo "export CLASSPATH=\$JAVA_HOME/jre/lib/ext:\$JAVA_HOME/lib/tools.jar" >> /etc/profile # 使环境变量立即生效 source /etc/profile # 输出安装完成 echo "Java installation completed." # 输出Java版本 java -version # 结束脚本 exit 0
2. 服务器应用环境配置 这一部分主要配置微服务所依赖的环境: mySQL, Redis等 使用Docker脚本直接执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 version: '3.9' services: mysql: image: mysql:8.0.32 container_name: mysql command: --default-authentication-plugin=mysql_native_password restart: always environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123456 networks: - my-network depends_on: - mysql-job-dbdata ports: - "13306:3306" volumes: - ./mysql/sql:/docker-entrypoint-initdb.d healthcheck: test: [ "CMD" , "mysqladmin" ,"ping" , "-h" , "localhost" ] interval: 5s timeout: 10s retries: 10 start_period: 15s volumes_from: - mysql-job-dbdata mysql-job-dbdata: image: alpine:3.18.2 container_name: mysql-job-dbdata volumes: - /var/lib/mysql phpmyadmin: image: phpmyadmin:5.2.1 container_name: phpmyadmin hostname: phpmyadmin ports: - 8899 :80 environment: - PMA_HOST=mysql - PMA_PORT=3306 - MYSQL_ROOT_PASSWORD=123456 depends_on: mysql: condition: service_healthy networks: - my-network redis: image: redis:6.2 container_name: redis restart: always hostname: redis privileged: true ports: - 16379 :6379 volumes: - ./redis/redis.conf:/usr/local/etc/redis/redis.conf command: redis-server /usr/local/etc/redis/redis.conf networks: - my-network healthcheck: test: [ "CMD" , "redis-cli" , "ping" ] interval: 10s timeout: 5s retries: 3 redis-admin: image: spryker/redis-commander:0.8.0 container_name: redis-admin hostname: redis-commander restart: always ports: - 8081 :8081 environment: - REDIS_HOSTS=local:redis:6379 - HTTP_USER=admin - HTTP_PASSWORD=admin - LANG=C.UTF-8 - LANGUAGE=C.UTF-8 - LC_ALL=C.UTF-8 networks: - my-network depends_on: redis: condition: service_healthy networks: my-network: driver: bridge
使用Docker-compose 执行该脚本docker-compose -f docker-compose-environment.yml up -d
3. 本地前后端应用推送到Docker-Hub 3.1 前端构建镜像 next.config.ts
中新增target: 'server',
output: "standalone",
用于控制项目的构建和部署行为,特别是构建后如何打包和运行应用
新增Dockerfile用于构建镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 FROM node:18 -alpine AS base FROM base AS deps RUN apk add --no-cache libc6-compat WORKDIR /app COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ RUN yarn config set registry 'https://registry.npmmirror.com/' RUN yarn install FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN yarn build FROM base AS runner WORKDIR /app COPY --from=builder /app/public ./public COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static COPY --from=builder /app/.next/server ./.next/server EXPOSE 3000 ENV PORT 3000 ENV HOSTNAME "0.0.0.0" CMD ["node" , "server.js" ]
通过脚本构建镜像: docker build -t priska/big-market-front-app:1.0 .
中间出现很多bug。node.js
和react
还是很难用的。比如要让Eslint禁用:
1 2 3 4 5 6 7 8 { "extends" : [ "next/core-web-vitals" , "next/typescript" ] , "extends" : "next" , "rules" : { "react/no-unescaped-entities" : "off" , "@next/next/no-page-custom-font" : "off" } }
更改一些已经编写好的typescript文件
3.2 后端构建镜像 将配置文件从开发配置改成工程配置,在aplication.yml
中修改profiles: active: prod
然后修改对应的工程配置,把对应的数据库,缓存等配置成生产环境的, 这里只列出关键信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 app: config: api-version: v1 cross-origin: '*' spring: datasource: username: 服务器数据库用户名 password: 服务器数据库密码 url: jdbc:mysql://127.0.0.1:3306/... redis: sdk: config: host: 127.0 .0 .1 port: 16379
使用dockerfile进行镜像构建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 FROM openjdk:8 -jre-slim MAINTAINER priska ENV PARAMS="" ENV TZ=PRC RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ADD target/big-market-app.jar /big-market-app.jar ENTRYPOINT ["sh" ,"-c" ,"java -jar $JAVA_OPTS /big-market-app.jar $PARAMS " ]
4. 服务器开启服务 将写好的docker-compose-app放到服务器拉取已经上传的前后端镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 version: '3.8' big-market-app: image: yaqiyu/big-market-app:1.5 container_name: big-market-app restart: always ports: - "8091:8091" environment: - TZ=PRC - SERVER_PORT=8091 - APP_CONFIG_API_VERSION=v1 - APP_CONFIG_CROSS_ORIGIN=* - SPRING_DATASOURCE_USERNAME= - SPRING_DATASOURCE_PASSWORD= - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/big_market?serverTimezone=UTC&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Shanghai - SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver - SPRING_HIKARI_POOL_NAME=Retail_HikariCP - REDIS_SDK_CONFIG_HOST=redis - REDIS_SDK_CONFIG_PORT= volumes: - ./log:/data/log networks: - my-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" big-market-front-app: container_name: big-market-front-app image: yaqiyu/big-market-front-app:1.0 restart: always networks: - my-network ports: - 3000 :3000 environment: - API_HOST_URL=http://127.0.0.1:8091 - PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin healthcheck: test: [ "CMD" , "wget" , "--spider" , "-q" , "http://0.0.0.0:3000/" ] interval: 1m timeout: 10s retries: 3 networks: my-network: driver: bridge