Skip to content

Instantly share code, notes, and snippets.

@swrogers
Last active November 16, 2023 19:40
Show Gist options
  • Save swrogers/5e3e003afe7a00a0f217c0268d86da8c to your computer and use it in GitHub Desktop.
Save swrogers/5e3e003afe7a00a0f217c0268d86da8c to your computer and use it in GitHub Desktop.
Run Gitlab Docker behind Caddy reverse proxy via Portainer stack (with an XWiki bonus!)

Gitlab Docker / Caddy / Portainer (plus bonus XWiki)

This is how I was able to get Gitlab CE Docker to run behind a Caddy reverse proxy, created from Portainer stack.

This has taken quite a lot of searching, so I figured that I'd write it up in a location that I could easily refer to it in the future.

There are a handful of items that are initially needed here:

  • Caddy and its network
  • Portainer
  • Luck and patience

Here we have the docker-compose.yml for the caddy service:

version: "3.7"
services:
  caddy:
    image: lucaslorentz/caddy-docker-proxy:ci-alpine
    ports:
      - 80:80
      - 443:443
    environment:
      - CADDY_INGRESS_NETWORKS=caddy
    networks:
      - caddy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - caddy_data:/data
    restart: unless-stopped
   
networks:
  caddy:
    external: true
    
volumes:
  caddy_data: {}

Next is the docker-compose.yml file for the portainer service - sure these could probably be in the same file, but I kept these self contained:

version: "3"
services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    security_opt:
      - no-new-privileges: true
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./portainer_data:/data
    ports:
      - 9443:9443
      - 9000:9000
    networks:
      - caddy
    labels:
      caddy: YOUR_FQDN_HERE
      caddy.reverse_proxy: "{{upstreams 9000}}"
      
networks:
  caddy:
    external: true

Make sure to replace the YOUR_FQDN_HERE from the caddy line with the URI of where you want the service to live.

Next up is the what we'll call docker-compose.yml from the portainer stack details for Gitlab:

version: '3.6'

services:
  web:
    image: 'gitlab/gitlab-ee:latest'
    restart: unless-stopped
    hostname: YOUR_GITLAB_FQDM
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://GIT.FQDM.HERE'
        nginx['listen_port'] = 8929
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        # Other gitlab omnibus configs go here, one per line
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "taylor.mxrouting.net"
        gitlab_rails['smtp_port'] = 587
        gitlab_rails['smtp_user_name'] = "gitlab@YOUR.EMAIL.HOST"
        gitlab_rails['smtp_password'] = "YOUR_SMTP_PASSWORD"
        gitlab_rails['smtp_domain'] = "YOUR_SMTP_DOMAIN"
        gitlab_rails['smtp_authentication'] = "login"
        gitlab_rails['smtp_enable_starttls_auto'] = true
        # gitlab_rails['smtp_openssl_verify_mode'] = 'peer'

        gitlab_rails['gitlab_email_from'] = 'gitlab@YOUR.EMAIL.HOST'
        gitlab_rails['gitlab_email_reply_to'] = 'noreply@YOUR.EMAIL.HOST'
        gitlab_rails['incoming_email_enabled'] = true
        gitlab_rails['incoming_email_address'] = "gitlab-incoming+%{key}@YOUR.EMAIL.HOST"
        gitlab_rails['incoming_email_email'] = "gitlab-incoming@YOUR.EMAIL.HOST"
        gitlab_rails['incoming_email_password'] = "YOUR_INCOMING_EMAIL_PASSWORD"
        gitlab_rails['incoming_email_host'] = "taylor.mxrouting.net"
        gitlab_rails['incoming_email_port'] = 993
        gitlab_rails['incoming_email_ssl'] = true
        gitlab_rails['incoming_email_start_tls'] = false
        gitlab_rails['incoming_email_mailbox_name'] = "inbox"
        gitlab_rails['incoming_email_idle_timeout'] = 60
        gitlab_rails['incoming_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log"
        gitlab_rails['incoming_email_expunge_deleted'] = true
        gitlab_rails['incoming_email_delivery_method'] = "sidekiq"
        gitlab_rails['service_desk_email_delivery_method'] = "sidekiq"
    ports:
      # - '8282:80'
      # - '8443:443'
      - '8929:8929'
      - '2222:22'
    volumes:
      - 'gitlab_volume_config:/etc/gitlab'
      - 'gitlab_volume_logs:/var/log/gitlab'
      - 'gitlab_volume_data:/var/opt/gitlab'
    shm_size: '256m'
    networks:
      - caddy
    labels:
      caddy: GIT_FQDM_HERE
      caddy.reverse_proxy: "{{upstreams 8929}}"
      
volumes:
  gitlab_volume_config:
  gitlab_volume_logs:
  gitlab_volume_data:
  
networks:
  caddy:
    external: true

You'll want to ensure that whatever changes need to be made are done so, such as the email settings and passwords. Some of the major pain points that I found were in the external_url setting: the internal nginx was always pulling the published port number for its own use in everything, up to and including throwing it into email and page templates. Once that was removed and replaced by the separate nginx port setting things are much better.

I also noticed that after an upgrade, incoming email stopped getting pulled, which was fixed with the following information: https://forum.gitlab.com/t/all-incoming-mail-stopped-working-after-update-to-v15-3-1-last-night/74026/10

As I'm a glutton for punishment, how about some Xwiki just for fun:

version: '2'
networks:
  caddy:
    external: true
  bridge:
    driver: bridge
services:
  web:
    image: "xwiki:lts-postgres-tomcat"
    container_name: xwiki-postgres-tomcat-web
    labels:
      caddy: WIKI_FQDN_HERE
      caddy.reverse_proxy: "{{upstreams 8080}}"
    depends_on:
      - db
    ports:
      - "8888:8080"
    environment:
      - DB_USER=DB_USER_HERE
      - DB_PASSWORD=DB_USER_PASSWORD_HERE
      - DB_HOST=xwiki-postgres-db
    volumes:
      - xwiki_data:/usr/local/xwiki
    networks:
      - caddy
      - bridge
  db:
    image: "postgres:13"
    container_name: xwiki-postgres-db
    volumes:
      - xwiki_postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_ROOT_PASSWORD=POSTGRES_ROOT_PASSWORD_HERE
      - POSTGRES_PASSWORD=POSTGRES_USER_PASSWORD_HERE
      - POSTGRES_USER=POSTGRES_USER_HERE
      - POSTGRES_DB=POSTGRES_DATABASE_HERE
      - POSTGRES_INITDB_ARGS="--encoding=UTF8"
    networks:
      - bridge
volumes:
  xwiki_postgres_data: {}
  xwiki_data: {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment