經過一週的嘗試, 終於從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+次....真不適合編程