[关闭]
@jikeytang 2023-07-26T22:25:23.000000Z 字数 5789 阅读 370

Docker如何部署 Web 项目

2023-blog


Spring Boot 项目开发完成之后,就需要进行部署了,部署大概有这三种:

今天主要介绍在 Docker 上部署 SpringBoot 应用,本次的环境配置:

  1. 一台真实的服务器 4core 8G Memory 80G Disk
  2. Centos 7.9 (通过 cat /etc/redhat-release 查看)
  3. Java 11
  4. Spring Boot 2.7.5
  5. Mybatis 2.1.3
  6. Mysql 5.7

1. 安装Docker

  1. yum list docker-ce --showduplicates | sort -r
  1. yum -y install docker-ce-24.0.2-1.ce
  1. systemctl start docker
  2. systemctl enable docker

然后输入 docker version 进行信息验证,正常打印出Client, Server信息说明安装成功,如果没有正常打印,在重新检查安装步骤。

2. Docker中安装Nginx

Nginx 在这个场景通过代理转发的手段来隐藏真实项目的端口,比如:http://www.host.com:8080 让普通用户从默认 80 端口进行业务访问,最后就是: http://www.host.com,简洁明了。

同时分发其它域名的入口,比如一个服务器绑定多个域名时 Nginx 就是最好的工具,就是说 Docker 中运行一个 Nginx 容器就可以服务整个服务器。Mysql 也是同样的道理。

然后,这块业界的其它小伙伴也有不同的看法,因为 Nginx 做为唯一的 Web 服务器且在服务器上以版本稳定而著称。简单说,可以不放在容器当中,现在选择放在容器当中,是为了统一整合发布资源。

    1. # 下载最新版Nginx镜像
    2. docker pull nginx
    1. # 查当前所有Docker下载的镜像
    2. docker images
    1. # 创建挂载目录
    2. mkdir -p /home/nginx/conf
    3. mkdir -p /home/nginx/log
    4. mkdir -p /home/nginx/html
    1. # 生成容器
    2. docker run --name nginx -p 80:80 -d nginx
    3. # 将容器nginx.conf文件复制到宿主机
    4. docker cp nginx:/etc/nginx/nginx.conf /home/nginx/conf/nginx.conf
    5. # 将容器conf.d文件夹下内容复制到宿主机
    6. docker cp nginx:/etc/nginx/conf.d /home/nginx/conf/conf.d
    7. # 将容器中的html文件夹复制到宿主机
    8. docker cp nginx:/usr/share/nginx/html /home/nginx/
    1. # 删除Nginx容器
    2. docker ps -a
    3. # 关闭该容器
    4. docker stop nginx
    5. # 删除该容器
    6. docker rm nginx
    7. # 强制删除正在运行的nginx容器
    8. docker rm -f nginx
    9. # 这块新建之后又删掉这个容器主要目的是为了复制内部的nginx.conf到宿主容器
    1. #创建Nginx新容器并运行,然后修改/home/nginx/conf中的配置重启容器即可生效
    2. docker run \
    3. -p 80:80 \
    4. --name nginx \
    5. -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
    6. -v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
    7. -v /home/nginx/log:/var/log/nginx \
    8. -v /home/nginx/html:/usr/share/nginx/html \
    9. -d nginx
    1. # 增加各个配置
    2. # 由于 /home/nginx/conf/nginx.conf 中有这样一句话: include /etc/nginx/conf.d/*.conf;
    3. # 所以,其它站点的 nginx 配置文件放在 /home/nginx/conf/conf.d 目录下,每个文件以域名来命名,比如:vue-admin-cn.conf, react-admin.conf,这样做的好处是配置解耦,那个站点下线,直接删除对应配置重启nginx就可以生效而不影响其它应用
    4. server {
    5. listen 80;
    6. server_name react-admin.cn www.react-admin.cn;
    7. root /usr/share/nginx/html/react-admin.cn; # 真实的宿主目录是:/home/nginx/html/vue-admin.cn
    8. location / {
    9. proxy_pass http://111.111.111.111:3000/; # 服务器真实IP
    10. proxy_set_header X-Real-IP $remote_addr;
    11. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    12. proxy_set_header Host $http_host;
    13. proxy_no_cache 1;
    14. proxy_cache_bypass 1;
    15. }
    16. }
    1. # 配置好之后重启 nginx
    2. docker restart nginx

3. Docker中安装Mysql

Docker中的Mysql有三步,先拉取镜像然后运行导入数据,就可以正常连接了。

    1. # 拉取Mysql镜像
    2. docker pull mysql:5.7
    1. # 运行镜像
    2. docker run \
    3. -p 3306:3306 \
    4. --name mysql57 \
    5. -v ~/mysql/data:/var/lib/mysql \
    6. -e MYSQL_ROOT_PASSWORD=123456 \
    7. --privileged=true \
    8. docker.io/mysql:5.7
    1. # 上传sql到用户文件目录
    2. /home/boot/bootblog.sql
    3. # 拷贝文件进窗口
    4. docker cp bootblog.sql mysql:/bootblog.sql
    1. # 进入容器内部
    2. docker exec -it mysql57 bash
    1. # 登录Mysql,新建数据库之后导入
    2. mysql -uroot -p123456
    3. mysql> create DATABASE bootblog;
    4. mysql> mysql -uroot -p123456 -D bootblog < bootblog.sql
    5. mysql> show databases;

4. Docker中部署Java项目

  1. 首先Java项目中增加 application.dev.yml, application.prod.yml 配置文件,以此来管理本地开发环境和生产环境的配置区别,不仅仅是数据库连接,还可以包括其它配置。

    • 然后在 application.yml 中设置 spring.profiles.active=dev 激活当前开发环境使用 dev 配置
    • Dockerfile 中增加参数 -Dspring.profiles.active=dev
    • Docker run 时增加参数 SPRING_PROFILES_ACTIVE=dev
  2. 编写docker文件

    1. # 基础镜像
    2. FROM openjdk:11
    3. # 挂载目录
    4. VOLUME /home/bootblog
    5. # 暴露端口
    6. EXPOSE 8000
    7. # 执行命令
    8. ENTRYPOINT ["java","-Xmx256m","-Xms256m","-Dspring.profiles.active=prod","-jar","/data/java/jar/boot-blog-app.jar"]
  3. Maven clean, Meavn package 进行打包

  4. Docker 编译

    1. docker build -t bootblog .
  5. 运行容器

    1. docker run -d -p 8000:8000 -e "SPRING_PROFILES_ACTIVE=prod" --name bootblog -it -v /home/boot/jar:/data/java/jar bootblog
    2. # -d: 后台运行容器,并返回容器ID
    3. # -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
    4. # -e SPRING_PROFILES_ACTIVE=prod: 设置环境变量
    5. # --name="bootblog": 为容器指定一个名称,后续docker命令操作可以用这个name来识别,比如:docker logs bootblog
    6. # -it: 以交互模式为容器重新分配一个伪输入终端
    7. # -v: 挂载一个目录,后续只更新宿主目录(/home/boot/jar)中的.jar文件,而不用删除重新构建 docker
  6. 项目更新

    • 只需要更新 /home/boot/jar 中的jar文件
    • 不需要重启 docker

5. Docker中部署Nuxt项目

Docker中部署 Nuxt 有三步,先拉取镜像然后上传打包好的文件最后在 docker 运行。为什么不在服务器上打包,主要服务器内存有限,在服务器上打包需要安装: Git, Node一波下来都是消耗。

  1. 上传 .output/home/blog 目录
    1. # 编写 Dockerfile
    2. # 拉取node镜像
    3. FROM node:16-alpine
    4. #参数,node的环境为生产环境
    5. ENV NODE_ENV=production
    6. #容器内创建目录blog
    7. RUN mkdir -p /blog
    8. #复制当前的内容到容器内容部目录portal
    9. COPY .output/ ./blog
    10. #切换工作目录到blog
    11. WORKDIR /blog
    12. ENV HOST 0.0.0.0
    13. #RUN npm config set registry https://registry.npmmirror.com
    14. #设置外部访问端口,Nuxt的默认端口,如果需要转化在 Docker 启动的时候转化
    15. EXPOSE 3000
    16. # 运行命令以启动应用程序
    17. CMD ["node","./server/index.mjs"]
    1. # 打包项目镜像
    2. docker build -t blog .
    1. # 运行镜像
    2. docker run --name blog -d -p 3005:3005 blog

6. Docker中部署Next.js项目

Docker中部署 Next.js 有三步,先上传整个项目到资源目录,然后编写 Dockerfile,然后运行。

  1. 上传 next-demo/home/next 目录

    1. # 编写 Dockerfile
    2. # 拉取node镜像
    3. FROM node:16-alpine
    4. #容器内创建目录blog
    5. RUN mkdir -p /app
    6. #切换工作目录到app
    7. WORKDIR /app
    8. #参数,node的环境为生产环境
    9. ENV NODE_ENV=production
    10. COPY ./package*.json /app
    11. # 安装项目的生产依赖,而不安装开发依赖
    12. RUN npm install
    13. COPY ./ /app
    14. EXPOSE 3000
    15. CMD ["npm", "start"]
    1. # 打包项目镜像
    2. docker build -t nextblog .
    1. # 运行镜像
    2. docker run --name nextblog -d -p 3006:3000 nextblog

7. Docker中部署Nest项目

Docker中的Nest有三步,先拉取镜像然后运行导入数据,就可以正常连接了。

    1. # 设定环境
    2. FROM node:16-alpine
    3. # 设置时区
    4. ENV TZ=Asia/Shanghai
    5. #参数,node的环境为生产环境
    6. ENV NODE_ENV=production
    7. #容器内创建目录blog
    8. RUN mkdir -p /app
    9. # 指定工作目录
    10. WORKDIR /app
    11. # 复制当前代码到/app工作目录
    12. COPY ./ ./
    13. # npm 安装依赖
    14. COPY package.json /app/package.json
    15. RUN cd /app && rm -rf /app/node_modules && npm install
    16. #设置外部访问端口
    17. EXPOSE 3000
    18. # 运行命令以启动应用程序
    19. CMD [ "node", "dist/main" ]
    1. # 打包项目镜像
    2. docker build -t nestblog .
    1. # 运行镜像
    2. docker run --name nestblog -d -p 9000:3000 nestblog
    1. # 进入容器内部
    2. docker exec -it mysql57 bash
    1. # 登录Mysql,新建数据库之后导入
    2. mysql -uroot -p123456
    3. mysql> create DATABASE bootblog;
    4. mysql> mysql -uroot -p123456 -D bootblog < bootblog.sql
    5. mysql> show databases;

8. Docker中部署Go项目

Docker中的 Go 项目的部署就比较简单。有三步,上传打包好的文件,及相关的配置文件静态文件(如果有的话,go build是不打包静态文件,当然也有办法可以打包静态文件,这儿选择不打包),然后编写 Dockerfile,最后运行。

    1. # 定义打包环境 build.sh
    2. # 然后在命令行运行 build.sh
    3. GOOS=linux GOARCH=amd64 go build main.go
    1. # 定义版本
    2. FROM golang:1.18 as golang
    3. #容器内创建目录blog
    4. RUN mkdir -p /blog
    5. # 进入工作目录
    6. WORKDIR /blog
    7. COPY . .
    8. # 暴露服务端口
    9. EXPOSE 4001
    10. RUN chmod +x main
    11. # 容器启动时运行的命令
    12. ENTRYPOINT ["./main"]
    1. # 打包项目镜像
    2. docker build -t goblog .
    1. # 运行镜像
    2. docker run --name goblog -d -p 4001:4001 goblog
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注