经过一周的尝试, 终于从0到1把gitlab-ci
弄好了, 完全抛弃travis-ci
, 最大的坑仍是墙外的东西太慢了, 老是timeouthtml
整个过程分为以下几步:前端
gitlab-runner
, 并选择正确的executor
gitlab-ci.yml
, 实现一个完整的前端后分离项目的构建部署gitlab-runner
跟gitlab-ci
是连体婴, 主要为gitlab-ci
打工, 使用镜像的安装方式以下:vue
docker run -d --name gitlab-runner --restart always \ -v /srv/gitlab-runner/config:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest
其中挂载卷/srv/gitlab-runner/config/config.toml
包含了全部runner
的配置信息.node
经过挂载/var/run/docker.sock:/var/run/docker.sock
,使得容器中的进程能够经过它与Docker守护进程通讯webpack
在启动了gitlab-runner
容器后, 执行以下命令进入容器, 注册runner
nginx
docker exec -it gitlab-runner /bin/bash root@492ce6ab72f9:/# gitlab-runner register
接下来须要填写的信息以下:git
Please enter the gitlab-ci coordinator URL: 你的Gitlab地址: http(s)://gitlab.xxx.com Please enter the gitlab-ci token for this runner: 你的Gitlab admin/runners页面中的token Please enter the gitlab-ci description for this runner: 填写描述, 可有可无 Please enter the gitlab-ci tags for this runner (comma separated): 填写标签, 没有标签谁均可以用, 是shared-runner, 有标签须要声明才可用, 回车就对了 Please enter the executor: docker-ssh, ssh, docker+machine, kubernetes, docker-ssh+machine, docker, parallels, shell, virtualbox: 选择你的executor: Docker应该是我观察到最经常使用的吧 Please enter the default Docker image (e.g. ruby:2.6): 选择一个默认镜像: 例如 docker:stable-alpine
不出意外, 就能在gitlab
中看到了github
参考官方文档 - executorweb
shell executor
: 最简单的executor, 全部依赖都必须手动安装redis
Virtual Machine Executor
: 建立虚拟机用于构建, 若是你但愿在不一样的操做系统上构建, 能够选择它
Docker Executor
: 最佳的选择QAQDocker Machine
: Docker的拓展, 工做方式与Docker相似, 不过须要额外的一些安装步骤最后只尝试了Docker
和Docker + Machine
, 只是Docker + Machine
的runner
一直没有链接成功
使用dind
的背景是: 须要在容器内执行docker命令,
在1.1
中注册好了一个docker executor
以后, 只须要完成两个操做, 便可使用
gitlab-ci.yml
中添加:imgage: docker:stable service: - docker:dind # 测试 before_script: - docker info
config.toml
中该runner
中设置了privileged = true
讲道理, 我没有在官方文档中找到: 当使用docker做为runner executor时, 如何设置registry-mirror
若是使用docker + machine
的话, 能够在config.toml
中设置:
进过测试, 此项配置显然对docker
无效...
最终使用的办法是:
image: docker:stable services: - docker:dind stages: - build - make_image - deploy cache: untracked: true paths: - backend/node_modules/ - frontend/node_modules/ - frontend/dist/ upload_to_oss: image: node:lts-alpine stage: build script: - cd frontend - npm install --registry https://registry.npm.taobao.org - npm run build
经过在gitlab-ci
控制台配置一些用于上传至OSS的环境变量, 就能够在这个阶段实现以下两个功能:
对于先后端分离的项目, 每每有一个特色: 须要经过nginx进行反向代理
所以, 前端镜像是以NGINX为核心的, 须要准备2~3个文件
dist
目录: 前端的静态资源xxx.conf
: nginx的部分配置, 例如: history路由的处理, 端口转发Dockerfile
以下:
FROM nginx:stable-alpine LABEL maintainer=Caaalabash EXPOSE 800 COPY xxx.conf /etc/nginx.conf.d COPY dist /etc/nginx/dist/ CMD nginx -g "daemon off;"
xxx.conf
以下:
server { listen 800; server_name localhost; root /etc/nginx/dist; location / { try_files $uri $uri/ @router; index index.html; } location @router { rewrite ^.*$ /index.html last; } # 此处直接使用localhost进行转发与后文采用的network_mode有关 location /api { proxy_pass http://localhost:3000/api; } }
能够看到xxx.conf
只与业务相关, 不涉及https
的处理, 这部分应该交由宿主机的nginx进行处理, 示例代码以下:
宿主机nginx配置:
server { listen 80; server_name xxx.xxx.xxx; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2 default_server; server_name xxx.xxx.xxx; ssl on; ssl_certificate cert/blog.pem; ssl_certificate_key cert/blog.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; # 全部请求交给前端容器处理 location / { proxy_pass http://127.0.0.1:8888; } }
体如今gitlab-ci.yml
中
make_fe: stage: make_image script: - docker login -u="$DOCKER_USERNAME_ALI" -p="$DOCKER_PASSWORD_ALI" $DOCKER_REPOSITORY_ALI - docker build -t $DOCKER_REPOSITORY_ALI/calabash/blog:$CI_COMMIT_SHORT_SHA-FE ./frontend - docker push $DOCKER_REPOSITORY_ALI/calabash/blog:$CI_COMMIT_SHORT_SHA-FE
过程很简单, 登陆私有镜像仓库, 构建镜像, 上传镜像
对比前端就更更加简单了, 就是一个普通的构建node镜像流程~
FROM node:lts-alpine LABEL maintainer=Caaalabash WORKDIR /app COPY package.json /app RUN npm install --registry https://registry.npm.taobao.org COPY . /app ENV NODE_ENV=production EXPOSE 3000 CMD ["npm", "run", "online"]
体如今gitlab-ci.yml
中
make_be: stage: make_image script: - docker login -u="$DOCKER_USERNAME_ALI" -p="$DOCKER_PASSWORD_ALI" $DOCKER_REPOSITORY_ALI - docker build -t $DOCKER_REPOSITORY_ALI/calabash/blog:$CI_COMMIT_SHORT_SHA-BE ./backend - docker push $DOCKER_REPOSITORY_ALI/calabash/blog:$CI_COMMIT_SHORT_SHA-BE
在构建完镜像后, 就进入最后一个阶段: 部署
部署的核心是:
docker-compose.yml
体如今gitlab-ci.yml
中为:
deploy_test: image: caaalabash/alpine-ssh:latest stage: deploy before_script: - echo "$SSH_PRIVATE_KEY" > id_rsa_2048 - chmod 0600 id_rsa_2048 - eval $(ssh-agent) - ssh-add id_rsa_2048 script: - scp -P $SSH_PORT deploy/* root@$DEPLOY_SERVER:$SERVER_FOLDER/deploy - ssh -p $SSH_PORT root@$DEPLOY_SERVER "chmod +x $SERVER_FOLDER/deploy/startup.sh" - ssh -p $SSH_PORT root@$DEPLOY_SERVER "$SERVER_FOLDER/deploy/startup.sh $CI_COMMIT_SHORT_SHA"
构建脚本只是: 中止/删除旧容器/镜像, docker-compose up
简化版的配置以下:
version: "3" services: backend: image: calabash/blog:${VUE_BLOG_TAG}-BE container_name: blog-backend # 只须要暴露前端端口 ports: - 8888:800 network_mode: bridge restart: unless-stopped # 使用的mongodb redis服务 external_links: - myMongoDB - myRedis frontend: image: calabash/blog:${VUE_BLOG_TAG}-FE container_name: blog-frontend restart: unless-stopped network_mode: "service:backend"
核心在于frontend
中的配置:
network_mode: "service:backend"
经过这个配置, 和后端容器共用一个网络, 所以在nginx配置文件中, 能够直接使用localhost
进行转发, 不过这样作须要保证, 后端容器就绪后再启动前端容器
总所周知, docker-compose
没有这个能力TAT, 最使用的方案有两个
此处使用wait-for-it.sh
的简化版操做
修改前端Dockerfile
为:
FROM nginx:stable-alpine LABEL maintainer=Caaalabash EXPOSE 800 COPY wait-for-it.sh wait-for-it.sh RUN chmod +x wait-for-it.sh COPY blog.conf /etc/nginx/conf.d COPY dist /etc/nginx/dist/ CMD ["./wait-for-it.sh"]
添加wait-for-it.sh
#!/bin/sh while ! nc -z -v localhost 3000 do echo "wait backend" sleep 3 done echo "done" nginx -g "daemon off;"
便可
这波折腾虽然麻烦, 不过仍是完整的实现了一个先后端分离项目的Gitlab-ci配置,
达到了预期的目标, 虽然gitlab-ci.yml
配置是很是好上手的, 除此以外
没想到试错了90+次....真不适合编程