本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或從新修改使用,但須要註明來源。 署名 4.0 國際 (CC BY 4.0)css
本文做者: 蘇洋html
建立時間: 2020年02月04日 統計字數: 12336字 閱讀時間: 25分鐘閱讀 本文連接: soulteary.com/2020/02/04/…mysql
本文成文於 2019年9月,將介紹如何使用 Traefik v1 搭建易於維護管理的 Gogs 。git
原計劃是替換家中 HomeLab 的代碼倉庫,但因爲 GitLab CI 的良好體驗,家裏的 HomeLab 最終仍是選擇繼續使用 GitLab。redis
這篇文章也就沉入了草稿箱,最近在折騰 Traefik 升級和測試服務器,遇到了一些相關的小需求,故將內容更新了一些後發佈出來,但願能幫到有須要的同窗。sql
一直以來,都在使用 GitLab 做爲團隊/我的的倉庫工具,隨着版本的不斷升級,GitLab 的界面功能愈來愈強大,消耗的服務器資源也愈來愈多。docker
最近將 GitLab Community Edition 升級到了 12.3+ ,服務器上依舊是絲般順滑,可是家裏 UPS 顯示服務器待機功率默默上去了 10w。數據庫
這 10w 消耗的電費是小,可是本來靜音的服務器,開始了輕微的風扇轉動,這就有些不能忍了,因而有了使用更輕量應用替換 GitLab 的想法。編程
Gogs 自身支持 HTTPS、支持掛在 SSL 證書,可是考慮到可維護性,這個事情交託給 Traefik 來處理。json
Gogs 默認數據庫使用的是 SQLite,輕量有餘,可是做爲重要數據的數據後端卻不是那麼安全,從官方網站的「如何修復數據庫」能夠看到掛掉的可能性仍是很多的,因此咱們要將其替換。
Gogs 默認的緩存方案是應用自己的內存,通常來講足夠應付我的/小團隊使用,可是爲了進一步提升性能和健壯性,咱們將緩存功能從應用主體解耦,交託於 Redis 進行處理。
那麼開始配置 Gogs 依賴的軟件和環境吧。
使用 compose 配置數據庫很是簡單,二十行之內解決戰鬥:
version: '3.6'
services:
db:
image: mysql:5.7.16
restart: always
expose:
- 3306
volumes:
# 標準 Linux 系統下使用
# - /etc/localtime:/etc/localtime:ro
# - /etc/timezone:/etc/timezone:ro
- ./mysql:/var/lib/mysql
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
environment:
MYSQL_ROOT_PASSWORD: gogs
MYSQL_DATABASE: gogs
MYSQL_USER: gogs
MYSQL_PASSWORD: gogs
TZ: Asia/Shanghai
複製代碼
使用 compose 搞定 Redis 更爲簡單,由於咱們不須要將緩存持久化,因此不到二十行就完事了:
cache:
image: redis:5.0-alpine
restart: always
expose:
- 6379
environment:
TZ: Asia/Shanghai
# volumes:
# 標準 Linux 系統下使用
# - /etc/localtime:/etc/localtime:ro
# - /etc/timezone:/etc/timezone:ro
複製代碼
不須要 Traefik 、MySQL、Redis 的 Gogs 編排文件顯得十分簡單:
version: '3.6'
services:
app:
image: gogs/gogs:0.11.91
restart: always
ports:
- 22:22
- 80:3000
volumes:
# 標準 Linux 系統下使用
# - /etc/localtime:/etc/localtime:ro
# - /etc/timezone:/etc/timezone:ro
- ./data/:/data/
labels:
- "traefik.enable=true"
- "traefik.port=3000"
- "traefik.frontend.rule=Host:${GOGS_DOMIAN}"
- "traefik.frontend.entryPoints=http,https"
- "traefik.frontend.headers.SSLRedirect=true"
- "traefik.frontend.headers.SSLProxyHeaders=X-Forwarded-Proto:https"
- "traefik.frontend.headers.STSSeconds=315360000"
- "traefik.frontend.headers.frameDeny=true"
networks:
traefik:
external: true
複製代碼
可是這樣配置的應用,顯然少了「應用健康檢查」、「倉庫數據安全存儲」、「頁面高性能響應」的能力。
想讓 Gogs 、Redis、MySQL 做爲一個總體一塊兒正常工做,又不受到其餘應用干擾,須要作幾件事:
想要達到這個效果,須要修改 docker-compose.yml
文件,定義 networks
:
version: '3.6'
services:
app:
networks:
- traefik
- gogs
db:
networks:
- gogs
cache:
networks:
- gogs
networks:
gogs:
internal: true
traefik:
external: true
複製代碼
上面的示例代碼中,咱們聲明瞭兩個網絡環境,分別爲私有網絡 gogs
,用於 Gogs 和 MySQL、Redis 互通;外部的網絡 traefik
,用於暴露 Web 服務、Git SSH 服務給用戶。
應用網路互通後,Gogs 能夠經過 Docker 賦予的容器名稱訪問 MySQL、Redis,或者使用 gogs
隨機分配的內網地址進行數據交互。
然而這兩種方案都不是特別利於維護,一旦容器擴展/重建後,容器名稱會發生變化、分配的 IP 地址也會發生變化。
因此這裏可使用 compose 組網聲明 MySQL、Redis 的內網域名。
version: '3.6'
services:
app:
links:
- db:mysql.gogs.lab.com
- cache:cache.gogs.lab.com
複製代碼
而後在 Gogs 容器中訪問上面的域名就可以直接訪問到 MySQL、Redis 啦。
若是你直接啓動包含三個應用的編排文件,可能會遇到 Gogs 報錯,因此能夠配合給三個應用都添加健康檢查,以及啓動依賴關係來解決問題:
version: '3.6'
services:
app:
depends_on:
- db
- cache
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy off localhost:3000 || exit 1"]
db:
healthcheck:
test: ["CMD-SHELL", "/etc/init.d/mysql status"]
interval: 30s
cache:
healthcheck:
test: ["CMD", "redis-cli", "ping"]
複製代碼
如今,你可能會發現一向很靈敏的 Traefik 出現了偶爾不工做的問題,緣由是 Traefik 有時將端口暴露到了 gogs
私有網絡網卡上,解決方案很簡單,聲明 Traefik 工做使用的網卡就成:
version: '3.6'
services:
app:
labels:
- "traefik.docker.network=traefik"
複製代碼
根據以前的經驗,反代的應用有可能會向公網 DNS 尋求幫助,查找服務域名,好比 gogs.lab.com ,爲了不這種狀況發生,應用出現轉半天轉不開的狀況,咱們能夠選擇讓 Gogs 容器的服務域名的解析地址映射爲本地:
version: '3.6'
services:
app:
extra_hosts:
- "${GOGS_DOMIAN}:127.0.0.1"
複製代碼
相比較「默認方案」直接映射 /data
整個大目錄,若是將子目錄單獨映射,則能夠更好的控制應用數據遷移、配置更新。
version: '3.6'
services:
app:
volumes:
- ./app.ini:/data/gogs/conf/app.ini:ro
- ./logs:/data/gogs/data/log
- ./data/avatars:/data/gogs/data/avatars
- ./data/ssh:/data/ssh
- ./data/git:/data/git
複製代碼
官方文檔中提到咱們能夠修改 custom/templates/inject/
和 public/css
下的文件,來定製頁面展現。
可是容器中,這塊實際的目錄卻有一些變化,若是你有定製模版的需求,能夠參考下面的配置解決問題。
version: '3.6'
services:
app:
volumes:
- ./data/custom/template/head.tmpl:/app/gogs/templates/inject/head.tmpl
- ./data/custom/template/footer.tmpl:/app/gogs/templates/inject/footer.tmpl
- ./data/custom/inject-assets/:/app/gogs/public/inject-assets/
複製代碼
加上了健康檢查的 Gogs ,日誌會隨着時間慢慢變大,而這裏日誌對於咱們解決問題沒有絲毫幫助,因該被丟棄:
app_1 | [Macaron] 2019-09-28 07:07:04: Started GET / for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:07:04: Completed GET / 302 Found in 7.6542ms
app_1 | [Macaron] 2019-09-28 07:07:04: Started GET /user/login for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:07:04: Completed GET /user/login 200 OK in 16.5518ms
app_1 | [Macaron] 2019-09-28 07:07:34: Started GET / for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:07:34: Completed GET / 302 Found in 2.892ms
app_1 | [Macaron] 2019-09-28 07:07:34: Started GET /user/login for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:07:34: Completed GET /user/login 200 OK in 10.2743ms
複製代碼
配置 Gogs 應用日誌輸出選項,給出一個「最大尺寸」限制便可:
version: '3.6'
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
複製代碼
將上述全部內容合併,完整的 docker-compose.yml
配置文件以下:
version: '3.6'
services:
app:
image: ${DOCKER_GOGS_IMAGE}
restart: always
networks:
- traefik
- gogs
expose:
- 3000
ports:
- 22:22
links:
- db:${MYSQL_HOST}
- cache:${REDIS_HOST}
depends_on:
- db
- cache
labels:
- "traefik.enable=true"
- "traefik.port=3000"
- "traefik.frontend.rule=Host:${GOGS_DOMIAN}"
- "traefik.frontend.entryPoints=http,https"
- "traefik.frontend.headers.SSLRedirect=true"
- "traefik.frontend.headers.SSLProxyHeaders=X-Forwarded-Proto:https"
- "traefik.frontend.headers.STSSeconds=315360000"
- "traefik.frontend.headers.frameDeny=true"
- "traefik.docker.network=traefik"
logging:
driver: "json-file"
options:
max-size: "10m"
extra_hosts:
- "${GOGS_DOMIAN}:127.0.0.1"
volumes:
# 標準 Linux 系統下使用
# - /etc/localtime:/etc/localtime:ro
# - /etc/timezone:/etc/timezone:ro
- ./app.ini:/data/gogs/conf/app.ini:ro
- ./logs:/data/gogs/data/log
- ./data/avatars:/data/gogs/data/avatars
- ./data/ssh:/data/ssh
- ./data/git:/data/git
# 根據本身需求使用
# - ./data/custom/template/head.tmpl:/app/gogs/templates/inject/head.tmpl
# - ./data/custom/template/footer.tmpl:/app/gogs/templates/inject/footer.tmpl
# - ./data/custom/inject-assets/:/app/gogs/public/inject-assets/
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy off localhost:3000 || exit 1"]
interval: 5s
db:
image: ${DOCKE_MYSQL_IMAGE}
restart: always
networks:
- gogs
expose:
- 3306
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
environment:
MYSQL_ROOT_PASSWORD: gogs
MYSQL_DATABASE: gogs
MYSQL_USER: gogs
MYSQL_PASSWORD: gogs
TZ: Asia/Shanghai
volumes:
# 標準 Linux 系統下使用
# - /etc/localtime:/etc/localtime:ro
# - /etc/timezone:/etc/timezone:ro
- ./mysql:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "/etc/init.d/mysql status"]
interval: 30s
cache:
image: ${DOCKER_REDIS_IMAGE}
restart: always
networks:
- gogs
expose:
- 6379
healthcheck:
test: ["CMD", "redis-cli", "ping"]
environment:
TZ: Asia/Shanghai
# volumes:
# 標準 Linux 系統下使用
# - /etc/localtime:/etc/localtime:ro
# - /etc/timezone:/etc/timezone:ro
networks:
gogs:
internal: true
traefik:
external: true
複製代碼
和配置文件搭配使用的 .env
環境變量文件內容以下:
DOCKER_GOGS_IMAGE=gogs/gogs:0.11.91
GOGS_DOMIAN=gogs.lab.com
DOCKE_MYSQL_IMAGE=mysql:5.7.16
MYSQL_HOST=mysql.gogs.lab.com
DOCKER_REDIS_IMAGE=redis:5.0-alpine
REDIS_HOST=cache.gogs.lab.com
複製代碼
Gogs 使用的 app.ini
配置文件內容:
APP_NAME = Private Repo
RUN_USER = git
RUN_MODE = prod
[database]
DB_TYPE = mysql
HOST = mysql.gogs.lab.com:3306
NAME = gogs
USER = gogs
PASSWD = gogs
SSL_MODE = disable
PATH = data/gogs.db
[cache]
ADAPTER=redis
INTERVAL=60
HOST=network=tcp,addr=cache.gogs.lab.com:6379,password=,db=0,pool_size=100,idle_timeout=180
[repository]
ROOT = /data/git/gogs-repositories
FORCE_PRIVATE=true
MAX_CREATION_LIMIT=-1
DISABLE_HTTP_GIT=true
[server]
DOMAIN = gogs.lab.com
HTTP_PORT = 3000
ROOT_URL = https://gogs.lab.com/
DISABLE_SSH = false
SSH_PORT = 22
SSH_LISTEN_HOST = 0.0.0.0
SSH_LISTEN_PORT = 22
START_SSH_SERVER = false
OFFLINE_MODE = true
[mailer]
ENABLED = false
[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = false
ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = true
[picture]
DISABLE_GRAVATAR = true
ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER=redis
PROVIDER_CONFIG=network=tcp,addr=cache.gogs.lab.com:6379,password=,db=0,pool_size=100,idle_timeout=180
[log]
MODE = console, file
LEVEL = Info
ROOT_PATH = /app/gogs/log
[admin]
DISABLE_REGULAR_ORG_CREATION=true
[security]
INSTALL_LOCK = true
LOGIN_REMEMBER_DAYS=true
SECRET_KEY = pLdr79uA4YnwDab
[other]
SHOW_FOOTER_BRANDING=false
複製代碼
使用 docker-compose up
啓動應用,稍等片刻能夠看到日誌相似下面:
Network traefik is external, skipping
Creating network "gogs_gogs" with the default driver
Creating gogs_db_1 ... done
Creating gogs_cache_1 ... done
Creating gogs_app_1 ... done
Attaching to gogs_cache_1, gogs_db_1, gogs_app_1
cache_1 | 1:C 28 Sep 2019 15:38:57.955 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
cache_1 | 1:C 28 Sep 2019 15:38:57.955 # Redis version=5.0.6, bits=64, commit=00000000, modified=0, pid=1, just started
cache_1 | 1:C 28 Sep 2019 15:38:57.955 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
db_1 | Initializing database
db_1 | 2019-09-28T07:38:58.172565Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db_1 | 2019-09-28T07:38:59.117064Z 0 [Warning] InnoDB: New log files created, LSN=45790
db_1 | 2019-09-28T07:38:59.264592Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
db_1 | 2019-09-28T07:38:59.281117Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 08ba4fc7-e1c3-11e9-a436-0242c0a89003.
app_1 | usermod: no changes
cache_1 | 1:M 28 Sep 2019 15:38:57.956 * Running mode=standalone, port=6379.
cache_1 | 1:M 28 Sep 2019 15:38:57.956 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
cache_1 | 1:M 28 Sep 2019 15:38:57.956 # Server initialized
cache_1 | 1:M 28 Sep 2019 15:38:57.956 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
cache_1 | 1:M 28 Sep 2019 15:38:57.956 * Ready to accept connections
db_1 | 2019-09-28T07:38:59.284542Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
db_1 | 2019-09-28T07:38:59.287236Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
app_1 | Sep 28 07:38:59 syslogd started: BusyBox v1.30.1
... ...
... ...
db_1 | 2019-09-28T07:39:11.612027Z 0 [Note] Event Scheduler: Loaded 0 events
db_1 | 2019-09-28T07:39:11.612400Z 0 [Note] mysqld: ready for connections.
db_1 | Version: '5.7.16' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
app_1 | 2019/09/28 07:39:11 [TRACE] Custom path: /data/gogs
app_1 | 2019/09/28 07:39:11 [TRACE] Log path: /app/gogs/log
app_1 | 2019/09/28 07:39:11 [TRACE] Build Time: 2019-08-12 02:30:12 UTC
app_1 | 2019/09/28 07:39:11 [TRACE] Build Git Hash: c154721f4a8f3e24d2f6fb61e74b4b64529255c2
app_1 | 2019/09/28 07:39:11 [ INFO] Private Repo 0.11.91.0811
app_1 | 2019/09/28 07:39:11 [ INFO] Cache Service Enabled
app_1 | 2019/09/28 07:39:11 [ INFO] Session Service Enabled
app_1 | 2019/09/28 07:39:14 [ INFO] Git Version: 2.22.0
app_1 | 2019/09/28 07:39:14 [ INFO] Git config user.name set to Gogs
app_1 | 2019/09/28 07:39:14 [ INFO] Git config user.email set to gogs@fake.local
app_1 | 2019/09/28 07:39:14 [ INFO] SQLite3 Supported
app_1 | 2019/09/28 07:39:14 [ INFO] Run Mode: Production
app_1 | 2019/09/28 07:39:14 [ INFO] Listen: http://0.0.0.0:3000
app_1 | [Macaron] 2019-09-28 07:39:14: Started GET / for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:39:14: Completed GET / 302 Found in 2.4563ms
app_1 | [Macaron] 2019-09-28 07:39:14: Started GET /user/login for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:39:14: Completed GET /user/login 200 OK in 13.0259ms
app_1 | [Macaron] 2019-09-28 07:39:20: Started GET / for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:39:20: Completed GET / 302 Found in 1.4996ms
app_1 | [Macaron] 2019-09-28 07:39:20: Started GET /user/login for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:39:20: Completed GET /user/login 200 OK in 11.8768ms
app_1 | [Macaron] 2019-09-28 07:39:25: Started GET / for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:39:25: Completed GET / 302 Found in 1.9598ms
app_1 | [Macaron] 2019-09-28 07:39:25: Started GET /user/login for 127.0.0.1
app_1 | [Macaron] 2019-09-28 07:39:25: Completed GET /user/login 200 OK in 10.8364ms
app_1 | [Macaron] 2019-09-28 07:39:30: Started GET / for 127.0.0.1
複製代碼
訪問 gogs.lab.com
打開頁面,就能夠開始使用啦。
備份數據須要使用 gogs backup
,不管是在 容器內執行,仍是在容器外使用 docker exec
都是能夠的。
chown -R /backup
su git -c "/app/gogs/gogs backup -v --target /backup/"
2019/09/28 17:12:36 [ INFO] Backup succeed! Archive is located at: /app/gogs/backup/gogs-backup-20190928171236.zip
複製代碼
比較巧合的是,去年九月開始,gogs 的更新開始了休眠模式,隨後它的 fork 版本 Gitea 開始了茁壯成長。
下一篇聊聊,怎麼使用 Traefik v2 TCP 模式搭建 Gitea 。
--EOF
我如今有一個小小的折騰羣,裏面彙集了一些喜歡折騰的小夥伴。
在不發廣告的狀況下,咱們在裏面會一塊兒聊聊軟件、HomeLab、編程上的一些問題,也會在羣裏不按期的分享一些技術沙龍的資料。
喜歡折騰的小夥伴歡迎掃碼添加好友。(請註明來源和目的,不然不會經過審覈)