本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或重新修改使用,但需要註明來源。 署名 4.0 國際 (CC BY 4.0)
本文作者: 蘇洋
建立時間: 2019年04月10日 統計字數: 6199字 閱讀時間: 13分鐘閱讀 本文連結: soulteary.com/2019/04/10/…
使用 Docker 和 Traefik 搭建 GitLab (前篇)
之前曾不止一次的介紹過 GitLab 在容器中的安裝使用。考慮到多數使用場景都是在內網環境下,所以也未曾過多的進行過安全配置。最近在幫研究院進行系統搭建,其中一個述求是“公網環境下使用”。
本篇將介紹如何更好的使用容器中的 GitLab ,並搭配 Traefik 實現自動掛載 HTTPS 。
編寫 Traefik 配置規則
Traefik 的詳細使用,可以參考以往的文章,比如:使用服務發現改善開發體驗、更完善的 Docker + Traefik 使用方案 等,更多內容可以翻看歷史內容標籤,這裡不過多贅述。
本文依舊只需要關注編排檔案中的 labels
和 networks
欄位配置就足夠啦。
對 GitLab 容器服務的 networks
欄位設定全域性使用的網路卡 traefik
(本例),就可以讓 Traefik 自動接管 GitLab 對外的 Web 服務請求。
networks:
- traefik
複製程式碼
編排檔案中的 labels
欄位,宣告瞭 Traefik 如何對流量進行轉發。假設我們要對外提供三種訪問能力:
https://gitlab.${DOMAIN}
- 訪問 GitLab Web 頁面和 Web API
https://registry.${DOMAIN}
- 使用終端訪問容器倉庫
https://page.${DOMAIN}
- 使用瀏覽器訪問一些倉庫的預覽頁面(類似 GitHub Page)
那麼我們可以這樣配置:
labels:
- "traefik.enable=true"
# GitLab Web 服務
- "traefik.gitlab.port=80"
- "traefik.gitlab.frontend.rule=Host:gitlab.${BASEHOST}"
- "traefik.gitlab.frontend.entryPoints=http,https"
- "traefik.gitlab.frontend.headers.SSLProxyHeaders=X-Forwarded-For:https"
- "traefik.gitlab.frontend.headers.STSSeconds=315360000"
- "traefik.gitlab.frontend.headers.browserXSSFilter=true"
- "traefik.gitlab.frontend.headers.contentTypeNosniff=true"
- "traefik.gitlab.frontend.headers.customrequestheaders=X-Forwarded-Ssl:on"
- "traefik.gitlab.frontend.passHostHeader=true"
- "traefik.gitlab.frontend.passTLSCert=false"
# Registry 服務
- "traefik.registry.port=5100"
- "traefik.registry.frontend.rule=Host:registry.${BASEHOST}"
- "traefik.registry.frontend.entryPoints=http,https"
# Pages 服務
- "traefik.pages.port=5201"
- "traefik.pages.frontend.rule=Host:page.${BASEHOST}"
- "traefik.pages.frontend.entryPoints=http,https"
複製程式碼
Registry
、Pages
這裡,為了節約篇幅,我就不重複貼上相同的內容了,你可以參考 GitLab Web 服務
補全響應頭處理。
當然,如果你覺得容器編排檔案寫的內容太多了,想放到 GitLab 中進行處理也是可以的,稍後我會講。
編寫 GitLab 配置
配置 GitLab 還是需要一些額外的耐心,不過好在坑我都替你趟完了。
配置 GitLab Nginx 服務
在給出參考程式碼之前,我們需要先知道 GitLab 的一個“Tricks”:
如果你設定的 external_url
內容包含 https
,那麼服務預設會使用 SSL 方式對外提供服務。如果你的 external_url
宣告為 http://gitlab.${DOMAIN}
,當系統執行起來後(預設埠為 80
),當我們使用 https
進行訪問,又會出現各種問題,官方文件寫的也是不清不楚。
搜尋 reddit
上的討論歷史,發現有個老外都自暴自棄放棄使用 https
,改用 http
了,令人哭笑不得。
遇到問題解決問題就好了鴨,逃避是什麼鬼。
使用容器方式搭建 GitLab ,所有的配置都需要宣告在編排檔案的 environment
欄位內,下面是 GitLab Web 服務的使用配置。
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.${BASEHOST}'
nginx['enable'] = true
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['http2_enabled'] = false
nginx['client_max_body_size'] = '250m'
nginx['redirect_http_to_https'] = true
複製程式碼
需要注意的是,宣告的外部連結地址 external_url
需要使用 HTTPS
協議。而監聽埠需要設定為 80
,另外也要配置Nginx不進行 https
監聽,不使用 HTTP2
,至於 HTTP
自動轉向 HTTPS
可配可不配,因為 Traefik 側我預設開啟了 HTTP
轉向 HTTPS
功能。
前文提到,如果我們不想使用 Traefik 進行響應頭的修改,那麼該如何在 GitLab 中進行配置呢,也很簡單,多新增一個 proxy_set_headers
的配置即可:
nginx['proxy_set_headers'] = {
"Host" => "$$http_host",
"X-Real-IP" => "$$remote_addr",
"X-Forwarded-For" => "$$proxy_add_x_forwarded_for",
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}
複製程式碼
這裡有一點需要額外注意,所有出現在 environment
欄位內的變數,都需要使用 雙$ 符號宣告,而非 單個$,否則結果不會如願以償。
前端提到了,我們要同時提供 Web 訪問、容器倉庫、頁面預覽三個功能,所以配置還需要加上其他兩項。
registry['enable'] = true
registry_external_url 'https://registry.${BASEHOST}/'
registry_nginx['listen_port'] = 5100
registry_nginx['listen_https'] = false
registry_nginx['redirect_http_to_https'] = true
pages_external_url "https://page.${BASEHOST}/"
pages_nginx['listen_port'] = 5200
pages_nginx['listen_https'] = false
pages_nginx['redirect_http_to_https'] = true
gitlab_pages['enable'] = true
gitlab_pages['inplace_chroot'] = true
gitlab_pages['external_http'] = ['gitlab:5201']
gitlab_pages['dir'] = "/var/opt/gitlab/gitlab-pages"
gitlab_pages['log_directory'] = "/var/log/gitlab/gitlab-pages"
gitlab_pages['artifacts_server'] = true
gitlab_pages['artifacts_server_timeout'] = 10
複製程式碼
可以看到,除了 gitlab_pages
欄位比較特殊外,配置和剛剛大同小異。
另外提一點,我原本的習慣是將所有的流量都配置到 80
埠,再讓 Traefik 進行轉發可讀性會更好一些,但是看到了另外一位國外同學的配置後,我覺得讓埠保持在預設埠也是不錯的選擇,比如 5100
、5200
。
配置檔案最上面的監控需要額外配置,我們回頭細聊,為了減少影響,這裡將這部分功能進行關閉。
配置 GitLab SSH 埠
這裡我選擇讓 GitLab 的 SSH
埠保持預設,而修改宿主機的 SSH
埠到其他位置,這樣做的好處是:
- 可以減少對 GitLab 的配置。
- 倉庫訪問地址顯得更美觀了,避免了使用者使用軟體過程中需要解決的額外問題。
使用編排檔案,將 GitLab 埠對映到宿主機中。
version: '3'
services:
gitlab:
expose:
- 80
- 443
ports:
- '0.0.0.0:22:22'
複製程式碼
這裡有一個小細節,如果你不在 labels
中對你的服務埠進行宣告,Traefik 會使用你暴露的第一個埠作為服務發現的埠。所以將你所有依賴的內容都顯式宣告,是一個好的習慣。
完整的配置檔案
比較重要的細節都講完了,這裡給出完整的配置參考(容器倉庫和頁面預覽服務的響應頭有刪減,有需求可以自行新增):
version: '3'
services:
gitlab:
restart: always
image: ${GITLAB_IMAGE}
hostname: ${HOSTNAME}
healthcheck:
disable: true
expose:
- 80
- 443
ports:
- '0.0.0.0:22:22'
# 解決搜尋引擎搜尋不出小於3字元問題
# https://gitbaai.ac.cn/gitlab-org/gitlab-ce/issues/40379
entrypoint: |
bash -c 'sed -i "s/MIN_CHARS_FOR_PARTIAL_MATCHING = 3/MIN_CHARS_FOR_PARTIAL_MATCHING = 1/g" /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/sql/pattern.rb && /assets/wrapper'
volumes:
- ./config:/etc/gitlab
- ./data:/var/opt/gitlab
- ./logs:/var/log/gitlab
- ./embedded-logs:/opt/gitlab/embedded/logs/
labels:
- "traefik.enable=true"
# GitLab Web 服務
- "traefik.gitlab.port=80"
- "traefik.gitlab.frontend.rule=Host:gitlab.${BASEHOST}"
- "traefik.gitlab.frontend.entryPoints=http,https"
- "traefik.gitlab.frontend.headers.SSLProxyHeaders=X-Forwarded-For:https"
- "traefik.gitlab.frontend.headers.STSSeconds=315360000"
- "traefik.gitlab.frontend.headers.browserXSSFilter=true"
- "traefik.gitlab.frontend.headers.contentTypeNosniff=true"
- "traefik.gitlab.frontend.headers.customrequestheaders=X-Forwarded-Ssl:on"
- "traefik.gitlab.frontend.passHostHeader=true"
- "traefik.gitlab.frontend.passTLSCert=false"
# Registry 服務
- "traefik.registry.port=5100"
- "traefik.registry.frontend.rule=Host:registry.${BASEHOST}"
- "traefik.registry.frontend.entryPoints=http,https"
# Pages 服務
- "traefik.pages.port=5201"
- "traefik.pages.frontend.rule=Host:page.${BASEHOST}"
- "traefik.pages.frontend.entryPoints=http,https"
networks:
- traefik
networks:
traefik:
external: true
複製程式碼
光有編排配置,不能夠愉快使用,這裡還需要建立一個 .env
環境配置檔案:
GITLAB_IMAGE=gitlab/gitlab-ce:11.8.6-ce.0
BASEHOST=lab.com
HOSTNAME=gitlab.lab.com
複製程式碼
兩個配置檔案都準備好之後,使用 docker-compose up
啟動你的應用,然後就可以開始使用了。
如果你還不熟悉 docker-compose
的使用,可以翻閱之前的文章,查閱 “一些額外的小技巧”一節。
最後
下一篇,我將著重介紹一些安全配置上的問題。
我現在有一個小小的折騰群,裡面聚集了一些喜歡折騰的小夥伴。
在不發廣告的情況下,我們在裡面會一起聊聊軟體、HomeLab、程式設計上的一些問題,也會在群裡不定期的分享一些技術沙龍的資料。
喜歡折騰的小夥伴歡迎掃碼新增好友。(請註明來源和目的,否則不會通過稽核)