自建 Gitlab (郵箱配置、拆分 PostgreSQL、Redis) + 隨想

前言

最近折騰了一番自建 gitlab,在此作個記錄,供君參考。整個構建過程基於 Docker Swarm(近期有計劃將微服務移植到 Kubernetes,但還沒倒騰順手,暫時先沿用舊的方案),主題配圖與主題無關,請忽略......
node

1. 快速啓用

配置的通常原則是先可用再優化,簡單啓動 gitlab 只須要一條命令:nginx

sudo docker run --detach \
    --hostname gitlab.yuclk.com \
    --publish 443:443 --publish 80:80 --publish 22:22 \
    --name gitlab \
    --restart always \
    --volume /mnt/nas/gitlab/config:/etc/gitlab \
    --volume /mnt/nas/gitlab/logs:/var/log/gitlab \
    --volume /mnt/nas/gitlab/data:/var/opt/gitlab \
    gitlab/gitlab-ce:latest

而後就功能而言只差配置郵箱這麼一步了,經過 docker exec -it 進入容器,修改 /etc/gitlab/gitlab.rb,添加以下配置:git

# SMTP
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = 'smtp.exmail.qq.com'
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = 'gitlab@youclk.com'
gitlab_rails['smtp_password'] = '******'
gitlab_rails['smtp_domain'] = 'smtp.qq.com'
gitlab_rails['smtp_authentication'] = 'login'
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'

# If your SMTP server does not like the default 'From: gitlab@localhost' you
# can change the 'From' with this setting.
gitlab_rails['gitlab_email_from'] = 'gitlab@youclk.com'
# gitlab_rails['gitlab_email_reply_to'] = 'noreply@youclk.com'

接着使用如下命令讓配置生效:redis

gitlab-ctl reconfigure
gitlab-ctl restart

最後就能夠進入 gitlab 控制檯測試發送郵件:sql

gitlab-rails console
Notify.test_email('destination_email@address.com', 'Message Subject', 'Message Body').deliver_now

除此以外還有兩種配置方式,例:docker

sudo docker run \
    --env GITLAB_OMNIBUS_CONFIG="external_url 'http://my.domain.com/'; gitlab_rails['lfs_enabled'] = true;"
sudo docker run -e GITLAB_CDN_HOST=gitlab.youclk.com

以上只是簡寫示例,我我的並不推薦後面兩種,雖然經過環境變量設置具備更高的自由度,可是配置太多了,我仍是更傾向替換或者掛載配置文件的方式。數據庫

經過以上配置以後整個 gitlab 的基本功能均可用了(CI/CD 往後有空再折騰)。緩存

2. 集成到 swarm

這一步只須要準備兩個編排文件,proxy:bash

version: '3.5'
services:
  proxy:
    image: vfarcic/docker-flow-proxy:18.04.06-12
    ports:
      - 80:80
    networks:
      - proxy
    environment:
      - LISTENER_ADDRESS=swarm-listener:18.04.06-12
      - MODE=swarm
    secrets:
      - dfp_users_monitoring
    deploy:
      labels:
        - com.df.notify=true
        - com.df.port=8080
        - com.df.serviceDomain=localhost
        - com.df.reqPathSearchReplace=/alive,/v1/docker-flow-proxy/ping
      restart_policy:
        condition: any
        max_attempts: 3
      update_config:
        delay: 5s
        order: start-first

  swarm-listener:
    image: vfarcic/docker-flow-swarm-listener:18.04.12-7
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DF_NOTIFY_CREATE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/reconfigure
      - DF_NOTIFY_REMOVE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/remove
    deploy:
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: any
        max_attempts: 3
      update_config:
        delay: 5s
        order: start-first

networks:
  proxy:
    external: true
secrets:
  dfp_users_monitoring:
    external: true

gitlab:負載均衡

version: '3.5'
services:
  gitlab:
    image: gitlab/gitlab-ce
    hostname: gitlab.youclk.com
    networks:
      - proxy
      - youclk
    ports:
      - 2289:22
    volumes:
      - /mnt/nas/gitlab/config:/etc/gitlab
      - /mnt/nas/gitlab/logs:/var/log/gitlab
      - /mnt/nas/gitlab/data:/var/opt/gitlab
    deploy:
      mode: replicated
      labels:
        - com.df.notify=true
        - com.df.port=80
        - com.df.serviceDomain=gitlab.youclk.com
      restart_policy:
        condition: any
        max_attempts: 3
      update_config:
        delay: 5s
        order: start-first

networks:
  proxy:
    external: true
  youclk:
    external: true

而後依次啓用便可,例:

# create infrastructure
echo "youclk:****" | docker secret create dfp_users_monitoring -
docker network create --driver overlay proxy
docker network create --driver overlay youclk

# startup
docker stack deploy -c src/docker-compose-proxy.yml proxy
docker stack deploy -c src/docker-compose-gitlab.yml gitlab

第一步優化完畢,若是不但願太折騰的話到這就能夠結束了,服務的可用性方面不會有太大影響。

3. 分離緩存與數據庫

我不知道 gitlab 爲何不進一步提供純淨版的鏡像,並且官方推薦 omnibus 的安裝方式,反正我至少不喜歡把數據庫和緩存都集成到一個鏡像裏面,預期是構建一個子鏡像並移除 nginx、postgreSQL、redis。通過一番揪心地測試以後,仍是得說惋惜,浪費了很多時間卻沒有順利達到目的,最後只能按照官方推薦的在配置文件中禁用 postgreSQL 和 redis。

首先準備一份 db 的編排文件:

version: '3.5'
services:
  redis:
    image: redis
    networks:
      - proxy
      - youclk
    ports:
      - 6379:6379
    deploy:
      restart_policy:
        condition: any
        max_attempts: 3
      update_config:
        delay: 5s
        order: start-first

  postgresql:
    image: postgres
    networks:
      - proxy
      - youclk
    ports:
      - 5432:5432
    volumes:
      - /mnt/nas/db/postgresql:/var/lib/postgresql
      - $PWD/src/postgresql.conf:/etc/postgresql/postgresql.conf
    deploy:
      labels:
        - com.df.notify=true
        - com.df.port=5432
      restart_policy:
        condition: any
        max_attempts: 3
      update_config:
        delay: 5s
        order: start-first
networks:
  proxy:
    external: true
  youclk:
    external: true

注意,postgreSQL 默認是禁用遠程鏈接的,須要修改 /etc/postgresql/postgresql.conf,反正是內網用,容許全部 ip 就行了 listen_addresses = '*',獲取配置文件的方式:

docker run -i --rm postgres cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf

而後就像我編排文件中示例,掛載上去就好了。

postgreSQL 默認的用戶名、密碼、初始數據庫都是 postgres,能夠經過設置環境變量更改默認配置:

environment:
  - POSTGRES_PASSWORD=mysecretpassword
  - POSTGRES_USER=myuser
  - POSTGRES_DB=mydb

最後就是就是修改 gitlab 的配置文件了:

# redis 
redis['enable'] = false

# Redis via TCP
gitlab_rails['redis_host'] = 'redis'
gitlab_rails['redis_port'] = 6379

# Disable the built-in Postgres
postgresql['enable'] = false

# Fill in the connection details for database.yml
gitlab_rails['db_adapter'] = 'postgresql'
gitlab_rails['db_encoding'] = 'utf8'
gitlab_rails['db_host'] = 'postgresql'
gitlab_rails['db_port'] = 5432
gitlab_rails['db_username'] = 'postgres'
gitlab_rails['db_password'] = 'postgres'
gitlab_rails['db_database'] = 'postgres'

第二步優化到此結束,啓動命令:

cp gitlab.rb /mnt/nas/gitlab/config/gitlab.rb
docker stack deploy -c src/docker-compose-gitlab.yml gitlab

4. 啓用 SSL

若是你的狀況徹底符合官方文檔推薦的場景,那很簡單:

external_url "https://gitlab.youclk.com"
nginx['redirect_http_to_https'] = true

mkdir -p /etc/gitlab/ssl
chmod 700 /etc/gitlab/ssl
cp gitlab.youclk.com.key gitlab.youclk.com.crt /etc/gitlab/ssl/

但通常狀況下在微服務中證書呀、負載均衡呀、網關呀等都是屬於外圍的基礎設施了,不會和應用掛鉤,這種狀況下更簡單,由於,徹底不須要任何配置。

5. 強迫症的救贖

上一節提到在目前的微服務環境下啓用 SSL 不須要任何配置,那我寫這節幹嗎?腦殘嗎?好吧,是腦殘,並且是添加了強迫症的腦殘,先放一張圖:

逼死強迫症的是什麼,各位能懂嗎?也許這輩子都不會用到使用 HTTP 去 clone 代碼,但哥哥就是受不了這個提示,一想起來就頭皮發麻,宛如被一萬頭草泥馬來回碾壓。

這個小問題讓我吃不香,睡不着,都胖了好幾斤,我必需要解決他。而後,我不知道當時的狀態是否是已經已經在阿鼻地獄的邊緣,我最開始想到的是從源代碼中去尋找這個提示的邏輯,強行改爲 HTTPS(失敗);注入一段 js 去修改提示(有修改的延遲,仍然沒法忍受);修改 nginx 的配置文件(成功)。

最後的方案是先設置 external_url 爲 https(這個繞不過去),而後由於負載均衡過來的的只有 http,因此先代理到 https ,再回到 http(也能夠不回),就爲了抵消 external_url 的配置,最後修改下請求頭就好了:

proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;

如今是否是舒服多了...以上一番測試差很少花了一天的時間,就爲了這麼個小玩意兒,但不管怎麼樣,最後有結果了仍是能稍感欣慰的。

但,你覺得就這麼結束了嗎,不,當我從新回顧了一下參考文檔後,我發現了這麼一段提示:

# Other bundled components (Registry, Pages, etc) use a similar strategy for proxied SSL. Set the particular component's *_external_url with https:// and prefix the nginx[...] configuration with the component name. For example, for Registry use the following configuration:

registry_external_url 'https://registry.example.com'

registry_nginx['listen_port'] = 80
registry_nginx['listen_https'] = false

因而,我嘗試着修改爲這樣子:

external_url 'https://gitlab.youclk.com'
nginx['listen_port'] = 80
nginx['listen_https'] = false

效果徹底一致,這時候宛如被好幾萬頭草泥馬來回碾壓,我當初爲何就沒有把參考文檔拉到最後面,忙活一成天卻鬧了個大笑話,血淋淋的教訓!

結語

週六通過這麼一番折騰本就很喪,又碰上 mac 揚聲器壞了,心情一擼到底。而後就想着怎麼去調節一下,好嘛,這一想,又冒出一堆負能量。

不知道有多少人會像我同樣經常被 「本身」 掣肘,在心裏層面我不算是一個很宅的人,我不喜歡呆在家裏,我老是和不少人談詩和遠方,但,只侷限於談。一方面大塊時間的浪費經常給我帶來負罪感,所以我不多能玩得盡興;另外一方面,對於每個月結餘都是負數的資產情況,偶爾還得厚着臉皮問家裏要,我不知道我還有什麼資格去追求些什麼?

想了一夜,週日早上五點鐘起來,買了張動車票準備去上海散散心,好嘛,忘了地鐵沒那麼早開呀,又捨不得打的(備感悽慘~),只能等到點了排隊去改簽(還跟插隊的吵了一架,義正詞嚴地要插我前面,還有傻X幫忙維護,我也是見什麼鬼了~)... 雖過程曲折,但結果總歸不是太糟,被陸家嘴那一堆建築震撼以後也再也不那麼消極了。最後,去了上海中心大廈的頂樓,在那點了杯咖啡,打了一天代碼,晚上七點鐘返回~


個人公衆號《有刻》,咱們共同成長!

相關文章
相關標籤/搜索