{"id":20329278,"url":"https://github.com/whisperpine/gitlab-compose","last_synced_at":"2026-04-29T19:31:28.505Z","repository":{"id":214753406,"uuid":"737276431","full_name":"whisperpine/gitlab-compose","owner":"whisperpine","description":"Self-host GitLab in your office and access it everywhere.","archived":false,"fork":false,"pushed_at":"2026-04-09T18:26:29.000Z","size":239,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-09T20:23:19.315Z","etag":null,"topics":["aws-s3","aws-ses","cloudflare-tunnels","deployment","doker-compose","gitlab","opentofu","self-host","terraform"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/whisperpine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-30T12:52:12.000Z","updated_at":"2026-04-09T18:26:33.000Z","dependencies_parsed_at":"2024-01-15T11:07:37.149Z","dependency_job_id":"7729b2aa-ede1-4448-b0ae-fb7ac7128a44","html_url":"https://github.com/whisperpine/gitlab-compose","commit_stats":null,"previous_names":["whisperpine/gitlab-compose"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/whisperpine/gitlab-compose","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperpine%2Fgitlab-compose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperpine%2Fgitlab-compose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperpine%2Fgitlab-compose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperpine%2Fgitlab-compose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/whisperpine","download_url":"https://codeload.github.com/whisperpine/gitlab-compose/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whisperpine%2Fgitlab-compose/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32440842,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T18:12:22.909Z","status":"ssl_error","status_checked_at":"2026-04-29T18:11:33.322Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-s3","aws-ses","cloudflare-tunnels","deployment","doker-compose","gitlab","opentofu","self-host","terraform"],"created_at":"2024-11-14T20:09:55.329Z","updated_at":"2026-04-29T19:31:28.493Z","avatar_url":"https://github.com/whisperpine.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitLab Docker Compose\n\n[![GitLab](https://img.shields.io/badge/GitLab-%23FC6D26?logo=gitlab\u0026logoColor=white)](https://about.gitlab.com/)\n[![GitHub License](https://img.shields.io/github/license/whisperpine/gitlab-compose)](https://github.com/whisperpine/gitlab-compose/blob/main/LICENSE)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/whisperpine/gitlab-compose/checks.yml?logo=github\u0026label=checks)](https://github.com/whisperpine/gitlab-compose/actions/workflows/checks.yml)\n[![GitHub deployments](https://img.shields.io/github/deployments/whisperpine/gitlab-compose/infra-default?label=deployment\u0026\u0026logo=github)](https://github.com/whisperpine/gitlab-compose/deployments/infra-default)\n[![GitHub Release](https://img.shields.io/github/v/release/whisperpine/gitlab-compose?logo=github)](https://github.com/whisperpine/gitlab-compose/releases)\n\nSelf-host [GitLab](https://about.gitlab.com/) in your office and access it everywhere.\n\nIf you want to self-host GitLab in your office or on-premise data center, and\naccess from anywhere, with zero cloud cost, you come to the right place. While\nthis repository is tailored for my use cases, it may help you get started.\n\n```mermaid\nflowchart LR\n  pub(\"Access from WAN\")\n  private(\"Access from LAN\")\n  cf(\"Cloudflare edge nodes\")\n  s3(\"AWS S3\")\n  ses(\"AWS SES\")\n\n  pub -.-\u003e cf\n  cf ---|tunnel| cloudflared\n\n  subgraph Docker Compose\n    cloudflared(\"Cloudflared\")\n    gitlab(\"GitLab\"):::red_stroke\n    cloudflared --- gitlab\n  end\n\n  private -...-\u003e gitlab\n\n  gitlab -.-|auto backup| s3\n  gitlab -.-|email service| ses\n\n  classDef red_stroke stroke: #f66\n```\n\n## Background\n\nWhen developing game projects with large binary files (e.g., textures, audio\nclips) ranging from several to tens of GBs, [Git LFS](https://git-lfs.com/) is\nthe ideal solution for tracking these files. Our team heavily relied on CI/CD\npipelines, which generated significant network traffic between the repository\nand CI runner. These pipelines also required computational resources due to long\ncompile times, making a self-hosted CI runner on a powerful device preferable.\nTherefore hosting both the Git server and CI runner within the same subnet\nreduces network latency and financial costs.\n\nUsing GitHub was not ideal due to expensive LFS storage and outbound bandwidth\n(refer to [GitHub LFS Pricing](https://docs.github.com/en/billing/concepts/product-billing/git-lfs)),\nas well as prolonged CI/CD times caused by cloning repositories to a device with\na self-hosted GitHub runner.\n\nTo address this, I came up with this solution: a self-hosted GitLab server and\nGitLab runner in our office, within the same subnet, while maintaining global\naccessibility using Cloudflare Tunnels.\n\n## Get Started\n\n- Setup infrastructure by [Terraform](\u003chttps://github.com/hashicorp/terraform\u003e)\n  or [OpenTofu](https://github.com/opentofu/opentofu) (see [infra/README.md](./infra/README.md)).\n- Config environment variables in `.env` file (refer to [example.env](./example.env)).\n- Setup docker ipvlan network by [./scripts/setup-network.sh](./scripts/setup-network.sh).\n- Run `docker compose up -d` to spin up services.\n\n## Cloud Services\n\nWhile it's easy to spin up a standalone GitLab instance via docker compose, it's\nessential to manage dependent cloud services properly, to make it\nproduction-ready. These services are managed by OpenTofu in this repo.\n\n- [AWS S3](https://aws.amazon.com/s3/):\n  provides an S3 bucket used by GitLab to periodically upload backups.\n- [AWS SES](https://aws.amazon.com/ses/):\n  provides an SMTP server which is used by GitLab to send emails.\n- [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/):\n  provides a secure way to host without a public IP address.\n\n## File Notes\n\n- [gitlab.rb](./gitlab.rb) is duplicated from */opt/gitlab/etc/gitlab.rb.template*\n(version v18.1.2-ee), as a handy reference.\n- [setup-network.sh](./scripts/setup-network.sh) demonstrates how to create a\n  docker network with the\n  [ipvlan](https://docs.docker.com/engine/network/drivers/ipvlan/) driver type.\n- [example.env](./example.env) is a template which is expected to be copied as\nthe `.env` file and edited further.\n\n## Feature Flags\n\nOn self-hosted GitLab, you may choose to enable or disable certain [feature flags](https://docs.gitlab.com/ee/user/feature_flags).\nRefer to GitLab Docs:\n[Enable and disable GitLab features deployed behind feature flags](https://docs.gitlab.com/ee/administration/feature_flags).\nHere's a quick note:\n\n```sh\n# enter interactive tty of gitlab container.\ndocker compose exec -it gitlab bash\n# enter gitlab-rails console (this command may take several minutes).\nsudo gitlab-rails console\n```\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\u003csummary\u003eCommonly used commands in gitlab-rails console\u003c/summary\u003e\n\n```ruby\n# enable \"example_feature\" feature flag.\nFeature.enable(:example_feature)\n# check if \"example_feature\" is enabled.\nFeature.enabled?(:example_feature)\n# disable \"example_feature\" feature flag.\nFeature.disable(:example_feature)\n# unset \"example_feature\" so that GitLab falls back to the default.\nFeature.remove(:example_feature)\n```\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## Admin Settings\n\nDisable [event data tracking](https://docs.gitlab.com/administration/settings/event_data/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhisperpine%2Fgitlab-compose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhisperpine%2Fgitlab-compose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhisperpine%2Fgitlab-compose/lists"}