Skip to main content

Docker 发布部署

前端容器化

  1. 本地开发(3000)
npm run start
  1. 本地编译(8000)
npm run build
http-server -p 8000 ./dist
  1. 拉取 nginx 镜像
docker nginx
  1. 添加.dockerignore
node_modules;
build;
  1. 添加 Dockerfile (80)

通过 其他服务镜像 node/nginx 等 创建 自定义镜像

# 基于node14
FROM node:14

# 设置环境变量
ENV PROJECT_ENV production
ENV NODE_ENV production

# 安装nginx
RUN apt-get update && apt-get install -y nginx

# 把所有源代码拷贝到/app
COPY . /app

# 切换到app目录
WORKDIR /app

# 拷贝配置文件到nginx
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

# 启动nginx,关闭守护式运行,否则容器启动后会立刻关闭
CMD ["nginx", "-g", "daemon off;"]
  1. 打包镜像(80)
docker build --no-cache -t timeline/react-nginx .
  1. 启动容器(8888:80)
docker run -d --name react-nginx-timeline  -p 8888:80 timeline/react-nginx

Node 容器化

  1. 本地开发(mysql 3306)(node 8000)
npm run dev
  1. 创建网络
docker network create app-timeline
  1. 拉取 mysql / node 镜像
docker pull --platform linux/x86_64 mysql:5.7

docker pull node:14
  1. 创建网络(mysql 3307:3306)(node 8000)
docker run -p 3307:3306 --name mysql-timeline  --network app-timeline -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

docker run -it --name node-timeline --network app-timeline node:14 /bin/bash
  1. 测试通信 自动进入 node-timeline
ping mysql-timeline
  1. 修改 mysql 的 host 改为 db 统一 host
MYSQL_CONF = {
// host: "localhost",
host: "db",
user: "root",
password: "123456",
port: "3306",
database: "timeline",
};
  1. 新建一个 Dockerfile(设置端口为 8000 同 node 端口一致)
# 基于node14
FROM node:14

# 把 package.json package-lock.json 复制到/app目录下
# 为了npm install可以缓存
COPY package*.json /app/

# 切换到app目录 同cd
WORKDIR /app

# 安装依赖
RUN npm install

# 把所有源代码拷贝到/app
COPY . /app

# 设置端口
EXPOSE 8000

# 运行启动
ENTRYPOINT ["npm", "run"]
CMD ["dev"]
  1. 构建镜像(端口为 8000)
docker build -t timeline/node-mysql .
  1. 启动容器(mysql 3307:3306)(node 4444:8000)
# 创建网络
docker network create app-timeline

# 端口冲突:需要先删除 mysql-timeline 容器

# 重新启动mysql容器需要密码
docker run -p 3307:3306 --name db --network app-timeline -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

# 关闭无用node-timeline 测试容器

# 启动node-mysql 容器
docker run --name node-mysql-timeline -p 4444:8000 --network app-timeline -d timeline/node-mysql
  1. 测试 http://localhost:4444/

关联 前端容器化 与 Node 容器化

  1. 修改 react-app 目录下的 nginx.conf(映射 8000)

修改后必须先启动 Node 容器化,否则找不到 proxy_pass http://node-mysql-timeline:8000;

server {
listen 80;
server_name localhost;

location / {
root /app/build; # 打包的路径
index index.html index.htm;
try_files $uri $uri/ /index.html; # 防止重刷新返回404
}

location /api {
proxy_pass http://node-mysql-timeline:8000; # 添加后台api 代理地址
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
  1. 重新构建镜像
docker build -t timeline/react-nginx-node .
  1. 启动容器(9999:80)
docker run -d --name react-nginx-node-timeline --network app-timeline  -p 9999:80 timeline/react-nginx-node
  1. 测试 http://localhost:9999/mobile_index.html

docker-compose 开启多容器(本地)

  1. 编写 docker-compose.yml
version: "3.7"

services:
node-mysql-timeline:
image: timeline/node-mysql # 指定镜像
restart: always # 自动重启
ports: # 端口映射
- 4444:8000
networks: # 网络通信
- app-timeline

react-nginx-node-timeline:
image: timeline/react-nginx-node # 指定镜像
restart: always # 自动重启
depends_on:
- node-mysql-timeline
ports: # 端口映射
- 9999:80
networks: # 网络通信
- app-timeline

networks:
app-timeline: # 加入网络,引用顶级networks下条目
driver: bridge
  1. 开启多容器 注意:启动前需要把之前的容器暂停,接口不能冲突!
# 启动所有容器
docker-compose up -d

# 停止所有容器
docker-compose stop

发布 Docker Hub 镜像

  1. 登录
docker login
  1. 创建镜像及版本
# docker tag 本地镜像(镜像名) 远程镜像(用户名/镜像名: lastest / v.1.0

docker tag timeline/react-nginx-node xinjn/timeline-react-nginx-node:latest

docker tag timeline/node-mysql xinjn/timeline-node-mysql:latest
  1. 推送远程 docker hub
docker push xinjn/timeline-react-nginx-node:latest

docker push xinjn/timeline-node-mysql:latest
  1. 拉取远程 docker hub
docker pull xinjn/timeline-react-nginx-node:latest

docker pull xinjn/timeline-node-mysql:latest

docker-compose 开启多容器(远程)

  1. 重新编写 docker-compose.yml
version: "3.7"

services:
node-mysql-timeline:
image: xinjn/timeline-node-mysql # 指定镜像
restart: always # 自动重启
ports: # 端口映射
- 4444:8000
networks: # 网络通信
- app-timeline

react-nginx-node-timeline:
image: xinjn/timeline-react-nginx-node # 指定镜像
restart: always # 自动重启
depends_on:
- node-mysql-timeline
ports: # 端口映射
- 9999:80
networks: # 网络通信
- app-timeline

networks:
app-timeline: # 加入网络,引用顶级networks下条目
driver: bridge
  1. 开启多容器 注意:启动前需要把之前的容器暂停,接口不能冲突!
# 启动所有容器
docker-compose up -d

# 停止所有容器
docker-compose stop

让用户拿到 docker-compose.yml 并执行

URL 重写 nginx

Url 末尾必须跟“/”,否则 window.location.assgin 不识别,可以先在控制台测试

总结

由于没有用到 mysql 数据库,实际上只用到 2 个镜像,timeline/react-nginx-node(远程:xinjn/timeline-react-nginx-node)和 timeline/node-mysql(远程:xinjn/timeline-node-mysql),通过这两个镜像构建容器,访问 location:9999 进行启动预览。

  1. 前端容器化

通过构建 timeline/react-nginx-node(远程:xinjn/timeline-react-nginx-node) 镜像,创建 react-nginx-node 容器,容器会安装 2 个应用( React / Nginx )。

由于 React 项目中引用到非 npm 中的包,所以无法在容器中npm install安装,需要提前构建后文件,使用 dist 文件。

需要使用 network 命令建立容器通信,然后编写 nginx.conf 才能通过 Nginx 代理接口 到 Node 层。

这样当 react 框架中发送请求 Api 时,请求通过 nginx 代理到 node 层,从而进一步操作 mysql 数据库(虽然没有用到)。

  1. Node 容器化

通过构建 timeline/node-mysql(远程:xinjn/timeline-node-mysql)镜像,创建 node-mysql 容器, mysql:5.7(未用到,启动错误):创建 mysql 容器,启动 mysql 数据库 timeline/node-mysql:创建 node 关联 mysql 容器,可以通过 node 操作 mysql 数据库