一看一个不吱声,前端 Docker + GitLab Runner 自动化部署

2,435 阅读4分钟

前言

作为前端开发,想必自动化部署大家也经常提到,是现代开发流程中不可或缺的一部分,它可以显著提高开发效率和代码质量。但是很多小伙伴进入公司时,公司已经有一套完整的流程了,所以对具体流程不太清楚,文本将从 0 到 1 介绍如何搭建一套个人 CICD 自动化部署流程,记录遇到的坑。希望大家多多支持!

手动部署

1. 创建项目

pnpm create vite my-cicd-demo --template react
cd my-cicd-demo
pnpm install
pnpm run build

2. 创建 nginx.conf 文件

# nginx 的默认的配置内容,可以在这里修改 nginx 配置
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

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

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

3. 创建 Dockerfile 文件

FROM node:20-slim as build

# 设置工作目录为`/app`,后续的`COPY`和`RUN`命令都会在这个目录下执行。
WORKDIR /app
# 将当前目录的文件复制到镜像的 /app 目录下
COPY . /app

RUN npm install -g pnpm
RUN pnpm install && pnpm run build

FROM nginx:latest

# 从构建阶段复制构建结构到 Nginx 的默认静态文件目录 /usr/share/nginx/html
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

4. 创建镜像

docker 自行下载即可,官网地址

# -t 指定 image 名称
# 默认标签 latest,可以使用冒号指定,如:my-cicd-demo-image:0.0.1
# 最后的 . 别忘了,表示 Dockerfile 所在当前路径
docker image build -t my-cicd-demo-image .

5. 创建容器

# -d,容器在后台运行
# -p 将宿主机的 8088 端口映射到容器的 80 端口。
# --name 容器名称
docker container run -d -p 8088:80 --name my-cicd-demo-container my-cicd-demo-image

接下来在就可访问页面了

image.png

踩坑

因为上面的项目是新创建的,所以走下来没有问题,但是我们正常的项目本地都是有 node_modules 这个文件的,然后在创建镜像的时候可能会遇到如下情况。

image.png

这时候需要新建 .dockerignore 文件将不必要的文件排除,接下来就可以愉快的创建了。

node_modules
.git
.gitignore

自动化部署

上面的方法每次有新的东西需要自己去手动操作,都不能安心摸鱼。

因此我们可以结合 Docker + Nginx + GitLab + GitLab Runner 来完成自动化部署。

GitLab 部署

1. 拉取镜像

docker pull gitlab/gitlab-ce

2. 启动容器

# hostname 指定主机的 IP,用于访问
# publish 端口映射,分别将容器的三个端口映射到主机对应的三个端口
# volume 将宿主机上的目录挂载到容器对应的目录上,用于存储 GitLab 的文件
docker run \
    --hostname 10.0.1.223 \
    --publish 443:443 --publish 80:80 --publish 22:22 \
    --name gitlab \
    --restart always \
    --volume $HOME/docker-data/gitlab/config:/etc/gitlab \
    --volume $HOME/docker-data/gitlab/logs:/var/log/gitlab \
    --volume $HOME/docker-data/gitlab/data:/var/opt/gitlab \
    -v /etc/localtime:/etc/localtime \
    -d \
    gitlab/gitlab-ce:latest

这里需要注意 如果配置的时候对外端口不是 80:80,那么就会出问题,可能会遇到推送不成功,runnew 无法连接的情况,因为容器端口和外部端口不一致了。

这时候可以通过配置文件修改。

# 在 gitlab.rb 文件中添加 external_url 'http://你的IP:你的端口',如:'http://127.0.0.1:8088'
docker exec -it gitlab bash
vim /etc/gitlab/gitlab.rb

参考:官方初始启动配置

等待启动完成访问 hostname 对应 IP 将可以访问到界面

image.png

初始用户为 root

初始密码可以通过以下方式获取

cat $HOME/docker-data/gitlab/config/initial_root_password
# 进入容器找到初始文件
docker exec -it gitlab bash  
cat /etc/gitlab/initial_root_password

后面的创建项目,推送项目,本文不再赘述。

那么如何才能在每次推送的时候让他自动更新呢?那就是 GitLab Runner。

部署 GitLab Runner

1. 拉取镜像

docker pull gitlab/gitlab-runner:latest

2. 创建实例

docker run -d --name gitlab-runner-test \
    --restart always \
    -v $HOME/_docker/runner/srv/gitlab-runner/config:/etc/gitlab-runner \
    # 注意!这里的 docker.sock 不能使用 $HOME 路径。
    -v /var/run/docker.sock:/var/run/docker.sock \
    gitlab/gitlab-runner:latest

3. 注册 runner

在 GitLab 项目下的 Settings / CD/CD 目录下创建 runner

image.png

image.png

docker exec -it gitlab-runner bash
gitlab-runner register
# 根据提示输入信息
# url
http://10.0.1.223
# token (上图中的 token)
glrt-*****
# runner name
a runner
# executor
docker
# docker image
alpine:latest

image.png

可以看到注册成功

image.png

官方教程:注册 runner

.gitlab-ci.yml

那怎么每次触发执行呢?

在当前目录下添加.gitlab-ci.yml 文件,官方文档,每次提交都会触发 CI 流水线( pipeline )的执行,别忘了文件前面的.一开始忘记写上了,一直没触发,一度以为是哪里配错了。

第一种方法,按照手动部署的方式
# .gitlab-ci.yml
stages:
  - deploy
  
deploy:
  image: docker:stable
  stage: deploy
  script:
# 下面这几步相当于是我们一开始手动部署的内容,现在让 GitLab Runner 帮我执行。 
    - docker build -t my-cicd-demo-image .
    - if [ $(docker ps -aq --filter name=my-cicd-demo-container) ]; then docker rm -f my-cicd-demo-container;fi
    - docker run -d -p 8088:80 --name my-cicd-demo-container my-cicd-demo-image

提交代码,摸会儿鱼,访问 http://localhost:8088/ ,可以正常访问,搞定。

image.png

尝试下修改文件,走一遍提交代码流程,然后等待 pipeline 执行完成,刷新页面,可以显示更新后的内容,自动化部署完成。

image.png

第二种方法

当然我们也可以把代码打包的逻辑放到.gitlab-ci.yml 文件中

# .gitlab-ci.yml
stages:
  - build
  - deploy

build:
  stage: build
  image: node:20-slim
  script:
    - npm install -g pnpm
    - pnpm install
    - pnpm run build
  # 把本次 stage 打包后的 dist 文件移到下一个 stage,让下一个 stage 可以直接使用
  artifacts:
    paths:
      - dist

deploy:
  image: docker:stable
  stage: deploy
  script:
    - docker build -t my-cicd-demo-image .
    - if [ $(docker ps -aq --filter name=my-cicd-demo-container) ]; then docker rm -f my-cicd-demo-container;fi
    - docker run -d -p 8088:80 --name my-cicd-demo-container my-cicd-demo-image

# Dockerfile
FROM nginx:latest

COPY dist /usr/share/nginx/html

COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

踩坑

1.

执行 CI 的时候可能会遇到以下情况

image.png

# 在创建实例的时候这个配置没配对,这个配置很关键,它允许容器内的进程与宿主机的Docker守护进程通信。
-v /var/run/docker.sock:/var/run/docker.sock \
2.

image.png

找到目录 docker-data/runner/srv/gitlab-runner/config 下的 config.tomal 修改如下代码,重试 deploy stage

# 将 volumes = ["/cache"] 修改为下面内容
volumes = ["/var/run/docker.sock:/var/run/docker.sock","/cache"]

总结

面试的时候:熟练掌握前端自动化部署。

工作的时候:我不会啊,找运维吧。