最近折腾了一番自建 gitlab,在此作个记录,供君参考。整个构建过程基于 Docker Swarm(近期有计划将微服务移植到 Kubernetes,但还没倒腾顺手,暂时先沿用旧的方案),主题配图与主题无关,请忽略......node
配置的通常原则是先可用再优化,简单启动 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 往后有空再折腾)。缓存
这一步只须要准备两个编排文件,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
第一步优化完毕,若是不但愿太折腾的话到这就能够结束了,服务的可用性方面不会有太大影响。
我不知道 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
若是你的状况彻底符合官方文档推荐的场景,那很简单:
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/
但通常状况下在微服务中证书呀、负载均衡呀、网关呀等都是属于外围的基础设施了,不会和应用挂钩,这种状况下更简单,由于,彻底不须要任何配置。
上一节提到在目前的微服务环境下启用 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
效果彻底一致,这时候宛如被好几万头草泥马来回碾压,我当初为何就没有把参考文档拉到最后面,忙活一成天却闹了个大笑话,血淋淋的教训!
个人公众号《捷义》