前端项目的CICD流程构建

原文地址

原文链接

前言

之前已经说过后端CICD的部署流程,那么同样的套路,改为前端的环境即可,这里简单列一下各项配置文件以及坑

我们这里采用的是使用yarn/npm build构建后的dist文件夹index.html作为nginx的访问文件,而不是使用yarn serve/npm run serve生成访问接口的方式。不过整体来说如果是直接生成访问接口的话,那么各个文件配置会更类似后端的配置,自己按需调整即可。既然需要构建,那么沿袭我们这边后端CICD的构建原则,build过程自然是由gitlab完成,直接生成带有css/js/html的文件包,然后将文件包传到服务器上

这时候问题来了,需不需要将文件包放在容器内,其实从节约资源的角度来说其实不需要,但是我们又希望在尽可能的节约系统资源的情况下,保证部署流程的统一,这里提供几种解决方案

  1. 和后端部署一样,启动一个最小的容器,将文件包映射到平台服务器上,容器内部执行一个存续命令维持容器运行

    这种的好处是所有前后端的的部署流程都是相同的,统一整齐,强迫症直呼内行,并且一般前端项目不会布很多所以这种资源消耗并不明显。但是问题是即使是最小的容器也会资源消耗,蚊子腿肉也是肉

  2. 在gitlab完成构建后,通过文件包传输将文件传输到服务器指定文件夹

    这种的好处是资源消耗最小,只是看起来不是特别整齐,没有统一的管理/观测通道

  3. 折中方案,启动容器,将文件包映射到服务器上,但是不使用存续命令维持容器运行,退出就退出了

    基本没有资源消耗,部署流程比较统一整齐,但是portainer界面不太好看,前端的容器会始终处于exit的状态,不是特别美观

这里大家自行选择,1,3两种配置基本一样,只有两个地方不同下文会说明。2方案就不展示了,只保留gitlab-ci的部分,然后再ci中使用命令将文件传到自己服务器即可,如果有需要注意权限问题

CICD配置

docker-compose.yml

上半部分没啥好说的,特别需要注意一下我们在这里是使用命名卷去映射容器,而不是使用已有文件夹映射容器参考命名卷和映射已有文件夹的区别。简单来说对于空的宿主机映射卷这种方式会使用容器对于目录预先填充,之后再是相互同步操作。如果是空的已有文件夹,则不会有这个操作,直接将空文件夹覆盖容器已有文件夹,那么就会导致容器对应的映射文件夹为空,这种行为模式参考linux的挂载

version: "3.9"
services:
  application-front:
    build:
      context: ./
      dockerfile: Dockerfile
      args:
        READ_TOKEN: ${READ_TOKEN}
        CI_PROJECT_ID: ${CI_PROJECT_ID}
        CI_JOB_ID: ${CI_JOB_ID}
    pull_policy: build
    hostname: 'application-front'
    container_name: 'application-front'
    #restart on-failure
    restart: always
    volumes:
      - your_new_vol:/usr/src/apps/dist
volumes:
  www.astercasc.com:
    name: your_new_vol

如果是使用方案3,我们需要将重启策略设置为 on-failure,防止容器一直重启

Dockerfile

astercass/alpine-simple:latest 这个镜像是alpine:latest进行增加了curl命令获得的,使用alpine镜像再手动添加curl命令效果相同。中间部分没啥好说的和后端的发布流程相同,都是从gitlab获取制品,再解包

这里有个关键点,我们不能在RUN命令中直接将包解压到容器映射目录,因为之前提到了,无论是哪种卷映射方式,都无法做到在启动时候将容器映射目录覆盖非空的宿主机目录/卷。如果使用正常解压方式,且使用是命名卷映射,首次由于命名卷内容为空,所以会用宿主机填充空的命名卷,所以首次是没问题的。但是在第二次启动的时候,命名卷中已经有数据了,则会将命名卷的数据覆盖到容器内,此时就更新了等于没更新

所以我们不能直接在RUN命令中去将数据写入映射的容器目录,但是我们知道,在容器构建完成之后目录内容会双向同步,故而我们需要将更新文件目录下放到CMD或者ENTRYPOINT中。可以理解为RUN命令是构建态,而最后的CMD和ENTRYPOINT是执行态,既然在构建态无法完成由内而外的文件覆盖,只能在执行态的时候将映射目录覆盖

FROM  astercass/alpine-simple:latest
LABEL author="astercass@qq.com"
WORKDIR /usr/src/apps
ARG READ_TOKEN
ARG CI_PROJECT_ID
ARG CI_JOB_ID
RUN curl --location --output artifacts.zip  \
    --header PRIVATE-TOKEN:$READ_TOKEN  \
    "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/$CI_JOB_ID/artifacts" \
    && unzip -d ./data artifacts.zip
#CMD cp -r ./data/dist ./
CMD cp -r ./data/dist ./ top

如果是使用方案3,则不需要在最后执行top命令,直接让容器处于退出状态即可

gitlab-ci.yml

配置和后端的CI流程类似,这里就不再过多说明了,注意gitlab服务器在国外不需要改源不用画蛇添足,直接展示下代码

image: node:18.14.2-slim
stages:
  - build
  - release
  
#打印版本号和tag信息
before_script:
  - echo ${CI_PROJECT_ID}
  - echo ${CI_JOB_ID}
  #gitlab current variables
  - echo ${PORTAINER_APPLICATION_FRONT_WEB_HOOK}

#构建jar包
build:
  stage: build
  script:
    - npm install -g yarn --force
    - npm install -g @vue/cli
    - yarn install
    - yarn build
    - export PARAM_VAR="CI_PROJECT_ID=${CI_PROJECT_ID}&CI_JOB_ID=${CI_JOB_ID}"
    - echo "PARAM_VAR=${PARAM_VAR}" >> build.env
    - cat build.env
  except:
    - tags
  allow_failure: false
  artifacts:
    reports:
      dotenv: build.env
    paths:
      - dist/
    expire_in: 1 week

#deploy to
release:
  image: astercass/alpine-simple:latest
  stage: release
  script:
    - echo ${PORTAINER_APPLICATION_FRONT_WEB_HOOK}?${PARAM_VAR}
    - curl -X POST "${PORTAINER_APPLICATION_FRONT_WEB_HOOK}?${PARAM_VAR}"
  dependencies:
    - build

nginx配置

由于和前端相关这里简单说下nginx配置,其他的关于https证书申请,子域名申请等,一方面和本文无关另一方面运营商流程经常变动这里就不做说明了

cd /etc/nginx
#首先备份
cp nginx.conf nginx.conf.bak

简单展示下conf的配置,这里展示较为简单的,复杂的配置自行访问官网

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

#使用用户,需要和systemctl的启动用户保持一致 这里不建议使用root 我这里简便起见了
user root;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
  

#将http请求重定向到https 将无二级域名的访问重定向到www的二级域名
    server {
        listen       	443 ssl http2; 
        listen      	 [::]:443 ssl http2;
        server_name  	astercasc.com;
	rewrite		^/(.*)$ https://www.astercasc.com/$1 permanent;
    }
   server {
	server_name	test.astercasc.com;
	rewrite		^/(.*)$ https://test.astercasc.com/$1 permanent;
    }
    server {
	server_name	astercasc.com;
	rewrite		^/(.*)$ https://www.astercasc.com/$1 permanent;
    }
    server {
	server_name	www.astercasc.com;
	rewrite		^/(.*)$ https://www.astercasc.com/$1 permanent;
    }
    server {
	server_name	api.astercasc.com;
	rewrite		^/(.*)$ https://service.astercasc.com/$1 permanent;
    }
    
    
# Settings for a TLS enabled server.
    
    server {
        listen       443 ssl http2 default_server; 
        listen       [::]:443 ssl http2 default_server;
        server_name  www.astercasc.com;
        root         /your_index_site;

        ssl_certificate "/your_domin_crt_site/www.your_domin_bundle.crt";
        ssl_certificate_key "/your_domin_crt_site/www.your_domin.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers PROFILE=SYSTEM;
        ssl_prefer_server_ciphers on;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
    
    #这里根据需要直接打配置的docker映射卷上
    server {
        listen       443 ssl http2;
        listen       [::]:443 ssl http2;
        server_name  test.astercasc.com;
        root         /var/lib/docker/volumes/your_new_vol/_data;

        ssl_certificate "/your_domin_crt_site/test.your_domin_bundle.crt";
        ssl_certificate_key "/your_domin_crt_site/test.your_domin.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers PROFILE=SYSTEM;
        ssl_prefer_server_ciphers on;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }
    }

#这里是直接打到后端接口上,如果使用的yarn serve或者npm run serve的方式则也使用这种配置方式
    server {
    	listen       443 ssl http2;
	listen       [::]:443 ssl http2;
	server_name  api.astercasc.com;
        ssl_certificate "/your_domin_crt_site/api.your_domin_bundle.crt";
        ssl_certificate_key "/your_domin_crt_site/api.your_domin.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers PROFILE=SYSTEM;
        ssl_prefer_server_ciphers on;
	location / {
		proxy_pass  http://localhost:8000;
	}
    }
   

}

原文地址

原文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Jenkins是一种流行的持续集成和交付工具,可以帮助开发团队将软件开发的各个阶段自动化。 Jenkins的CICD流程是指在软件开发过程中的“持续集成-持续交付”的循环。它由以下几个主要步骤组成: 1. 代码管理:开发人员将代码上传到版本控制系统(如Git)中。这些代码可以包括新功能、修复问题或其他更改。 2. 构建:当代码被提交到版本控制系统后,Jenkins会监视这些代码的更改。一旦检测到新的提交,Jenkins会触发一个构建任务。构建任务的目的是将源代码编译成可执行的软件。 3. 自动化测试:在构建过程中,Jenkins会执行一系列自动化测试,包括单元测试、集成测试和系统测试等。这些测试用例旨在验证代码的质量和功能性。 4. 静态代码分析:Jenkins还可以执行静态代码分析,例如检查代码的可读性、复杂性和一致性等方面。这有助于发现潜在的问题和改进代码质量。 5. 部署:当构建和测试过程顺利完成后,Jenkins将自动将软件部署到目标环境中,例如测试服务器或生产环境。这确保了一个稳定和可用的软件版本可以及时地交付给用户。 6. 监控与反馈:在部署完成后,Jenkins还可以监控和记录应用程序的运行情况。开发人员可以通过Jenkins的仪表板查看项目构建和部署状态。如果出现问题,Jenkins会发送警报通知开发人员。 通过Jenkins的CICD流程,开发团队可以实现高效的软件交付和持续改进。它可以减少手动操作的工作量,提高软件质量,并减少发布新版本的风险。同时,它也促进了团队成员之间的协作和沟通,提高了开发流程的可见性和透明度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值