使用 docker-compose 部署 SpringBoot 项目 & nginx 部署前端

安装 Docker

自动下载

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

检查是否安装成功

docker -v

image-20231031135739923

配置镜像仓库

更换镜像加速器(推荐阿里云)

容器镜像服务 (aliyun.com)

扫码登录后找到镜像仓库

每个人都不同,复制自己的镜像仓库

image-20230618171351652

复制好上面的地址后,编辑到 daemon.json 中

vi /etc/docker/daemon.json

image-20231031140340869

ESC ,使用 :wq 保存

启动 docker

systemctl start docker

安装 docker-compose

安装命令行

curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

设置文件权限

chmod +x /usr/local/bin/docker-compose

查看版本

docker-compose -v

image-20231031140815313

编写 Dockerfile

Dockerfile 可以将我们的项目打包好的 jar 包转换为镜像

这里我将 dockerfile 以及 docker-compose 放在了项目包中,这里位置可随意,最后要上传到服务器上的

image-20231031141103201

文件内容

Dockerfile 的文件内容为

# 设置jdk版本
FROM java:8

# 设置我们的个人信息,大家根据需求随便写
MAINTAINER daqi <daqi_email@163.com>

# 这两行是设置我们容器内的时间以及 jvm 的时间(默认不是 GMT )
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone

# 前面的 【Esurvey-backend-1.1.jar】 是我们上传的 jar 包名称(在 target 目录中打包的 jar 包),后面的【springboot.jar】是我们新命名的 jar 包
ADD Esurvey-backend-1.1.jar springboot.jar

# 镜像启动成为容器后,对外暴露的端口
EXPOSE 9996

# Image创建容器时的初始化内存,最大内存,及启动时使用的profile. -c为清除以前启动的数据
ENTRYPOINT ["java","-Xms1024m","-Xmx1024m","-jar","/springboot.jar","--spring.profiles.active=prod","-c"]

说明:

**FROM java:8:**这是一个 FROM 指令,指定基础镜像为 java:8,也就是包含 Java 8 环境的镜像

**MAINTAINER daqi daqi_email@163.com:**这是一个 MAINTAINER 指令,指定镜像的作者和联系方式

**RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime:**这是一个 RUN 指令,执行一个命令,并将结果保存到镜像中。这个命令是将亚洲/上海时区文件复制到 /etc/localtime 文件中,设置容器内的时区为亚洲/上海

**ADD Esurvey-backend-1.1.jar springboot.jar:**这是一个 ADD 指令,将本地或远程文件或目录复制到镜像中。这个命令是将 Esurvey-backend-1.1.jar 文件复制到镜像中,并重命名为springboot.jar。如果只需要复制本地文件或目录,建议使用 COPY 指令代替 ADD 指令

**EXPOSE 9996:**这是一个 EXPOSE 指令,声明容器运行时监听的端口。这个指令不会实际开放端口,只是一种文档化的作用,需要在运行容器时使用 -p 或 -P 参数来映射端口。这个命令是声明容器监听9996端口

**ENTRYPOINT [“java”,“-Xms1024m”,“-Xmx1024m”,“-jar”,“/springboot.jar”,“–spring.profiles.active=prod”,“-c”]:**这是一个 ENTRYPOINT 指令,定义容器启动时运行的可执行程序和参数。这个指令可以与 CMD 指令配合使用,CMD 指令中的参数会追加到 ENTRYPOINT 指令中。这个命令是定义容器启动时运行 java 程序,并设置内存、jar 包和 profile 等参数。

编写 docker-compose 文件

介绍

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YAML 文件来配置应用程序需要的所有服务,然后使用一个命令就可以创建并启动所有服务。Docker Compose 可以帮助您简化容器的管理,实现服务的快速部署、扩展和升级

Docker Compose 的主要作用有以下几点:

  • 一次性创建和启动多个容器,实现应用程序的多服务协作
  • 使用 YAML 文件来定义服务的配置,避免重复输入命令行参数
  • 通过项目名来隔离不同的应用环境,避免容器、网络和卷之间的冲突
  • 提供了一系列命令来管理容器的生命周期,如构建、启动、停止、重启、销毁等
  • 支持使用变量和模板来参数化和复用配置文件

文件内容

找一个地方创建文件 docker-compose.yml

# 指定我们docker-compose的版本
version: "3"

# 设置我们的服务
services:

  # 配置mysql服务
  mysql:

    # 这里指定 mysql 镜像文件,mysql 版本是 8.0.27,这里要使用 docker 命令拉取镜像
    image: mysql:8.0.27

    # 配置容器名字
    container_name: esurvey-mysql

    # 通过我们的宿主机的 9995 端口映射到容器里的 3306 端口,因为容器内的网络与我们外界是不互通的,只有宿主机能够去访问我们的容器,这样我们就能通过宿主机的 9995 端口去访问容器的 mysql了
    ports:
      - "9995:3306"

    # 配置环境,主要是配置我们的mysql的登陆密码,mysql容器创建出来默认可以用不同的ip地址访问,所以这里不用进行配置
    environment:
      - MYSQL_ROOT_PASSWORD=mysql2023

    # 配置挂载的文件夹,在当前文件夹下面创建 mysql 文件夹,里面有 conf,logs,data,分别挂载到容器mysql 中的 conf.d,logs,mysql 中,这样当我们的容器如果没了,但是我们的数据还是在的
    volumes:
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/logs:/logs
      - ./mysql/data:/var/lib/mysql

  # 配置 redis 服务
  redis:

    # 设置容器对应的镜像,同上
    image: redis:6.2.7

    # 设置容器名
    container_name: esurvey-redis

    # 设置命令,这里是用来设置我们的redis登陆密码的,root处是密码,自己根据需求填入即可
    command: redis-server --requirepass redis2023

    # 同上,作为端口映射
    ports:
      - "9994:6379"

    # 同上,挂载文件夹
    volumes:
      - ./redis:/data

  # 配置springboot服务
  springboot:
    # 生成镜像,用.它会自动去当前目录下面去找一个Dockerfile的文件,然后根据里面的配置去生成一个镜像
    build: .

    # 指定我们生成的镜像的名字和版本号
    image: springboot:v1.1

    # 指定容器名
    container_name: Esurvey-backend

    # 同上,做端口映射
    ports:
      - "9996:9996"

    # 写清楚我们springboot依赖的服务,有 mysql 以及 redis,这里的名称是 service 名
    depends_on:
      - mysql
      - redis

修改 application-prod.yml

项目中使用了 spring.profiles.active 控制项目环境,这里修改 application-prod.yml 生成环境上的一些连接配置

  1. 修改 mysql 的 url,改为服务器 ip:端口
  2. 同理 redis 的 host 也改为 ip,同时端口也要和上面 docker-compose.yml 配置的一样

注:可以试一下 msyql:9995 以及 redis:9994 的访问方式,我没有访问成功,可能是 不在同一个 network 的原因,大家也可以试一下

image-20231031142742762

使用 docker-compose 运行容器

使用 xhell 连接服务器(也可以使用其他的远程连接),将打包好的 jar 包,Dockerfile,docker-compose 放在文件夹中

以我为例,我统一放在了 /home/server/Esurvey/Esurvey-backend 下,目录结构如下

image-20231031143302680

redis 和 mysql 文件是在运行容器后产生的,是映射容器中的数据卷

进入到当前的目录

image-20231031143558846

运行

docker-compose up -d

image-20231031143629359

这样后端 java 项目就运行成功了

前端项目 Nginx 部署

上传文件

同样,将打包好的文件上传到服务器

以我为例,我传到了 /home/server/Esurvey/Esurvey-app

image-20231031143956291

注意,将前端项目中的请求前缀去掉,我们是通过 nginx 反向代理访问的

安装 Nginx

这里如何用命令行安装就不赘述了

我使用宝塔安装 nginx,在软件商城中安装

配置文件修改

文件中修改 http 下的内容

注意 server 的位置,在 http 中的,这里监听了 9998 端口,首页文件是 index.html,文件路径是上传路径

location ^~ /api/ 是匹配 /api/ 路径然后代理成 http://127.0.0.1:9996/api/,这个地址是后端的地址

server {
  listen 9998;
  server_name xxxx.top;
  index index.html;
  root  /home/server/Esurvey/Esurvey-app;
  
  location ^~ /api/ {
    proxy_pass http://127.0.0.1:9996/api/;
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers '*';
    	if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Origin' $http_origin;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    	}
	}
}

重载 nginx,配置就生效了,页面也就可以访问了