公司最近準備了一臺新的開發服務器,正好用以實踐docker的基本應用。docker的好處再也不贅述,詳情可參考阮一峯的這篇入門。(關於Docker最好的中文介紹,沒有之一)。html
公司目前主要使用了EggJs + ReactJS的技術組合,而且是先後端分離的。在使用docker之後,大體的部署方式以下:node
在新購買的阿里雲主機上(域名要準備好,映射到主機的IP上),直接用root用戶鍵入如下命令:nginx
root# yum install gitlab-ci-multi-runner root# yum install docker root# yum install nginx
以上三個命令,即已安裝好所需的軟件環境。餘下任務都可交由docker和gitlab-runner完成。git
nginx在安裝完成後,須要對配置文件進行修改,添加要代理的端口設置。配置文件通常放在/etc/nginx/conf.d目錄下。web
在/etc/nginx/nginx.conf中,有這麼一段代碼:redis
... include /etc/nginx/conf.d/*.conf; ...
意思是,全部在/etc/nginx/conf.d目錄下的配置文件都會被自動載入。所以在該目錄下加入一個配置文件如:service.conf。內容以下:sql
server { listen 80; server_name your.website.com; // 這裏寫你配置好的域名 // api訪問路徑(http://your.website.com/api/test) location /api/test { proxy_http_version 1.1; client_max_body_size 100m; client_body_buffer_size 128k; proxy_send_timeout 300; proxy_read_timeout 300; proxy_buffer_size 4k; proxy_buffers 16 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_connect_timeout 30s; proxy_redirect off; proxy_pass http://127.0.0.1:18001/; // api的docker轉發的內部端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } // web訪問路徑(http://your.website.com/web/test) location /web/test { alias /data/www/test; // web項目文件放在此目錄下,可自行配置爲你本身的目錄 index index.html; } // gitlab訪問路徑(http://your.website.com/gitlab), location /gitlab { proxy_http_version 1.1; client_max_body_size 100m; client_body_buffer_size 128k; proxy_send_timeout 300; proxy_read_timeout 300; proxy_buffer_size 4k; proxy_buffers 16 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_connect_timeout 30s; proxy_pass http://127.0.0.1:15080/; // gitlab的docker轉發的內部端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
conf配置完成後,重啓nginxdocker
root# service nginx restart
經過docker方式安裝gitlab,比傳統方式簡單了不止100倍。只需簡單兩個命令便可開始使用:shell
root# docker pull gitlab/gitlab-ce // 這裏安裝的是ce版
這裏沒有指定版本,因此默認安裝的是最新版。你能夠在這裏找到本身想要的版本並進行安裝:npm
root# docker pull gitlab/gitlab-ce:11.3.3-ce.0
使用簡單一條命令,便可運行並使用gitlab。首先編輯啓動腳本gitlab-start.sh,例如放在/srv/docker中:
#! /bin/bash docker run --name gitlab \ -d \ --restart always \ -p 15022:22 \ # 暴露給nginx的外部端口, -p 15080:80 \ # 暴露給nginx的外部端口(與上面的nginx配置要一致) -p 15433:433 \ # 暴露給nginx的外部端口, -v /srv/gitlab/config:/etc/gitlab \ # gitlab的配置文件 -v /srv/gitlab/logs:/var/log/gitlab \ # gitlab的日誌文件 -v /srv/gitlab/data:/opt/lib/gitlab \ # gitlab的數據文件 gitlab/gitlab-ce
使用bash執行該shell文件,gitlab便可啓動
root# bash /srv/docker/gitlab-start.sh
如今訪問your.website.com/gitlab,應該就能夠正常訪問gitlab服務了。就是這麼簡單!
api項目和web項目的運行方式有所區別,因此runner也有所區別。
執行runner的註冊命令,按照說明進行參數配置
root# gitlab-ci-multi-runner register Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci): # http://your.website.com/gitlab Please enter the gitlab-ci token for this runner: # xxxxxxxx Please enter the gitlab-ci description for this runner: # web-deploy-runner Please enter the gitlab-ci tags for this runner (comma separated): # node-web-deploy Registering runner... succeeded runner=avuSXASJ Please enter the executor: docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine, docker: # docker Please enter the default Docker image (e.g. ruby:2.1): # node:10 Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
說明
添加完成後,runner就已經在服務中跑起來。只要gitlab的項目有提交,相關runner就根據tags來決定是否跑自動部署的命令。
在web項目的根目錄下,添加.gitlab-ci.yml文件以下:
stages: - deploy cache: key: ${CI_BUILD_REF_NAME} paths: - node_modules/ before_script: - export PATH=/usr/local/bin:$PATH - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - eval $(ssh-agent -s) - ssh-add <(echo "$SSH_PRIVATE_KEY") - mkdir -p ~/.ssh - chmod 700 ~/.ssh - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts - '[[ -f /.dockerenv ]] && echo -e "Host *\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config' # dev分支構建 dev-deploy: stage: build tags: - node-web-deploy # 這個是runner的tags內容 only: - dev # 僅僅dev分支會被對應的runner執行 script: - npm install - npm run build # web項目的打包命令 - scp -r dist/* root@your.website.com:/data/www/test-dev # 將打包好的dist拷貝到部署目錄 #uat分支構建 uat-deploy: stage: build tags: - node-web-deploy # 這個是runner的tags內容 only: - uat # 僅僅uat分支會被對應的runner執行 script: - npm install - npm run build # web項目的打包命令 - scp -r dist/* root@your.website.com:/data/www/test-uat # 將打包好的dist拷貝到部署目錄
說明
如上說明2,由於是在docker內部打包,只能經過scp來拷貝打包好的文件到宿主目錄下。所以須要配置SSH。
參考官方例子便可完成此步驟:
官方文檔推薦使用ed25519類型的SSH,我仍然用的RSA方式
root# ssh-keygen -o -t rsa -b 4096 -C "root@your.website.com"
按照提示,一路點擊Enter便可完成配置。記得:不要添加passphrase。
在gitlab的項目設置(Settings -> CI/CD -> Variables)中,添加SSH_PRIVATE_KEY變量,變量的值爲上一步生成的SSH密鑰對的私鑰。
root# vi ~/.ssh/id_rsa // 這裏保存的就是私鑰,拷貝到SSH_PRIVATE_KEY的value字段中
完成後,繼續添加SSH_KNOWN_HOSTS變量,變量的值爲如下命令的輸出:
root# ssh-keyscan your.website.com
上面兩步驟設置完成後,Runner運行時仍然會報錯,緣由就在於SSH登陸雖然設置完成,但沒有設置登陸免密。免密登陸的要點就在於,要將SSH密鑰對的公鑰導入到~/.ssh/authorized_keys文件中。
對於本次實踐,gitlab-runner和gitlab實際上是在同一臺服務器上完成的。因此,將PUBLC_KEY導入到本地的authorized_keys文件中便可
root# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
作好以上3部,WEB項目的自動部署就算已經完成了。訪問http://your.website.com/web/test 試試看,網頁應該已經出來了。
執行runner的註冊命令,按照說明進行參數配置。(具體說明見:web項目的自動部署)
root# gitlab-ci-multi-runner register Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci): # http://your.website.com/gitlab Please enter the gitlab-ci token for this runner: # xxxxxxxx Please enter the gitlab-ci description for this runner: # api-deploy-runner Please enter the gitlab-ci tags for this runner (comma separated): # node-api-deploy Registering runner... succeeded runner=avuSXASJ Please enter the executor: docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine, docker: # shell Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
在api項目的根目錄下,添加.gitlab-ci.yml文件以下:
stages: - deploy cache: key: ${CI_BUILD_REF_NAME} paths: - node_modules/ before_script: - export PATH=/usr/local/bin:$PATH - npm install # ep-dev分支構建 deploy_dev: stage: deploy tags: - node-api-deploy only: - dev script: - sudo docker cp ./ api-test:/home/service - sudo docker restart api-test # ep-release分支構建 deploy_uat: stage: deploy tags: - node-api-deploy only: - uat script: - sudo docker cp ./ api-test:/home/service - sudo docker restart api-test
說明
上面兩部已經配置好了gitlab的CI/CD,CI/CD命令也提到要使用api項目對應的docker服務。這個docker服務須要咱們提早打包一個image,docker裏要跑的正是api服務所須要的環境。
在api項目的根目錄下,新增Dockerfile(沒有後綴名)以下:
FROM node:10 RUN mkdir -p /home/service WORKDIR /home/service COPY . /home/service RUN npm install EXPOSE 8102 CMD ["npm", "start"]
說明
在根目錄下,執行如下命令便可打包一個image
root# docker build -t lynx/test .
打包完成後,執行docker images便可看到打包完成的docker鏡像。
與gitlab的使用方式相似,先編輯一個啓動腳本/srv/docker/start-test.sh,內容以下:
#! /bin/bash docker run -d --name nr-api-ep-dev \ -p 18001:8102 \ -v /data/api/test/logs:/home/service/logs \ lynx/test
使用bash執行該shell文件,node服務便可啓動
root# bash /srv/docker/start-test.sh
啓動後,執行docker ps能夠查看已啓動的docker任務列表。
至此,web和api服務都已經自動部署完成。
在api服務中,必定會用到sql或redis等第三方的服務。一種方式是將這個服務安裝到宿主環境中,另一種方式是啓動redis的docker服務,將服務請求鏈接(link)過來,(docker-compose方式本文沒有涉及)。
本文使用docker方式安裝redis,並啓動這個服務
root# docker pull redis // 安裝redis root# docker run -d --name=redis -p 6379:6379 -v /srv/redis/data:/var/lib/redis redis:latest redis-server --appendonly yes // 啓動redis
若是api服務須要使用到redis,那麼將redis的地址定義爲127.0.0.1是達不到目的的,由於兩個服務目前都是在docker環境中運行。
如上面的api的docker執行命令,加入--link選項
#! /bin/bash docker run -d --name nr-api-ep-dev \ -p 18001:8102 \ --link redis:redis \ -v /data/api/test/logs:/home/service/logs \ lynx/test
爲了提供服務,docker運行中可使用參數--link。注意,在link了之後api服務中若是要使用redis,服務的地址要改成redis,而不是127.0.0.1或者localhost