Gitlab+docker 代码自动化部署
本文涉及到的一些小知识
- docker
- gitlab
- gitlab-runner
- 一点点的linux
- 一点点的nginx
- 或者还需要一点docker-compose
- 这样的部署方式适用于前后端,不限于本文涉及的部署项目。
- 本文内容比较干,建议使用GPT结合食用
多看一眼就会爆炸,再靠近一点就会被融化
披金成王
每次部署都很繁琐
由于我自己采用的部署方式是docker镜像,每次都需要重新构建docker镜像,这一步往往都是手动操作
之前的构建方式
- 推送代码到gitlab
- 进入服务器
- 拉取最新代码
- 安装依赖
- 构建项目
- 根据当前项目的Dockerfile构建docker镜像
- 利用
docker-compose
执行项目的Dcokerfile文件 - 需要先使用
docker-compose up
执行项目,看看是否有报错,有报错的话先溯源 - 如果没有报错,使用
docker-compose up -d
后台运行项目。 - 需要查看对应项目的logs,利用
docker ps -a
找到你项目的id,并使用docker logs -f xxxxid
- docker 根据文件名查询容器
docker ps -q -f name=container-name
更新之后的部署方式
!!!! 推送代码,结束了~
所有流程都让流水线来帮你完成~
so,how to do it?
前置工作必须得做好哦,本文涉及到较多
docker-compose
创建应用,可以先了解一下哦~
Docker Compose | 菜鸟教程 (runoob.com)
你需要有一个代码管理工具(Gitlab)
建议直接用
docker-compose
创建,很方便。不需要后期修改容器内部的配置文件。
version: '2'
services:
gitlab:
image: 'twang2218/gitlab-ce-zh:11.1.4'
container_name: "gitlab"
restart: unless-stopped
privileged: true
hostname: 'gitlab'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://www.lvzy.xyz:9527'
gitlab_rails['gitlab_ssh_host'] = 'http://www.lvzy.xyz'
gitlab_rails['gitlab_shell_ssh_port'] = xxxx
gitlab_rails['time_zone'] = 'Asia/Shanghai'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "xxxxxxxx@qq.com"
gitlab_rails['smtp_password'] = "xxxxxxx"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'gitlab邮件提醒'
gitlab_rails['gitlab_shell_ssh_port'] = 22
gitlab_rails['gitlab_replay_to'] = "xxxxxxx@qq.com"
# 端口映射,容器内部的端口映射到宿主机。比如项目启动起来,容器内部访问为localhost:9527,映射就是->服务器ip:9527
ports:
- '9527:9527'
- '9430:443'
- '9922:22'
volumes:
# 映射文件夹,就算删除容器,你自己的项目还是会在。重新建立依然可以保留~
- /var/apps/gitlab/config:/etc/gitlab
- /var/apps/gitlab/data:/var/opt/gitlab
- /var/apps/gitlab/logs:/var/log/gitlab
#所以,此处的/vra/apps/gitlab/xxx路径,其实是你宿主机的路径,项目运行生成的文件也会在宿主机中得到持久化。创建的时候你也的得创建对应的目录出来
完成以上步骤之后,你需要访问你的gitlab,设置初始密码~
创建一个属于demo项目,作为测试构建的应用
我这里使用的是一个vue3+vite的项目
创建gitlab runner
我大部分创建容器都是利用docker-compose创建,也可以改造为docker命令自行创建~以下是一个基础gitlab runner构建的yml文件。当然,在此之前你还需要创建一个/config/config.toml 的文件路径,来保证runner的正确启动。
version: '3'
services:
gitlab-runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: always
volumes:
# 这两步骤是为了让容器内的gitlab-runner可以访问到docker
- /var/run/docker.sock:/var/run/docker.sock
- /bin/docker:/bin/dcoker
# 将当前目录的config文件,映射到容器的/etc/gitlab-runner目录
- ./config:/etc/gitlab-runner
environment:
# 也是指定docker
RUNNER_EXECUTOR: "docker"
config.toml文件的内容
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
当你以上工作都已经完成之后,就可以正式开始了
docker ps -q -f name="gitlab-runner"
# 237fc2c3a09a
# 先看看gitlab-runner是否跑起来了,输出正确的容器id 就是跑起来了
此时需要你先准备一个东西,gitlab的
token
,具体位置是到你的项目下,找到设置,设置中的cicd
,选择runner
,会有一个token
红框部分需要记住~
#开始把runner,链接到gitlab
docker exec -it gitlab-runner gitlab-runner register \
--non-interactive \
--url "https://gitlab.example.com" \
--registration-token "TOKEN" \
--executor "docker" \
--description "My Docker Runner" \
--docker-image "docker:19.03.12" \
--tag-list "docker,linux,xenial" \
--run-untagged="true" \
--locked="false" \
--access-level="not_protected"
# --url:指定你的 GitLab 服务器地址。
# --registration-token:刚刚获取的 GitLab Runner 注册 Token。
# --executor:指定 GitLab Runner 服务器的执行器,这里指定为 Docker。
# --description:Runner 的描述信息,可以自定义。
# --docker-image:指定容器运行时使用的 Docker 镜像版本。
# --tag-list:为 Runner 打标签,例如 "docker"、 "linux" 和 "xenial"。
# --run-untagged:允许
# 笔者是直接使用 docker exec -it gitlab-runner gitlab-runner register,每一步跟着敲的,没使用一键命令。
完成以上操作后,去查看
runner
的配置文件。是否有你注册的runner
,并且还需要查看logs
,看看是否报错,如果有报错,仔细检查,并重新操作。这个是我已经配置完成后的log
,大概这样子.
如果没有报错,那么进入你的项目,查看
runner
,如果成功了,会有一条记录,并且是active
状态。
到这一步,基本完成了大部分了
拉取你的项目,做一些项目里的配置~
Dockerfile
是必须的
Dockerfile是用来给你的项目打包镜像使用,在执行镜像的时候具体要做些什么。
# 设置 Node.js 版本
FROM node:16.14-alpine3.14 AS builder
# 安装 pnpm
RUN npm install -g pnpm
# 创建应用程序目录并将其设为工作目录
WORKDIR /app
# 将 package.json 和 package-lock.json(或 yarn.lock)复制到应用程序目录
COPY package*.json ./
# 安装应用程序依赖
RUN pnpm install
# 将应用程序的所有文件复制到应用程序目录
COPY . .
# 构建应用程序
RUN pnpm run build
FROM nginx:latest
COPY --from=builder /app/dist /opt/www
# RUN rm /etc/nginx/conf.d/default.conf
COPY --from=builder /app/nginx.conf /etc/nginx/nginx.conf
CMD ["nginx","-g","daemon off;"]
nginx.conf
,用来处理请求访问
这个配置只会在你生成的项目镜像内生效,不会影响其他项目
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
charset utf-8;
root /opt/www;
location / {
# 此处的 @router 实际上是引用下面的转发,否则在 Vue 路由刷新时可能会抛出 404
try_files $uri $uri/ @router;
# 请求指向的首页
index index.html;
}
# 由于路由的资源不一定是真实的路径,无法找到具体文件
# 所以需要将请求重写到 index.html 中,然后交给真正的 Vue 路由处理请求资源
location @router {
rewrite ^.*$ /index.html last;
}
error_page 500 502 503 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
}
}
events {
# 配置 Nginx 工作进程的最大数量
worker_connections 1024;
# 配置 Nginx 所使用的事件驱动模块
use epoll;
}
有些同学可能要问,为什么要配置
events
,是因为我这边用的nginx镜像,自带的没有配置他。需要手动配置一番。此处还应注意HTTP
下的include
和default_type
,如果不配置,返回的静态文件的content-type
可能会有问题,需要指定一下
.gitlb-ci.yml
,让你的流水线和当前项目挂钩~
.gitlab-ci.yml
是必要的文件,push代码时,会检测是否包含此文件,如果不包含,不会执行流水线的哦~
# stages,将流水线分为两步,第一步执行打包镜像的命令--build
# 第二步,执行启动镜像的命令 ---deploy
stages:
- "build"
- "deploy"
services:
- docker:dind
build:
stage: build
tags:
- build
script:
# 两个if,用来处理之前的数据
# 判断当前项目是否正在运行,如果正在运行,则停止,并删除这个容器,防止端口占用,导致deploy启动失败
- if [ $(docker ps -q -f name=runner-project) ]; then docker stop runner-project && docker rm runner-project; fi
# 由于我服务器内存较小,在构建新的镜像之前,我会删除掉之前的旧镜像。
- if docker images | awk '{print $1"_"$2}' | grep -qx runner-project; then docker rmi runner-project; fi
# 执行build,这一步跟之前的Dockerfile挂钩,其实执行的就是Dockerfile里的命令
- docker build -t runner-project .
deploy:
stage: deploy
tags:
- build
script:
- docker run -d -p 10880:80 runner-project #启动
# 如果你需要指定分支打包,可以使用only字段,限定分支打包,支持正则匹配哦
ok,看看效果
推送代码
推送代码的时候,会自动触发流水线,直接进入项目查看。
点进去查看一下具体内容,可以看到有两个过程,这个就是我们在
.gitlab-ci.yml
里面写的过程。点击具体step,可以查看更多详情。
查看服务器容器是否启动
这里可以看到,容器已经正常启动起来了~
访问项目
ok,没有任何问题!
是否可以用于公司部署项目?
No!
这是个玩具,不能用于公司部署
这个前一部分是可以用于公司的,没有任何问题~问题在哪呢,问题出在直接部署上面。 公司部署项目,是有多个环境的。而且也不是说上传代码立马部署。需要指定时间。 那么,就需要构造一个发布中心。原有的镜像,也不需要删除,留着就是,指定服务器发布指定的镜像。 具体的操作还是比较繁琐,所以我说这个就是个玩具。
每一个新项目都需要一个新的端口号支撑?
这个类似于一个服务,肯定会涉及到端口占用的问题。
如何优化?
在宿主机安装一个nginx,做路径转发。比如项目A,访问是
localhost:10088
,在宿主机中/proecjt-a/-> rewrite localhost:10088
,也是很不错的一个思路。
at last,想找份工作。
挺惨的哈哈哈,失业了。
希望在重庆、成都、北上广。
**[有路子的ikun,加我一起学习](url)**