要做的事情
- 前端应用实现容器化构建
- 容器化部署,使用
Docker-Compose管理容器 - 用
Nginx伺服静态资源 - 对接两个
server节点,用Nginx实现负载均衡 - 支持
https访问
编写 nginx.conf 文件
在前端代码库根目录编写 nginx.conf 文件
nginx.conf 内的层次结构如下:
events {
}
http {
upstream {
}
server {
location {
}
}
}
server
server 表示要监听的端口和对应的域名/IP,每个域名/IP 对应一个 server 配置项。
server_name 是对外提供服务的 ip/域名
e.g.
server {
listen 80;
server_name localhost;
}
server {
listen 443 ssl;
server_name www.safevue3.com;
}
https 配置
server {
listen 443 ssl;
server_name www.safevue3.com;
ssl_certificate cert/server.crt;
ssl_certificate_key cert/server.key;
}
这里的 ssl_certificate 和 ssl_certificate_key 是相对于 Nginx 根目录的。
正式环境需要申请
https证书,开发/测试环境可以用自签名的证书。 生成自签名证书可以使用openssl,命令如下:openssl genpkey -algorithm RSA -out server.key openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
location
location 表示路由,常用于反向代理。一般返回 html 都是 / 路由。如果需要反向代理,可以增加 location 配置项,配置对应的路由和 proxy_pass。
e.g.
location / {
root html;
index index.html index.htm;
}
几个反向代理的场景
场景 1:前端需要调两个后端服务的接口
思路
用不同的前缀区分不同服务的接口,通过 Nginx 反向代理。
处理方式
前端通过 url 前缀区分两个后端服务。e.g. /a 和 /b
请求先到达 Nginx,再由 Nginx 转发到对应服务的后台。需要配置 location 路由。
location /a {
proxy_pass http://<a服务的后端IP/域名 或者 a服务的upstream名字>;
}
location /b {
proxy_pass http://<b服务的后端IP/域名 或者 b服务的upstream名字>;
}
场景 2:两个前端应用,使用不用的域名,部署到同一个环境上,对接同一个后端服务。
思路
HTTP 请求的域名首先被 DNS 解析成 IP,再根据 IP 和端口(URL 没有端口号时,采用默认的端口)请求服务端。
由于两个应用部署在同一个环境上,所以域名解析出来的 IP 是相同的,单靠 IP 无法区分出请求来自哪个域名。
不过,请求头中还有 Host 字段,值为发起请求的域名。所以,Nginx 可以根据 Host 得知请求来自哪个域,从而转发请求到对应的服务。
处理方式
再搞个 Nginx 服务,做反向代理。根据请求头的 Host,将请求转发到对应的 Nginx。
upstream
upstream 可以理解成一组服务端节点的集合,常用于负载均衡。
可以在 location 下的 proxy_pass 中配置 upstream 的名字,把 location 和 upstream 关联起来。
upstream 中默认的负载均衡策略是轮询,其他的负载均衡策略还有 ip_hash 和 weight.
如果配置 ip_hash,只需要在 upstream 中单独一行写 ip_pash;
如果 upstream 中只配置了 server,没有其他属性,那就是轮询方式.
e.g.
upstream backend {
ip_hash;
server 192.168.1.102:3001;
server 192.168.1.102:3002;
}
server {
location /upstream {
proxy_pass http://backend;
}
}
画成图,就是如下形式:
容器化构建
在前端代码库根目录编写 Dockerfile 文件
基于 Nginx 基础镜像,构建前端应用的镜像.
要做的就是:
- 将构建产物目录
dist下的所有文件,复制到Nginx镜像中的/etc/nginx/html目录中 - 将
nginx.conf复制到/etc/nginx/下 - 为了支持
https,需要将证书目录cert复制到/etc/nginx/cert/中(本来nginx镜像中没有cert目录,需要用RUN mkdir创建目录)
容器化的
Nginx,不同版本的Nginx路径可能会有差异。可以用whereis nginx来查询Nginx的路径。
FROM nginx:1.26.1
COPY dist/ /etc/nginx/html/
COPY nginx.conf /etc/nginx/
RUN mkdir /etc/nginx/cert/
COPY cert/ /etc/nginx/cert/
构建 Docker 镜像时,在前端代码库根目录执行以下命令:
npm run build
docker build -t <镜像名> .
就把镜像构建出来了。可以使用以下命令查看已有的镜像:
docker images
如果要删除镜像,运行以下命令:
docker rmi <镜像ID 或者 镜像名:镜像版本号>
配置 Docker-Compose
为了方便拉起和销毁 Docker 容器,我们使用 Docker-Compose 来管理容器。
需要在 Linux 环境上维护一份 Docker-Compose.yml 配置文件。内容如下:
version: "3.8"
services:
vue2-demo:
image: vue2-demo:latest
ports:
- "443:443"
networks:
- mynetwork
server01:
image: koa2-demo:latest
ports:
- "3001:3000"
networks:
- mynetwork
volumes:
- ./logs:/app/logs # 将主机上的./logs目录挂载到容器的/app/logs目录
- data-volume:/app/data # 将名为data-volume的数据卷挂载到容器的/app/data目录
server02:
image: koa2-demo:latest
ports:
- "3002:3000"
networks:
- mynetwork
volumes:
- ./logs:/app/logs # 将主机上的./logs目录挂载到容器的/app/logs目录
- data-volume:/app/data # 将名为data-volume的数据卷挂载到容器的/app/data目录
networks:
mynetwork:
driver: bridge
volumes:
data-volume: # 定义一个名为data-volume的数据卷
services 下面是所有要拉起的容器
每个 service 需要配置对于的镜像 images,和端口号 ports
ports 为 <宿主机端口>:<容器内端口> 的形式
docker-componse.yml 配置好后,运行命令批量拉起容器:
docker-componse up -d
如果要停止并删除容器,运行以下命令:
docker-componse down
顺便讲几个 Docker 相关命令
查看运行中的容器
docker ps
查看所有容器(包括停止但没有删除的容器)
docker ps -a
手动删除容器
docker rm -f <容器ID>
查看容器的日志
docker logs <容器ID>
实时打印容器日志
docker logs -f <容器ID>
进入容器
docker exec -it <容器ID> sh