前言
作为前端开发,想必自动化部署大家也经常提到,是现代开发流程中不可或缺的一部分,它可以显著提高开发效率和代码质量。但是很多小伙伴进入公司时,公司已经有一套完整的流程了,所以对具体流程不太清楚,文本将从 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
接下来在就可访问页面了
踩坑
因为上面的项目是新创建的,所以走下来没有问题,但是我们正常的项目本地都是有 node_modules 这个文件的,然后在创建镜像的时候可能会遇到如下情况。
这时候需要新建 .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 将可以访问到界面
初始用户为 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
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
可以看到注册成功
官方教程:注册 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/ ,可以正常访问,搞定。
尝试下修改文件,走一遍提交代码流程,然后等待 pipeline 执行完成,刷新页面,可以显示更新后的内容,自动化部署完成。
第二种方法
当然我们也可以把代码打包的逻辑放到.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 的时候可能会遇到以下情况
# 在创建实例的时候这个配置没配对,这个配置很关键,它允许容器内的进程与宿主机的Docker守护进程通信。
-v /var/run/docker.sock:/var/run/docker.sock \
2.
找到目录 docker-data/runner/srv/gitlab-runner/config 下的 config.tomal 修改如下代码,重试 deploy stage
# 将 volumes = ["/cache"] 修改为下面内容
volumes = ["/var/run/docker.sock:/var/run/docker.sock","/cache"]
总结
面试的时候:熟练掌握前端自动化部署。
工作的时候:我不会啊,找运维吧。