为了托管一些私有的代码,折腾 CI/CD,我用 Docker 搭建一套自己的 Gitlab. Gitlab 社区版功能很强大, 包含且不限于 代码托管、容器镜像库,Gitlab Pages 以及 CI/CD。
搭建服务
我用的是 docker-compose
搭建的,Gitlab 版本为 14.1.1-ce.0
, 整个镜像文件有 2.23G,配置文件如下。
version: '3'
services:
web:
image: 'gitlab/gitlab-ce:14.1.1-ce.0'
restart: always
container_name: gitlab
hostname: 'gitlab.razeen.me'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url "https://gitlab.razeen.me"
letsencrypt['enable'] = false
nginx['redirect_http_to_https'] = false
nginx['listen_port'] = 80
nginx['listen_https'] = false
gitlab_pages['enable'] = true
gitlab_pages['inplace_chroot'] = true
pages_external_url "https://pages.razeen.me"
pages_nginx['listen_port'] = 80
pages_nginx['listen_https'] = false
registry['enabled'] = true
registry_nginx['listen_port'] = 5050
registry_nginx['listen_https'] = false
registry_external_url "https://registry.razeen.me"
gitlab_rails['gitlab_shell_ssh_port'] = 20022
gitlab_rails['gitlab_email_from'] = 'git@xxx.xxx'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "xxxx@xxxx.cn"
gitlab_rails['smtp_password'] = "xxxxxxx"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_domain'] = "exmail.qq.com"
grafana['enable'] = false
prometheus_monitoring['enable'] = false
ports:
- '127.0.0.1:19080:80'
- '127.0.0.1:19050:5050'
- '20022:22'
volumes:
- './config:/etc/gitlab'
- './data:/var/opt/gitlab'
- './logs:/var/log/gitlab'
在配置中,我们只使用了一个环境变量 GITLAB_OMNIBUS_CONFIG
就将我们需要的参数指定好了。其中主要开启了:
- Gitlab
- Pages (静态页面)
- Registry (镜像仓库)
- SMTP 服务
简要配置介绍如下:
# gitlab 服务的地址
external_url "https://gitlab.razeen.me"
# 如果你开启了该选项, 可以自动申请并使用 Let\`s Encrypt 的证书,当然还要配合一些其他设置。 我这里由于 `HTTPS` 是我自己管理的就关闭了该选项;
letsencrypt['enable'] = false
# Gitlab 主服务 Nginx 的配置, 我把 HTTPS 关闭了,全部自己统计管理;
nginx['redirect_http_to_https'] = false
nginx['listen_port'] = 80
nginx['listen_https'] = false
# 有时会结合 CI/CD 部署一些静态页面,就把 Pages 开了。
gitlab_pages['enable'] = true
gitlab_pages['inplace_chroot'] = true
pages_external_url "https://pages.razeen.me"
pages_nginx['listen_port'] = 80
pages_nginx['listen_https'] = false
# 镜像仓库是必须要有的,一些镜像放到内部,自用起来速度杠杠的。
registry['enabled'] = true
registry_nginx['listen_port'] = 5050
registry_nginx['listen_https'] = false
registry_external_url "https://registry.razeen.me"
# 一些基础的配置,SSH 端口,以及 SMTP 邮件服务(我用的QQ的)。
gitlab_rails['gitlab_shell_ssh_port'] = 20022
gitlab_rails['gitlab_email_from'] = 'git@xxx.xxx'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "xxxx@xxxx.cn"
gitlab_rails['smtp_password'] = "xxxxxxx"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_domain'] = "exmail.qq.com"
# grafana 和 prometheus 我关了,后面自建
grafana['enable'] = false
prometheus_monitoring['enable'] = false
# 几个关键的端口先映射出来,80是服务端口,5050是镜像仓库,22就是SSH了。
ports:
- '127.0.0.1:19080:80'
- '127.0.0.1:19050:5050'
- '20022:22'
# 配置、数据、日志 目录也持久化一下
volumes:
- './config:/etc/gitlab'
- './data:/var/opt/gitlab'
- './logs:/var/log/gitlab'
配置好这些,镜像拉下来后,第一次等个几分钟就启动好了(取决于服务器性能)。。。
通配符证书申请
由于要开启 HTTPS, 证书少不了, 首先想到的是 Let`s Encrypt 的通配符了,结合 Acme 自动化,免费 且 省心。 但 Let`s Encrypt 目前在国内申请老不稳定,我就选用了 ZeroSSL 的通配证书, 两行命令搞定。
# 注册账户
docker run --rm -it \
-v "$(pwd)/acme":/acme.sh \
neilpang/acme.sh --register-account -m me@razeen.me --server zerossl
# 申请 ECC 证书, 我用的是 DNSPod 直接写上 DNS 服务商密钥的两个环境变量即可。
# 其他的还参考 https://github.com/acmesh-official/acme.sh/wiki/dnsapi
docker run --rm -it \
-v "$(pwd)/acme":/acme.sh \
--net=host \
-e "DP_Id=xxxx" \
-e "DP_Key=xxxx" \
neilpang/acme.sh --issue \
--dns dns_dp \
-d "razeen.me" \
-d "*.razeen.me" \
-d "*.pages.razeen.me" \
--keylength ec-256 \
--dnssleep 300 \
--force
这样证书就申请好了,在$(pwd)/acme
目录下可找到对应目录及文件。
自建 Nginx
由于机器上我有一些其他服务要用 Nginx, 我就统一用了同一个 Nginx, 配置如下。
- Gitlab 服务
server {
listen 443 ssl http2;
server_name gitlab.razeen.me;
server_tokens off; ## Don't show the nginx version number, a security best practice
## Increase this if you want to upload large attachments
## Or if you want to accept large git objects over http
client_max_body_size 0;
## Strong SSL Security
## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
ssl_certificate /etc/nginx/ssl/razeen_wildcard.crt;
ssl_certificate_key /etc/nginx/ssl/razeen_wildcard.key;
ssl_verify_client optional;
ssl_client_certificate /etc/nginx/ssl/myroot.pem;
ssl_verify_depth 1;
# GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_tickets off;
ssl_session_timeout 1d;
access_log /var/log/nginx/access_gitlab.log;
error_log /var/log/nginx/error_gitlab.log;
## HSTS Config
## https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
add_header Strict-Transport-Security "max-age=63072000";
# Rails sets a default policy of strict-origin-when-cross-origin, so
# hide that and just send the one we've configured for nginx
proxy_hide_header Referrer-Policy;
add_header Referrer-Policy strict-origin-when-cross-origin;
if ($http_host = "") {
set $http_host_with_default "gitlab.razeen.me";
}
if ($http_host != "") {
set $http_host_with_default $http_host;
}
## https://github.com/gitlabhq/gitlabhq/issues/694
## Some requests take more than 30 seconds.
proxy_read_timeout 3600;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host_with_default;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $real_addr;
proxy_set_header X-Forwarded-For $forwarded_for;
proxy_set_header X-Forwarded-Proto https;
location / {
proxy_cache off;
proxy_pass http://127.0.0.1:19080;
}
}
- 镜像仓库配置
server {
listen 443 ssl;
server_name register.razeen.me;
server_tokens off; ## Don't show the nginx version number, a security best practice
client_max_body_size 0;
chunked_transfer_encoding on;
## Strong SSL Security
## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
ssl_certificate /etc/nginx/ssl/razeen_wildcard.crt;
ssl_certificate_key /etc/nginx/ssl/razeen_wildcard.key;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_tickets off;
ssl_session_timeout 1d;
## HSTS Config
## https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
add_header Strict-Transport-Security "max-age=63072000";
access_log /var/log/nginx/access_gitlab_registry.log;
error_log /var/log/nginx/error_gitlab_registry.log;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_read_timeout 900;
proxy_cache off;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:19050;
}
}
- Pages 配置
server {
listen 443 ssl http2;
server_name ~^(?<group>.*)\.pages\.razeen\.cn$;
server_tokens off; ## Don't show the nginx version number, a security best practice
## Disable symlink traversal
disable_symlinks on;
## Strong SSL Security
## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
ssl_certificate /etc/nginx/ssl/razeen_wildcard.crt;
ssl_certificate_key /etc/nginx/ssl/razeen_wildcard.key;
# GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_tickets off;
ssl_session_timeout 1d;
access_log /var/log/nginx/access_gitlab_pages.log;
error_log /var/log/nginx/error_gitlab_pages.log;
## HSTS Config
## https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
add_header Strict-Transport-Security "max-age=63072000";
# Pass everything to pages daemon
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $real_addr;
proxy_set_header X-Forwarded-For $forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_cache off;
proxy_pass http://127.0.0.1:19080;
}
}
配置好后,我们就可以愉快的通过 HTTPS 访问了。到这我们 Gitlab 就搭建好了,功能使用我们就可以后面慢慢折腾啦。
最后,看一下我的管理界面(我还拼了个简单的Logo==)。