一、背景
今天早上收到项目经理的一个任务,让我编写angular+ng-zorro-antd的一个前端项目的部署脚本。说实话,angular我也不是很会,就是来到项目组接手了一下。现在开发新的项目,项目搭建和部署脚本全归我了,臣妾做不到好不好!没办法,谁叫咋们是吃这碗饭的。
二、思路整理
我记得之前有配置过nginx的,它有正向代理,反向代理和动静分离等几大功能,于是乎干么不适用动静分离呢?
- 在docker中拉取node:12-alpine镜像
- npm i拉取依赖
- npm run build打包
- 移除nginx本身自带的/usr/share/nginx/html/*文件
- 将打包好的文件复制到这个文件夹
- 执行nginx
- 镜像打包完成
- 运行镜像,映射端口
三、代码实践
1. 编写nginx配置文件nginx.conf
server { listen 80; sendfile on; default_type application/octet-stream; gzip on; gzip_http_version 1.1; gzip_disable "MSIE [1-6]\."; gzip_min_length 1100; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_comp_level 9; root /usr/share/nginx/html; location / { try_files $uri $uri/ /index.html =404; } }
2. 编写Dockerfile构建镜像
### STAGE 1: Build ### FROM node:12-alpine AS builder # build-time variables # prod|release its value will be come from outside ARG env=prod WORKDIR /yinghe COPY . . RUN npm config set registry https://registry.npm.taobao.org RUN npm i RUN npm run build:$env ### STAGE 2: Setup ### FROM nginx:stable-alpine ## Copy our default nginx config COPY nginx.conf /etc/nginx/conf.d/default.conf ## Remove default nginx website RUN rm -rf /usr/share/nginx/html/* ## From ‘builder’ stage copy over the artifacts in dist folder to default nginx public folder COPY --from=builder /yinghe/dist/yinghe-frontend /usr/share/nginx/html CMD ["nginx", "-g", "daemon off;"]
3. 编写镜像和容器构建脚本deploy_admin
if [ $# -eq 0 ] then echo "Missing environment target" echo "FORMAT: ./deploy_admin ENV(dev|release|prod|staging|simulate)" exit 0 else docker build --no-cache --build-arg env=$2 -t yinghe-frontend:$2 . docker stop yinghe-frontend docker rm yinghe-frontend docker run -d --name yinghe-frontend -p 80:$1 yinghe-frontend:$2 fi
4. 不同环境配置文件编写
5. 在package.json中添加构建scripts
添加不同环境的构建命令,指向不同的配置文件!方便对应不同环境的后端服务器。
6. 在angular.json中添加不同环境的配置文件指向
这里4和5应该对换一下位置的,奈何太晚了,有点懒得CV了。
7. 编写linux脚本拉取代码和执行部署脚本my-ssh-script.sh
echo "start deployment" $1 "..." rm -rf yinghe-frontend git clone -b $1 --single-branch https://用户别名:密码@gitee.com/yinghe-frontend.git cd yinghe-frontend chmod 777 deploy_admin ./deploy_admin $2 $3
四、主角docker安装
curl -fsSL https://get.docker.com/ | sh systemctl restart docker systemctl enable docker
作为本场的主角,必须着重讲一下,有些版本不支持FROM node:12-alpine AS builder,需要更新docker版本,更新用以上语句,怎么卸载就不写了,自己去查。不然会出现如下错误:
Error parsing reference: "node:12-alpine AS binarybuilder" is not a valid repository/tag: inval
五、服务器上部署angular服务
- 创建yinghe文件夹,授权,执行脚本
$ mkdir yinghe $ cd yinghe $ vim my-ssh-script.sh #里面添加刚才3.7里面的linux命令 $ chmod 777 my-ssh-script.sh $ ./my-ssh-script.sh master 80 dev # 第一个参数是远程分支名即master,第二个参数是端口即80,第三个参数是环境即dev
- 执行日志展示
start deployment master ... Cloning into 'yinghe-frontend'... remote: Enumerating objects: 99, done. remote: Counting objects: 100% (99/99), done. remote: Compressing objects: 100% (92/92), done. remote: Total 99 (delta 23), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (99/99), done. invalid argument "yinghe-frontend:" for "-t, --tag" flag: invalid reference format See 'docker build --help'. Error response from daemon: No such container: yinghe-frontend Error: No such container: yinghe-frontend docker: Invalid containerPort: dev. See 'docker run --help'. root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker run --name yinghe-frontend -p 80:80 -d nginx:stable-alpine 0a9e764c7c8be34e7dbd6f3e7c152ff3f516f9c8ddd6c44c5f86ecc41dfd5f17 root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a9e764c7c8b nginx:stable-alpine "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp yinghe-frontend root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# ./my-ssh-script.sh master 80 dev start deployment master ... Cloning into 'yinghe-frontend'... remote: Enumerating objects: 99, done. remote: Counting objects: 100% (99/99), done. remote: Compressing objects: 100% (92/92), done. remote: Total 99 (delta 23), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (99/99), done. invalid argument "yinghe-frontend:" for "-t, --tag" flag: invalid reference format See 'docker build --help'. yinghe-frontend yinghe-frontend docker: Invalid containerPort: dev. See 'docker run --help'. root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker run --name yinghe-frontend -p 80:80 -d nginx:stable-alpine 00dff7994ce8072b5a192cedf106e884412ca9e7fd9f1b92d23c0b767d7c85e2 root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00dff7994ce8 nginx:stable-alpine "/docker-entrypoint.…" 14 seconds ago Up 13 seconds 0.0.0.0:80->80/tcp yinghe-frontend root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker commit 00dff7994ce8 yinghe-frontend:dev sha256:3991b7159075a6ce158369acd96b4f81027ac4f6e6a2ec2814ade3d057c82401 root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00dff7994ce8 nginx:stable-alpine "/docker-entrypoint.…" 55 seconds ago Up 54 seconds 0.0.0.0:80->80/tcp yinghe-frontend root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00dff7994ce8 nginx:stable-alpine "/docker-entrypoint.…" About a minute ago Up 58 seconds 0.0.0.0:80->80/tcp yinghe-frontend root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker images REPOSITORY TAG IMAGE ID CREATED SIZE yinghe-frontend dev 3991b7159075 13 seconds ago 21.9MB nginx stable-alpine f2343e2e2507 5 weeks ago 21.9MB root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# ./my-ssh-script.sh master 80 dev start deployment master ... Cloning into 'yinghe-frontend'... remote: Enumerating objects: 99, done. remote: Counting objects: 100% (99/99), done. remote: Compressing objects: 100% (92/92), done. remote: Total 99 (delta 23), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (99/99), done. invalid argument "yinghe-frontend:" for "-t, --tag" flag: invalid reference format See 'docker build --help'. yinghe-frontend yinghe-frontend docker: Invalid containerPort: dev. See 'docker run --help'. root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# ./my-ssh-script.sh master 80 dev start deployment master ... Cloning into 'yinghe-frontend'... remote: Enumerating objects: 99, done. remote: Counting objects: 100% (99/99), done. remote: Compressing objects: 100% (92/92), done. remote: Total 99 (delta 23), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (99/99), done. invalid argument "yinghe-frontend:" for "-t, --tag" flag: invalid reference format See 'docker build --help'. Error response from daemon: No such container: yinghe-frontend Error: No such container: yinghe-frontend docker: Invalid containerPort: dev. See 'docker run --help'. root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# ./my-ssh-script.sh master 80 dev start deployment master ... Cloning into 'yinghe-frontend'... remote: Enumerating objects: 102, done. remote: Counting objects: 100% (102/102), done. remote: Compressing objects: 100% (95/95), done. remote: Total 102 (delta 25), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (102/102), 163.66 KiB | 877.00 KiB/s, done. Resolving deltas: 100% (25/25), done. Sending build context to Docker daemon 885.8kB Step 1/12 : FROM node:12-alpine AS builder 12-alpine: Pulling from library/node 0a6724ff3fcd: Already exists 5fd2bdfdbf4b: Pull complete 80b224d472a8: Pull complete e21405c347ae: Pull complete Digest: sha256:41ae2b38e38e387517c59ca50498eac0537a2ff2316552c3df3b406d31414d78 Status: Downloaded newer image for node:12-alpine ---> 0206ff8a5f9e Step 2/12 : ARG env=prod ---> Running in 970decac1eb8 Removing intermediate container 970decac1eb8 ---> 398d6df8583d Step 3/12 : WORKDIR /yinghe ---> Running in b23562039c6a Removing intermediate container b23562039c6a ---> 1d6ca484cf4b Step 4/12 : COPY . . ---> 2463139a973b Step 5/12 : RUN npm config set registry https://registry.npm.taobao.org ---> Running in 353fd70991b3 Removing intermediate container 353fd70991b3 ---> 18e29fd5b322 Step 6/12 : RUN npm i ---> Running in 2ea255e1bd0c > core-js@3.6.4 postinstall /yinghe/node_modules/@angular-devkit/build-angular/node_modules/core-js > node -e "try{require('./postinstall')}catch(e){}" Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library! The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: > https://opencollective.com/core-js > https://www.patreon.com/zloirock Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -) > core-js@2.6.12 postinstall /yinghe/node_modules/core-js > node -e "try{require('./postinstall')}catch(e){}" Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library! The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: > https://opencollective.com/core-js > https://www.patreon.com/zloirock Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -) > @angular/cli@11.0.7 postinstall /yinghe/node_modules/@angular/cli > node ./bin/postinstall/script.js npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.1 (node_modules/@angular/compiler-cli/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.1: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.1 (node_modules/watchpack/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.1: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/rollup/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.1 (node_modules/ng-packagr/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.1: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) added 1544 packages from 1093 contributors in 27.776s 82 packages are looking for funding run `npm fund` for details Removing intermediate container 2ea255e1bd0c ---> ea60964e889d Step 7/12 : RUN npm run build:$env ---> Running in 1525734c5875 > yinghe-frontend@0.0.0 build:dev /yinghe > ng build --configuration=dev Compiling @angular/animations : es2015 as esm2015 Compiling @angular/core : es2015 as esm2015 Compiling ng-zorro-antd/core/environments : es2015 as esm2015 Compiling @angular/cdk/keycodes : es2015 as esm2015 Compiling ng-zorro-antd/core/animation : es2015 as esm2015 Compiling ng-zorro-antd/core/color : es2015 as esm2015 Compiling @angular/common : es2015 as esm2015 Compiling ng-zorro-antd/core/types : es2015 as esm2015 Compiling @angular/animations/browser : es2015 as esm2015 Compiling ng-zorro-antd/core/logger : es2015 as esm2015 Compiling @angular/cdk/platform : es2015 as esm2015 Compiling @angular/cdk/bidi : es2015 as esm2015 Compiling ng-zorro-antd/core/util : es2015 as esm2015 Compiling @angular/platform-browser : es2015 as esm2015 Compiling @angular/common/http : es2015 as esm2015 Compiling ng-zorro-antd/core/polyfill : es2015 as esm2015 Compiling @angular/cdk/layout : es2015 as esm2015 Compiling ng-zorro-antd/core/outlet : es2015 as esm2015 Compiling @angular/platform-browser/animations : es2015 as esm2015 Compiling ng-zorro-antd/core/services : es2015 as esm2015 Compiling @ant-design/icons-angular : es2015 as esm2015 Compiling @angular/cdk/collections : es2015 as esm2015 Compiling @angular/cdk/portal : es2015 as esm2015 Compiling @angular/cdk/scrolling : es2015 as esm2015 Compiling ng-zorro-antd/core/config : es2015 as esm2015 Compiling @ant-design/icons-angular/icons : es2015 as esm2015 Compiling ng-zorro-antd/core/no-animation : es2015 as esm2015 Compiling @angular/cdk/overlay : es2015 as esm2015 Compiling @angular/forms : es2015 as esm2015 Compiling ng-zorro-antd/core/overlay : es2015 as esm2015 Compiling ng-zorro-antd/icon : es2015 as esm2015 Compiling ng-zorro-antd/core/time : es2015 as esm2015 Compiling @angular/cdk/observers : es2015 as esm2015 Compiling ng-zorro-antd/core/transition-patch : es2015 as esm2015 Compiling @angular/cdk/a11y : es2015 as esm2015 Compiling ng-zorro-antd/core/wave : es2015 as esm2015 Compiling ng-zorro-antd/i18n : es2015 as esm2015 Compiling ng-zorro-antd/button : es2015 as esm2015 Compiling @angular/router : es2015 as esm2015 Compiling ng-zorro-antd/core/resize-observers : es2015 as esm2015 Compiling ng-zorro-antd/tooltip : es2015 as esm2015 Compiling ng-zorro-antd/empty : es2015 as esm2015 Compiling ng-zorro-antd/menu : es2015 as esm2015 Compiling ng-zorro-antd/pipes : es2015 as esm2015 Compiling ng-zorro-antd/checkbox : es2015 as esm2015 Compiling ng-zorro-antd/select : es2015 as esm2015 Compiling ng-zorro-antd/dropdown : es2015 as esm2015 Compiling ng-zorro-antd/radio : es2015 as esm2015 Compiling ng-zorro-antd/spin : es2015 as esm2015 Compiling ng-zorro-antd/time-picker : es2015 as esm2015 Compiling ng-zorro-antd/grid : es2015 as esm2015 Compiling ng-zorro-antd/core/highlight : es2015 as esm2015 Compiling ng-zorro-antd/input : es2015 as esm2015 Compiling ng-zorro-antd/pagination : es2015 as esm2015 Compiling ng-zorro-antd/core/pipe : es2015 as esm2015 Compiling @angular/platform-browser-dynamic : es2015 as esm2015 Compiling ng-zorro-antd/modal : es2015 as esm2015 Compiling ng-zorro-antd/tabs : es2015 as esm2015 Compiling ng-zorro-antd/table : es2015 as esm2015 Compiling ng-zorro-antd/date-picker : es2015 as esm2015 Compiling ng-zorro-antd/form : es2015 as esm2015 Compiling ng-zorro-antd/divider : es2015 as esm2015 Compiling ng-zorro-antd/layout : es2015 as esm2015 Compiling ng-zorro-antd/cascader : es2015 as esm2015 Compiling ng-zorro-antd/switch : es2015 as esm2015 Compiling ng-zorro-antd/popconfirm : es2015 as esm2015 Compiling ng-zorro-antd/page-header : es2015 as esm2015 Compiling ng-zorro-antd/skeleton : es2015 as esm2015 Compiling ng-zorro-antd/progress : es2015 as esm2015 Compiling ng-zorro-antd/collapse : es2015 as esm2015 Compiling ng-zorro-antd/tag : es2015 as esm2015 Compiling ng-zorro-antd/result : es2015 as esm2015 Compiling ng-zorro-antd/space : es2015 as esm2015 Compiling ng-zorro-antd/alert : es2015 as esm2015 Compiling ng-zorro-antd/statistic : es2015 as esm2015 Compiling ng-zorro-antd/breadcrumb : es2015 as esm2015 chunk {} runtime.9fb644ab68599d00176c.js (runtime) 2.23 kB [entry] [rendered] chunk {1} main.006e2e0096b60be5d8ae.js (main) 751 kB [initial] [rendered] chunk {2} polyfills.7aa99d0d2d925cfabce1.js (polyfills) 44 kB [initial] [rendered] chunk {3} polyfills-es5.3c2f87ef4cba455906e0.js (polyfills-es5) 127 kB [initial] [rendered] chunk {4} styles.7f7c35f1bc66195ddfd2.css (styles) 676 kB [initial] [rendered] chunk {5} 5.a87c4523ab86b1c2ce57.js () 58.9 kB [rendered] Date: 2021-01-25T13:05:59.082Z - Hash: 762297bdde32f3cf1aa6 - Time: 69919ms Removing intermediate container 1525734c5875 ---> 14b842766787 Step 8/12 : FROM nginx:stable-alpine ---> f2343e2e2507 Step 9/12 : COPY nginx.conf /etc/nginx/conf.d/default.conf ---> d440ea90fe9e Step 10/12 : RUN rm -rf /usr/share/nginx/html/* ---> Running in 07fa1bb4c90c Removing intermediate container 07fa1bb4c90c ---> 967a2883eaf8 Step 11/12 : COPY --from=builder /yinghe/dist/yinghe-frontend /usr/share/nginx/html ---> fdffaae10f7f Step 12/12 : CMD ["nginx", "-g", "daemon off;"] ---> Running in 8c4caa8629b4 Removing intermediate container 8c4caa8629b4 ---> d8da48b08a1b Successfully built d8da48b08a1b Successfully tagged yinghe-frontend:dev
- docker 容器和镜像查看
root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7244459f21cd yinghe-frontend:dev "/docker-entrypoint.…" 4 hours ago Up 4 hours 0.0.0.0:80->80/tcp yinghe-frontend root@iZbp1g1qpfdlqea4avz2sfZ:~/yinghe# docker images REPOSITORY TAG IMAGE ID CREATED SIZE yinghe-frontend dev d8da48b08a1b 4 hours ago 24.8MB node 12-alpine 0206ff8a5f9e 2 weeks ago 88.9MB nginx stable-alpine f2343e2e2507 5 weeks ago 21.9MB
- 页面访问
- 至此部署成功,欢迎采纳!!!