docker&gitlab-ci實現一機多用和前端自動化

image

咱們開發的流程通常是新建一個開發分支,而後開發,開發完打包部署到測試環境讓測試測。可是這裏有個痛點,尤爲在大的團隊中,咱們通常會不少人共用一臺測試機,這樣就致使了一個問題,一旦有人在使用這個機器,那麼其餘人就沒法使用該機器,由於切了分支就致使另一我的的代碼被切掉了,這樣就致使測試機器不夠用。而docker的出現,能夠很好的解決這個問題。css

備註:看本文須要對docker和gitlab-ci有所理解。關於這方面的知識不懂的,須要去學習下。html

思路

咱們在每一個分支上開發準備提測的時候,就生成一個該分支特有docker鏡像,該鏡像基於nginx的,它會完成代碼的打包和部署(到nginx上),以此來實現不一樣的分支代碼在不一樣的docker容器上運行的目的,從而實現一個機器能夠運行多個分支的代碼的目的。node

第一步: 編寫Dockerfile

由於咱們須要用到nginx,因此咱們的鏡像是基於nginx的,若是咱們還要作到打包的操做,還須要用到node,假設咱們的項目是在/home/test.liweiji.com下(固然這裏是一個git倉庫,咱們須要先切換咱們的分支並拉取咱們本身的代碼):nginx

Dockerfile:git

# 基於node鏡像
FROM node

# 設置工做路徑 相似cd /home/test.liweiji.com
WORKDIR /home/test.liweiji.com

# 打包到/home/test.liweiji.com/dist目錄下,固然是否是dist看本身項目
RUN npm install \
    && npm run build

# 基於nginx鏡像
FROM nginx

# 通常nginx的默認配置咱們沒法直接使用,因此須要用到本身的nginx配置
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
複製代碼

nginx.confdocker

# 這裏根據你運行docker的用戶來定,設置不對,會出現403
user root;

events {
    use epoll;
    worker_connections 102400;
}

http {
    # 這個不能少,否則會致使靜態樣式沒法起效
    include mime.types;
    # 下面的配置根據本身的項目而定
    server {
        listen 80;
        server_name test.liweiji.com;

        location / {
            add_header Access-Control-Allow-Origin *;
            root /home/test.liweiji.com/dist;
            break;
        }
    }
}
複製代碼

第二步:生成鏡像並運行容器

咱們登陸到測試機,而後進入到/home/test.liweiji.com下shell

# 生成鏡像,不一樣的分支用不一樣的tag
docker build -t <image_name>:<tag> .
# 運行容器,端口映射你們靈活配置,這裏的例子是8080,不一樣的分支能夠用不一樣的端口
docker run --name <container_name> -p 8080:80 -idt <image_name>:<tag>
複製代碼

這樣咱們就實現了不一樣的分支代碼打包到不一樣的docker鏡像中了。咱們可使用docker ps查看是否是在運行咱們的docker容器了。npm

備註:若是沒有運行,則說明出錯了,可是docker run指令並不會告訴咱們具體出錯的緣由,咱們能夠須要經過docker logs <container_name>來查看出錯信息bash

經過上面兩步,咱們就能夠實現了打包不一樣的分支代碼到不一樣的docker鏡像,讓測試經過不一樣的鏡像,測不一樣的分支代碼。app

可是這個方案還不夠完善,還須要開發者跑到測試機去切分支拉代碼,打包鏡像運行容器。那麼有什麼方法讓這些操做自動完成呢,答案是確定的,那就是gitlab-ci了。

利用gitlab-ci實現自動化

gitlab-ci可讓咱們提交代碼後,觸發gitlab-runner去運行一系列的操做,好比安裝、打包、部署等。


   image 

因此,咱們能夠經過gitlab-ci來實現:當咱們提交咱們代碼到遠端的時候,生成該分支的最新代碼對應的鏡像,並運行該鏡像對應的容器,從而實現自動化。

第一步:註冊gitlab-runner

gitlab-ci真正的任務執行是由runner負責的,因此咱們須要在特定的機器註冊runner,咱們經過gitlab-ci-multi-runner來註冊runner。至於如何安裝gitlab-ci-multi-runner,這裏就不在講,你們去google下。
運行gitlab-ci-multi-runner register來註冊runner,咱們按照步驟一步一步輸入url、token、description、tag、executor等,咱們根據咱們gitlab網站上的setting->pipeline上找到url和token。 image這裏的咱們只執行shell命令,因此executor選擇shell。

第二步:編寫.gitlab-ci.yml

咱們須要在.gitlab-ci.yml中定義咱們要作的一系列操做,咱們這裏須要上面所說的二個步驟:生成最新鏡像和運行容器。可是爲了保證每次打包都是最新代碼,咱們須要有個清理的任務,因此有三個步驟:

# gitlab-cli各類變量查看https://docs.gitlab.com/ee/ci/variables/
# 執行job的階段 按順序串行執行
stages:
  - clean
  - build
  - run

# 清理鏡像
job1:
  stage: clean
  only:
    - /^liweiji.*$/ # liweiji下的分支
  tags:
    - test
  script:
    - docker stop test:$CI_COMMIT_REF_NAME
    - docker rm test:$CI_COMMIT_REF_NAME
    - docker image rm test:$CI_COMMIT_REF_NAME
  allow_failure: true #這裏要容許失敗,否則第一次清理是沒有鏡像會報錯,致使後面任務沒法執行
# 自定義階段build的job流程
job2: # 自定義名字
  stage: build # 指定這階段操做的名稱
  only: # 指定那些分支會進入該處理流程
    - /^liweiji.*$/ # liweiji下的分支
  tags:
    # 指定哪些runner執行script裏面的操做,由於咱們上面註冊runner的時候輸入了test,因此這裏就是test,固然你想其餘runner也執行,這裏就添加其餘runner的tag
    - test
  script:
    # docker build, $CI_COMMIT_REF_NAME是分支名,變量能夠查看https://docs.gitlab.com/ee/ci/variables/
    - cd page/public-sale
    - echo `docker build -t test:$CI_COMMIT_REF_NAME . | awk -F "Successfully built " '{print $2}'`
job3:
  stage: run
  only:
    - /^liweiji.*$/ # liweiji下的分支
  tags:
    - test
  script:
    # $CI_COMMIT_REF_NAME是分支名
    - docker run --name test:$CI_COMMIT_REF_NAME -p 8000:80 -idt test:$CI_COMMIT_REF_NAME
複製代碼

咱們的runner有兩種類型,Specific Runners和Shared Runners,咱們一提交代碼,若是.gitlab-ci.yml的job中不指定tag的話,則會執行Shared Runners,指定的話就執行tag對應的Specific Runners。

若是任務成功,咱們就能夠在咱們gitlab網站的pipelines下看到咱們任務的執行了。 image

注意:這裏其實正確的任務應該是生成鏡像後將鏡像上傳到鏡像倉庫,而後讓測試去拉取對應分支的鏡像運行容器的。我這裏這樣作是由於gitlab-runner和測試機在同個機器。

遇到問題

問題一:docker運行nginx報403

這個問題有兩個緣由,一個是權限問題,一個是首頁index.html不存在,咱們遇到的是第一個緣由。其實上面也講過,是由於咱們用root權限運行docker,可是nginx.conf裏面沒有配置user爲root,因此nginx.conf的開頭須要這樣配置:

user root;
複製代碼

問題二:樣式下載了可是未起效

這個緣由也是nginx配置致使的,由於咱們nginx本身從新配置了,因此有些配置沒作好。這裏nginx若是未配置mime.types的話,默認只有application/octet-stream,因此css資源能下載可是不能起效且有Resource interpreted as Stylesheet but transferred with MIME type text/plain的警告,解決辦法就是在nginx.conf的http標籤下添加include mime.types;

http {
    include mime.types;
    .....
}
複製代碼

問題三:docker: command not found

這個緣由是由於.gitlab-ci.yml中的job沒配置tags,致使share runner執行,而share runner中沒有配置docker。

問題四:su: user gitlab-runner does not exist

這個緣由是咱們的runner指定了user爲gitlab-runner可是咱們的機器並無建立這個用戶,全部有兩種方式解決:

  1. useradd gitlab-runner
  2. 殺掉gitlab-ci-multi-runner進程,並以其餘用戶運行,這裏換成root運行
gitlab-ci-multi-runner run --working-directory /home/gitlab-runner --config /etc/gitlab-runner/config.toml --service root--syslog --user root
複製代碼

總結

docker是一個獨立的容器,相互之間隔離,咱們能夠給各個docker鏡像部署nginx和代碼,從而利用docker實現不一樣開發分支下不一樣的代碼運行,從而實現一機多分支代碼運行。gitlab-ci能夠實現自動化任務,好比安裝、打包、部署等一系列任務,那麼咱們就能夠利用gitlab-ci來實現docker鏡像生成和容器運行的自動化,從而避免用戶手動操做。

相關文章
相關標籤/搜索