Gitlab(17.2) docker compose で立ち上げる方法

## 事前準備

dockerをインストールする。

https://qiita.com/KO_YAmajun/items/41ea85d30f143b25135c

自己証明書を二つ生成する。一つはgitlabサーバ用、もう一つはpages用

https://www.baeldung.com/linux/alpine-self-signed-certificate

### コードサンプル

```yaml:compose.yml
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json

x-logging: &default-logging
  logging:
    options:
      max-size: "10m"
      max-file: "10"
  extra_hosts:
    # IPはGITLABサーバのIP
    - "gitlab.aruki.com:192.168.1.3"
    - "projects.gitlab.aruki.io:192.168.1.3"
    # GITLABのトップレベルグループ名を指定
    - "publics.gitlab.aruki.io:192.168.1.3"

services:
  proxy:
    container_name: proxy
    image: traefik:v3.1.0
    restart: always
    env_file: ./common.env
    environment:
      no_proxy: gitlab
    command:
      # DOCKERの状態を動的に読み取る。
      - --providers.docker
      - --providers.docker.exposedByDefault=false
      # HTTP
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entryPoint.scheme=https
      - --entrypoints.web.http.redirections.entryPoint.to=websecure
      # HTTP(TLS)
      - --entrypoints.websecure.address=:443
      - --entrypoints.websecure.http.tls=true
      - --providers.file.filename=/etc/traefik/config.yaml
      - --providers.file.watch=true
      # SSH(GIT)
      - --entrypoints.ssh.address=:22
      # [OPTION]ダッシュボード。実運用環境では無効にすること
      - --api.insecure=true
    ports:
      - "22:22"
      - "80:80"
      - "443:443"
      # ダッシュボード用のポート
      - "8089:8080"
    volumes:
      # DOCKERの状態を動的に読み取る。
      - /var/run/docker.sock:/var/run/docker.sock:ro
    configs:
      - source: traefik-config
        target: /etc/traefik/config.yaml
        mode: 440
    secrets:
      - gitlab-cert
      - gitlab-key
      - pages-cert
      - pages-key
    <<: *default-logging

  # https://docs.gitlab.com/ee/install/docker.html#install-gitlab-using-docker-swarm-mode
  gitlab:
    container_name: gitlab
    image: gitlab/gitlab-ce:17.2.1-ce.0
    restart: always
    env_file: ./common.env
    volumes:
      - gitlab-config:/etc/gitlab
      - gitlab-log:/var/log/gitlab
      - gitlab-data:/var/opt/gitlab
    hostname: 'gitlab.aruki.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: "from_file('/omnibus_config.rb')"
      no_proxy: proxy
    <<: *default-logging
    labels:
      - "traefik.enable=true"
      # ssh(git)
      - "traefik.tcp.services.gitlab-ssh.loadbalancer.server.port=22"
      - "traefik.tcp.routers.gitlab-ssh.service=gitlab-ssh"
      - "traefik.tcp.routers.gitlab-ssh.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.gitlab-ssh.entrypoints=ssh"
      # http
      - "traefik.http.services.gitlab.loadbalancer.server.port=80"
      - "traefik.http.routers.gitlab.service=gitlab"
      - "traefik.http.routers.gitlab.rule=Host(`gitlab.aruki.com`)"
      #- "traefik.http.routers.gitlab.rule=Host(`gitlab.aruki.com`) || Host(`projects.gitlab.aruki.io`)"
      - "traefik.http.routers.gitlab.entrypoints=websecure"
      # http-registry
      - "traefik.http.services.gitlab-registry.loadbalancer.server.port=5000"
      - "traefik.http.routers.gitlab-registry.service=gitlab-registry"
      - "traefik.http.routers.gitlab-registry.rule=Host(`registry.aruki.com`)"
      - "traefik.http.routers.gitlab-registry.entrypoints=websecure"
      # http-pages
      - "traefik.http.services.gitlab-pages.loadbalancer.server.port=8081"
      - "traefik.http.routers.gitlab-pages.service=gitlab-pages"
      - "traefik.http.routers.gitlab-pages.rule=HostRegexp(`^[a-zA-Z-]+\\.gitlab.aruki.io$`)"
      - "traefik.http.routers.gitlab-pages.priority=199"
      # || Host(`publics.gitlab.aruki.com`) || Host(`projects.gitlab.aruki.com`)
      - "traefik.http.routers.gitlab-pages.entrypoints=websecure"
    configs:
      - source: gitlab
        target: /omnibus_config.rb
    secrets:
      - source: gitlab-cert
        target: /etc/gitlab/ssl/gitlab.aruki.com.crt
        mode: 440
      - source: gitlab-key
        target: /etc/gitlab/ssl/gitlab.aruki.com.key
        mode: 440
      - source: pages-cert
        target: /etc/gitlab/ssl/gitlab.aruki.io.crt
        mode: 440
      - source: pages-key
        target: /etc/gitlab/ssl/gitlab.aruki.io.key
        mode: 440
      - source: gitlab-cert
        target: /usr/local/share/ca-certificates/gitlab.aruki.com.crt
        mode: 440
      - source: gitlab-key
        target: /usr/local/share/ca-certificates/gitlab.aruki.com.key
        mode: 440
      - source: pages-cert
        target: /usr/local/share/ca-certificates/gitlab.aruki.io.crt
        mode: 440
      - source: pages-key
        target: /usr/local/share/ca-certificates/gitlab.aruki.io.key
        mode: 440
      - source: gitlab_root_password
        target: /run/secrets/gitlab_root_password
        mode: 440

  runner:
    container_name: runner
    image: gitlab/gitlab-runner:alpine3.19-v17.2.1
    restart: always
    volumes:
      - gitlab-runner-config:/etc/gitlab-runner
      - /var/run/docker.sock:/var/run/docker.sock
    <<: *default-logging
    secrets:
      # 自己証明書を取り込む。そうしないと、runnerとGitlabが接続できない
      # https://www.baeldung.com/linux/alpine-self-signed-certificate
      - source: gitlab-cert
        target: /usr/local/share/ca-certificates/gitlab.aruki.com.crt
        mode: 440

  # 製図用サーバ。awsの製図をするのに使える
  kroki:
    image: 'yuzutech/kroki:0.25.0'
    hostname: kroki.aruki.com
    container_name: kroki
    restart: always
    environment:
      - KROKI_SAFE_MODE=unsafe
      - KROKI_DIAGRAMSNET_HOST=diagramsnet
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.kroki.loadbalancer.server.port=8000"
      - "traefik.http.routers.kroki.service=kroki"
      - "traefik.http.routers.kroki.rule=Host(`kroki.aruki.com`)"
      - "traefik.http.routers.kroki.entrypoints=websecure"
    expose:
      - '8000'

volumes:
  gitlab-config:
  gitlab-log:
  gitlab-data:
  gitlab-runner-config:
configs:
  traefik-config:
    file: ./traefik-config.yaml
  gitlab:
    file: ./omnibus_config.rb
secrets:
  gitlab-cert:
    file: ./gitlab.aruki.com.crt
  gitlab-key:
    file: ./gitlab.aruki.com.key
  pages-cert:
    file: ./gitlab.aruki.io.crt
  pages-key:
    file: ./gitlab.aruki.io.key
  gitlab_root_password:
    file: ./root_password.txt
```

```ruby:omnibus_config.rb
external_url 'https://gitlab.aruki.com/'

#ROOT初期パスワードをファイルから読み取る
gitlab_rails['initial_root_password'] = File.read('/run/secrets/gitlab_root_password').gsub("\n", "")
# gitlab_rails['time_zone'] = 'Tokyo'

# データベースを外部化する設定。ただし、DOCKERの場合外部化はあまりお勧めしない・・・
# gitlab_rails['db_adapter'] = 'postgresql'
# gitlab_rails['db_host'] = 'gitlab-db'
# gitlab_rails['db_port'] = 5432
# gitlab_rails['db_database'] = 'gitlab'
# gitlab_rails['db_username'] = 'gitlab'
# gitlab_rails['db_password'] = 'gitlab'

# HTTPS設定
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.aruki.com.crt"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.aruki.com.key"
nginx['hsts_max_age'] = 0

#[OPTION]gitlab container registryを有効化することで、コンテナをローカルに保有できる
registry_external_url 'http://registry.aruki.com'
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_api_url'] = "http://localhost:5000"
registry['enable'] = true
registry_nginx['enable'] = false
registry['registry_http_addr'] = "0.0.0.0:5000"

# コンテナレジストリを次世代バージョンにする場合に使用
# registry['database'] = {
#     "enabled" => false,
#     "host" => "gitlab-registry-db",
#     "port" => 5432,
#     "user" => "gitlab",
#     "password" => "gitlab",
#     "dbname" => "gitlab-registry"
# }

#[OPTION]pages機能を有効化することで、ブラウザでhtmlレポートが読めるようになる
#pagesを使用する場合、生IPは使用不可。
pages_external_url 'https://gitlab.aruki.io/'
letsencrypt['enable'] = false

gitlab_pages['internal_gitlab_server'] = 'http://localhost:8080'
gitlab_pages['enable'] = true
gitlab_pages['access_control'] = false
gitlab_pages['redirect_http'] = false
gitlab_pages['metrics_address'] = ":9235"

#proxy=>pagesのアクセス経路
pages_nginx['enable'] = false
gitlab_pages['external_http'] = ['0.0.0.0:8081']
gitlab_pages['external_https'] = ['0.0.0.0:18081']
#gitlab_pages['env']['http_proxy'] = 'https://gitlab.aruki.com'
gitlab_pages['env'] = {
    "http_proxy" => "https://gitlab.aruki.com",
    "FF_CONFIGURABLE_ROOT_DIR" => "true"
}

# [OPTION]リソース軽減するために不要な機能を停止
gitlab_rails['gitlab_kas_enabled'] = false
prometheus_monitoring['enable'] = false
prometheus['enable'] = false
alertmanager['enable'] = false
sidekiq['metrics_enabled'] = false

gitlab_rails['env'] = {
  'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000'
}

gitaly['env'] = {
  'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000'
}
```

```root_password.txt
MySuperSecretAndSecurePassw0rd!
```

```yaml:traefik-config.yaml
# yaml-language-server: $schema=https://json.schemastore.org/traefik-v2-file-provider.json
tls: 
  stores:
    default:
      # フォールバック(gitlab証明書がヒットしないため、pages用証明書にフォールバック)
      defaultCertificate:
        certFile: "/run/secrets/pages-cert"
        keyFile: "/run/secrets/pages-key"
  certificates:
    - certFile: "/run/secrets/gitlab-cert"
      keyFile: "/run/secrets/gitlab-key"

```

```common.env
TZ=Asia/Tokyo
```

## 起動方法

```bash
docker-compose up -d
docker exec gitlab update-ca-certificates
docker exec runner update-ca-certificates
```

起動後、下記のダッシュボードを開いて待つ。

http://locaslhost:8089/dashboard/#/

最初はServicesの数が4個、Gitlabの立ち上げに成功するとServicesの数が7個になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161516/2b24c1aa-544d-f247-b5a0-8323808da286.png)

### 外部からGitlabサーバにアクセスする方法

1. hostsを追加する
2. 自己証明書をインストールする

```text:hosts
192.168.1.3 gitlab.aruki.com kroki.aruki.com projects.gitlab.aruki.io publics.gitlab.aruki.io
```

### 製図サーバにアクセスする方法

https://kroki.aruki.com/

### 不具合切り分け基準

- traefikダッシュボードにアクセスできない
  - 【原因】docker構成またはdocker起動自体の失敗
- traefikダッシュボードにアクセスできる
  - krokiサーバにアクセスできないか、自己証明書警告が発生
    - 【原因】自己証明書設定の失敗
  - krokiサーバにアクセスできる
    - Gitlabにアクセスできない
      - 【原因】Gitlab構成の失敗

## リファレンス資料

### traefik

https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/

### gitlabテンプレート

https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/master/files/gitlab-config-template/gitlab.rb.template

### gitlabインストール方法

https://docs.gitlab.com/ee/install/docker.html