IdeaWorlds 前端开发笔记(三)
本篇目标:介绍本项目的前端自动化部署。
趁 618 买了台腾讯云的服务器折腾了下,因此先提前写下前端部署的笔记,完整流程:
1. 前端工程
1.1 GitHub Action 流程配置
- 自动部署流程
- 从分支名解析出当前要部署的项目(例:
release/www
-> 部署www
) - 设置 Docker 镜像名:{私有仓库}/{命名空间}/{项目名}
- 获取当前日期、checkout 最新代码、设置 nodejs 环境
- npm 打包要部署的项目,并将打包后的文件移到
./deploy/dist/
- Docker 打包
./deploy/
:{镜像名}:latest、{镜像名}:当前日期 - Docker 登录私有仓库,推送刚打包的两个镜像到仓库
- ssh 登录服务器(注意:该服务器需先手动登录 Docker 私有仓库)
- 创建前端目录:/app/{命名空间}/{项目名}
- 拉取刚推送的镜像:镜像名:latest
- 映射前端目录启动一个临时容器,执行成功后将在前端目录创建三个子目录
- prev (存放上次的文件,即先从 latest/ 移到 prev/ )
- latest (存放最新的文件)
- latest_bak (存放最新的文件)
- 删除镜像
./.github/workflows/deploy.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
name: deploy on: push: branches: [ "release/*" ] workflow_dispatch: env: docker-registry: ccr.ccs.tencentyun.com docker-namespace: ideaworlds remote-workdir: /app jobs: deploy: runs-on: ubuntu-latest steps: - name: Set env.project run: | echo "project=${GITHUB_REF#refs/heads/release/}" >> $GITHUB_ENV - name: Set env.image run: | echo "image=${{ env.docker-registry }}/${{ env.docker-namespace }}/${{ env.project }}" >> $GITHUB_ENV - name: Get Time id: time uses: nanzm/get-time-action@v1.1 with: timeZone: 8 format: 'YYMMDD' - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 18 cache: 'npm' - name: npm build run: | npm ci npm run build:${{ env.project }} mv ./dist/${{ env.project }}/ ./deploy/dist/ - name: docker build run: | cd ./deploy docker build -t ${{ env.image }}:latest . docker tag ${{ env.image }}:latest ${{ env.image }}:${{ steps.time.outputs.time }} - name: Login to Docker Registry uses: docker/login-action@v2 with: registry: ${{ env.docker-registry }} username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_TOKEN }} - name: Push to Docker Registry run: | docker push ${{ env.image }}:latest docker push ${{ env.image }}:${{ steps.time.outputs.time }} - name: Run Docker Image uses: appleboy/ssh-action@master with: host: ${{ secrets.REMOTE_HOST }} username: ${{ secrets.REMOTE_USER }} key: ${{ secrets.REMOTE_KEY }} script_stop: true script: | mkdir -p ${{ env.remote-workdir }}/${{ env.docker-namespace }}/${{ env.project }} docker pull ${{ env.image }}:latest docker run --rm -v ${{ env.remote-workdir }}/${{ env.docker-namespace }}/${{ env.project }}:/app/data ${{ env.image }}:latest docker rmi ${{ env.image }}:latest
- 从分支名解析出当前要部署的项目(例:
1.2 Angular 打包
开启 gzip
1 2
npm install --save-dev gulp-gzip npm install --save-dev gulp
./gulpfile.js1 2 3 4 5 6 7 8 9
// gulpfile.js 与 package.json 同级 let gulp = require('gulp'); let gzip = require('gulp-gzip'); gulp.task('compress', function () { return gulp.src(['./dist/**/*.js', './dist/**/*.css']) .pipe(gzip()) .pipe(gulp.dest('./dist')); });
修改部署包大小限制
Angular 默认打包大小超过 1m 会失败,我们的原部署包刚好超过 1m 一点点,gzip 压缩后不到 200k,因此需要放开这个限制。
./angular.json1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
{ "projects": { "www": { "architect": { "build": { "configurations": { "production": { { "type": "initial", "maximumWarning": "1mb", "maximumError": "2mb" 修改这个 } }, "console": 同上面 }
编写打包脚本
./package.json1 2 3 4 5 6 7 8 9 10
{ "scripts": { "ng": "ng", "start:www": "ng serve --project www --open", "build:www": "ng build --project www && gulp compress", "start:console": "ng serve --project console --open", "build:console": "ng build --project console && gulp compress", "build": "npm run build:www && npm run build:console" } }
1.3 Docker 打包
- Dockerfile./deploy/Dockerfile
1 2 3
FROM alpine:latest COPY . /app ENTRYPOINT ["sh", "/app/docker-entrypoint.sh"]
- Docker 容器内自动执行脚本./deploy/docker-entrypoint.sh
1 2 3 4 5 6 7 8 9 10
#!/bin/sh mkdir -p ./app/data/prev/ mkdir -p ./app/data/latest/ mkdir -p ./app/data/current/ rm -rf ./app/data/current/ mv ./app/dist/ ./app/data/current/ rm -rf ./app/data/prev/ mv ./app/data/latest/ ./app/data/prev/ mv ./app/data/current/ ./app/data/latest/
2. 服务器
2.1 安装 Docker
- 安装文档:Docker 官网 、腾讯云
- 开通容器镜像服务并登录私服
2.2 配置 Nginx
使用docker compose
启动 Nginx 服务
- 创建 Nginx 目录和默认配置
1 2 3 4 5
mkdir -p /data/nginx/conf.d docker run --name tmp-nginx -d nginx:latest docker cp tmp-nginx:/etc/nginx/nginx.conf /data/nginx/nginx.conf docker cp tmp-nginx:/etc/nginx/conf.d/default.conf /data/nginx/conf.d/default.conf docker rm -f tmp-nginx
- 配置前端服务
- 软链接前端目录
1 2 3
mkdir -p /data/nginx/html ln -s /app/ideaworlds/www /data/nginx/html/www.ideaworlds.info ln -s /app/ideaworlds/console /data/nginx/html/console.ideaworlds.info
- 在
./conf.d/
目录下新建 Nginx 配置文件并编辑1
vi /data/nginx/conf.d/ideaworlds.info.conf
/data/nginx/conf.d/ideaworlds.info.conf1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
server { listen 80; listen [::]:80; server_name ideaworlds.info www.ideaworlds.info; location / { root /html/www.ideaworlds.info/latest; try_files $uri $uri/ /index.html?$query_string; } } server { listen 80; listen [::]:80; server_name console.ideaworlds.info; location / { root /html/console.ideaworlds.info/latest; try_files $uri $uri/ /index.html?$query_string; } }
- 软链接前端目录
- 编写 Docker Compose 配置/data/nginx/docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
version: '3.0' services: nginx: restart: always image: nginx:latest container_name: nginx environment: TZ: Asia/Shanghai ports: - 80:80 - 443:443 volumes: - ./nginx.conf:/etc/nginx/nginx.conf - ./conf.d:/etc/nginx/conf.d - ./logs:/var/log/nginx - ./html/www.ideaworlds.info:/html/www.ideaworlds.info - ./html/console.ideaworlds.info:/html/console.ideaworlds.info
使用
nginx:latest
镜像启动一个名为nginx
的容器,并映射服务器的 80 和 443 端口。 - 启动 Nginx 服务
1
docker compose up -d
后续若修改
docker-compose.yml
配置文件,重启服务的命令如下:1 2
docker compose down docker compose up -d
2.3 生成密钥
3. GitHub
进入 远程仓库的设置选项
在Secrets/actions
添加几个仓库的密钥
key | 说明 |
---|---|
DOCKER_USER | Docker 私服用户名 |
DOCKER_TOKEN | Docker 私服用户密码 |
REMOTE_HOST | 远程服务器 ip |
REMOTE_USER | 远程服务器 ssh 用户名 |
REMOTE_KEY | 远程服务器 ssh 私钥 |
4. 总结
以上全部为一次性配置后续无需再修改,前端工程中推送代码到 release/ 开头的分支将触发 GitHub Action 部署流程,自动打包前端代码更新到服务器对应的目录下。