目前项目开发方式基本采用前后端分离的方式。前端作为一个独立的项目,一般是使用Webpack方式进行编译打包生成 dist 目录(特指vue项目),再通过Nginx单独进行部署。
为了和基于Docker的部署方式有个对比,我们先来说下服务器部署方式

服务器部署方式

一般来说,常规的部署方式的流程基本如下:

  1. 服务器环境配置及安装 nginx
  2. 将项目dist目录上传到服务器的指定位置
  3. 修改 nginx安装目录/conf/nginx.conf 文件,配置dist目录及后端项目的代理地址
  4. 启动nginx
    ok搞定,说起来很简单,其实最繁琐的操作基本是在第1步,nginx安装及环境配置。
    为了解决环境难的问题,锵锵锵,上docker

基于Docker的部署方式

基于Docker的部署方式可以简单分为两种,一种是直接使用原生的nginx镜像进行部署,一种是通过构建新的业务镜像进行部署。

使用原生的nginx镜像进行部署

这种方式和 服务器部署方式 基本类似。基本流程如下:

  1. 将项目dist目录上传到服务器的指定位置(eg: /home/dist)
  2. 准备好已经配置了 dist 目录及后端项目代理地址的 nginx.conf(eg: /home/nginx.conf)
  3. 拉起nginx镜像,通过挂载数据卷将 dist目录以及事先准备好的nginx.conf挂在到nginx容器中(eg: docker run -d -v /home/dist:/dist -v /home/nginx.conf:/etc/nginx/nginx.conf -p 8088:80 nginx:latest)
    ok搞定,访问 ip:8088即访问前端项目。

通过构建新的业务镜像进行部署

“使用原生的nginx镜像进行部署”的方式对比“服务器部署方式”来说是方便了一点,但是,部署时还要搞下dist目录,再搞下nginx.conf,这好像也有丢丢麻烦。咋办呢?
主角出场:构建新的业务镜像进行部署
问:为什么要这么做?
答:前端项目部署,说到底无非就是准备好dist目录以及在nginx.conf配置后端项目的地址。对于dist目录,静态目录完全可以预先放置在镜像中;而配置后端项目地址,其实就是一个值的问题,完全可以把这个值抽取成镜像中的一个环境变量。既然相关的步骤都能支持,直接构建一个新的镜像,部署时只需要配置个环境变量,舒舒服服,何乐而不为呢
具体操作

  1. 编写 nginx.conf.template(配置dist目录、后端项目地址抽取为环境变量)
user nginx;

worker_processes 1;
error_log logs/error.log error;
pid logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
	log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';			
	access_log logs/access.log combined;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /dist;
            index  index.html;
        }
		
		location /backend/ {
			proxy_pass ${BACKEND_URL}; #后端项目 http://ip:port
		}

		location /backend2/ {
			proxy_pass ${BACKEND2_URL}; #后端项目2
		}

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  1. 编写 Dockerfile(定义业务镜像构建流程)
FROM nginx:latest

RUN mkdir /dist
COPY ./dist /dist
COPY ./nginx.conf.template /

ENV BACKEND_URL=""
ENV BACKEND2_URL=""

CMD envsubst '$BACKEND_URL $BACKEND2_URL' < /nginx.conf.template > /etc/nginx/nginx.conf \
	&& cat /etc/nginx/nginx.conf \
	&& nginx -g 'daemon off;'
  1. 构建前端镜像
    将 dist目录、nginx.conf.template、Dockerfile 放到同个目录中,结构如下:
    frontend-docker目录
      | - dist
      | - nginx.conf.template
      | - Dockerfile
    进入frontend-docker目录,执行命令 docker build -f Dockerfile -t my-frontend:v1.0 . (注意最后的‘.’)进行镜像的构建。
    最终生成了一个镜像,名称为 my-frontend:v1.0
  2. 运行镜像,执行命令 docker run -d -e BACKEND_URL=192.168.1.10:8080 -e BACKEND2_URL=192.168.1.10:8081 -p 8088:80 my-frontend:v1.0
    ok搞定,访问 ip:8088即访问前端项目。

其实,有人会有疑问了,“通过构建新的业务镜像进行部署”方式是不是更复杂更繁琐了!
呃。。。咋一看是的。各种准备写配置,执行命令啥的。

但是呢,其实这些步骤是可以自动化的,像目前比较流行的持续集成方案jenkins,它支持从接收到git push事件后,就执行这一系列动作,包括:拉取源代码、打包、构建镜像、运行镜像等等。我们只需要准备好某些环节必要的文件(比如构建镜像的Dockerfile文件),这个流程就是模板一般按部就班。所以,重新构建业务镜像这种部署方式不仅仅是方便在不同环境中快速部署,更是较方便的接入自动化部署流程。(大言不惭的妄下定论哈哈)
so,pick它,没错。


end

reference:
论Docker容器中的Nginx配置文件如何读取系统/容器的环境变量
https://github.com/docker-library/docs/tree/master/nginx#using-environment-variables-in-nginx-configuration
https://serverfault.com/questions/577370/how-can-i-use-environment-variables-in-nginx-conf
Nginx官方文档
http://nginx.org/en/docs/ngx_core_module.html

Logo

前往低代码交流专区

更多推荐