掘金 后端 ( ) • 2024-04-16 15:30

本期分享的是服务器中通过docker compose服务编排的形式实现对java服务和web服务的部署,最后达到前端资源通过nginx路由转发到java服务所暴露的ip端口,实现一个完整项目的上线交付。

1.准备工作

工欲善其事必先利其器,在进行部署前,我们的服务器要先拉取配置必须的组件,以下为测试所需要的服务组件和简要作用,每个项目不同,所采用的组件和版本号也各不相同。请按实际情况进行配置。(组件的版本号需要和我们java服务maven配置的版本号保持一致,避免出现因版本导致的其他问题

服务名 版本号 作用 mysql 8.0.33 数据库 redis 6.2.4 缓存中间件 minio RELEASE.2024-03-15T01-07-19Z-cpuv1 存储服务 docker 26.0.1 容器部署 docker compose v2.26.1 编排部署

首先,先把这些服务的镜像拉取下来,方便后面通过服务编排一次性部署成容器。拉取命令如下,docker和docker compose自行百度进行安装,这儿不再进行赘述。

dockr pull  redis:6.2.4
docker pull mysql:8.0.3
3docker pull minio/minio:RELEASE.2024-03-15T01-07-19Z-cpuv

2.配置docker compose配置和d****ockerFile

2.通过编写docker compose的yml配置,docker的编排部署我这儿的理解用docker命令通过执行该yml配置和服务中的dockerFile进行容器创建,卷挂载,实现对docker容器的初始化。这边主要演示yml的配置信息,和web端,服务端的dockerFile配置,讲述三者之间的配置关系,使得web容器中的nginx通过卷挂载的方式,获取宿主机的nginx.conf配置,实现对服务端的调用。

2.1 docker compose的yml配置如下:

version: "3.8"

networks:
  byfn:

services:
  amps-store-sql:
    restart: always
    image: mysql:8.0.33
    container_name: store-sql
#    profiles: [ "alpha" ]
    command: |
      --mysqlx=0
      --secure_file_priv=
      --lower_case_table_names=1
      --default-authentication-plugin=mysql_native_password
      --sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
    ports:
      - "3306:3306"
    volumes:
      - "/data/amps/volumes/amps-store-sql/root:/root"
      - "/data/amps/volumes/amps-store-sql/data:/var/lib/mysql"
    environment:
      TZ: 'Asia/Shanghai'
      LANG: 'C.UTF-8'
      MYSQL_ROOT_PASSWORD: 'xxxx'
  amps-store-redis:
    restart: always
    image: redis:6.2.4
    container_name: store-redis
#    profiles: [ "alpha" ]
    ports:
      - "6379:6379"
    volumes:
      - "/root/data/amps-store-redis/data:/data"
      # - "/data/amps/volumes/amps-store-redis/conf/redis.conf:/etc/redis.conf"
    environment:
      TZ: 'Asia/Shanghai'
      LANG: 'C.UTF-8'
  amps-store-minio:
    restart: always
    image: minio/minio:RELEASE.2024-03-15T01-07-19Z-cpuv1
    container_name: store-minio
#    profiles: [ "alpha" ]
    command: server /data --console-address "0.0.0.0:9101"
    ports:
      - "9100:9000"
      - "9101:9101"
    environment:
      MINIO_ROOT_USER: "xxxx"
      MINIO_ROOT_PASSWORD: "xxxxxxxxxx"
      TZ: 'Asia/Shanghai'
    volumes:
      - "/root/data/amps-store-minio/data:/data"

  amps-web-meta:
    restart: always
    image: amps/amps-web-meta:1.0.0
    container_name: amps-web-meta
#    profiles: [ "main" ]
    build:
      context: $PWD/volumes/amps-web-meta
      dockerfile: amps-web-meta.dockerfile
    ports:
      - "80:80"
    volumes:
      - "$PWD/volumes/amps-web-meta/wwwroot:/wwwroot"
#    depends_on:
#      - amps-java-standalone
#
  amps-java-server:
    restart: always
    ports:
      - "8088:8088"
    build:
      context: $PWD/volumes/amps-java-server
      dockerfile: amps-java-server.dockerfile
    networks:
      - byfn
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - "$PWD/logs:/data/logs"

对上述不甚理解的朋友可以复制下来通过gpt解答一下,这份配置文件主要干的其实就是定义了几个docker镜像的容器创建启动,和各个容器在创建前发现没有镜像的情况下通过build的方式,将jar包或者web静态资源打包成image镜像创建启动容器。最后指定docker容器中的ip,目录和宿主机之间的挂载。

2.2 上传web端的静态资源和服务端的jar包,如图所示:

服务端:

image.png

服务端的dockerFile如下:

FROM openjdk:17  
  
VOLUME /tmp  
  
ADD amps-java-server-0.0.1-SNAPSHOT.jar amps-java-server.jar  
RUN bash -c 'touch /amps-java-server.jar'  
  
ENV TZ=Asia/Shanghai  
  
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone  
  
EXPOSE 8088  
  
ENTRYPOINT exec java -jar /amps-java-server.jar

该段dockerfile主要就是将当前目录下命名为amps-java-server-0.0.1-SNAPSHOT.jar的jar包添加到容器中命名为amps-java-server.jar。容器中暴露端口给外部宿主机,通过java-jar的命令将容器中的jar包run起来。

web端:

image.png

web端中的dockerfile配置如下:

FROM nginx:1.25.0  
LABEL maintainer='XXX<[email protected]>'  
  
COPY nginx.conf /etc/nginx/nginx.conf  
COPY wwwroot /wwwroot  
  
WORKDIR /wwwroot

****简而言之, 上述dockerfile配置的作用简而言之就是拉取通过nginx的镜像,将宿主机上当前目录下的wwwroot下的静态资源和nginx.conf配置文件配置到容器中的指定目录。

nginx.conf的配置文件如下:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      '[$server_name:$server_port]';

    access_log              /var/log/nginx/access.log  main;

    sendfile                on;

    keepalive_timeout       65;
    client_max_body_size    500m;
    client_body_buffer_size 500m;

    server {
        listen      80;
        listen      [::]:80;
        server_name 0.0.0.0;

        location ~* /api/ {
            rewrite ^/(.*)/api/(.*) /api/$2 break;
            proxy_pass          http://127.0。0.1:8088;
            proxy_set_header    Connection Upgrade;
            proxy_set_header    Upgrade $http_upgrade;
            proxy_set_header    X-real-ip $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version  1.1;
        }

        location / {
            root      /wwwroot;
            index     index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

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

    }

}

简而言之,上述的nginx.conf配置主要是通过一系列nginx的标准配置,将nginx自身配置和事件处理进行定义,http请求时上传主体的大小和web端请求路径通过api位置块进行匹配选择,路由到指定的http://xxx.xxx.x.x:xxxx服务器中,该处ip端口地址一般就是我们暴露的服务端地址和端口了****

最后,我们执行docker-compose up -d或者docker-compose up -d --force-recreate命令通过docker compose所配置的yml把当前目录下所配置的服务容器创建执行起来。实现一个完整的前后端的服务编排了。

image.png