Most teams end up with their source code in one US cloud, their container images in another, and their user accounts in a third. Each one is a separate contract, a separate outage, and a separate answer to the question "who can read our code?"
We run the whole developer stack ourselves, in the EU, and we operate it as a service. Source control, CI/CD, the image registry and single sign-on come from one place - infrastructure we administer in Germany, not resold capacity from a hyperscaler.
What the stack is
- GitLab CE on a dedicated Hetzner VPS in Nuremberg, Debian 12, HTTPS with Let's Encrypt certificates renewed automatically.
- Container registry bundled with GitLab, reachable on port 5050 of the same host, with retention policies that keep deployed images alive and prune the rest.
- GitLab Runner with the Docker executor - every CI job runs in its own container.
- Keycloak as the identity provider, federating users from LDAP, with OIDC clients for each application.
- Outbound mail through our own mail server, so pipeline notifications and merge request e-mails don't route through a third-party sender.
No component here is exotic. That is the point: this is standard open-source software, run properly, by people who answer the phone.
Single sign-on that maps to your organisation
The interesting part is not that Keycloak exists. It is what the login actually knows about the person logging in.
Users live in LDAP. Keycloak federates them into a realm and maps LDAP groups into OIDC group claims. GitLab consumes those claims through the standard openid_connect provider with PKCE, so group membership decides access level - a member of the admin group is an administrator in GitLab, without anyone maintaining a second list of who is who.
The same realm issues tokens for everything else you run - wiki, dashboards, ERP, monitoring. Onboarding a developer becomes one LDAP entry and one group membership. Offboarding becomes one deletion, and it closes every door at once. That is the actual argument for SSO, and it only holds if one operator runs both the directory and the applications.
The registry is where operational discipline shows
A container registry fills up. Teams that build several times a day discover this the hard way, usually when a push fails at the worst possible moment. So the registry has a cleanup policy - and the policy has one invariant we do not break: cleanup must never delete an image that is currently deployed.
In practice that means the retention count has to cover every distinct tag that is simultaneously running, not just the newest few. For an application deployed once, keeping ten to twenty tags is plenty. For an application running ten divergent instances, the number has to cover all ten plus history. The more robust variant tags deployed images with a protected marker and keeps them regardless of the count.
One related detail that costs people a weekend: the pull secret in your cluster must be a durable read-only deploy token, not the ephemeral token from a CI job. The job token expires when the job ends, and the next fresh pull fails with a 401 that looks like a registry outage and isn't.
From commit to cluster
CI builds an image, tags it with the immutable commit SHA and pushes it to the registry. The deployment stage pulls the Helm chart and values from the infrastructure repository and upgrades the release. Application repositories do not carry their own copies of charts or manifests.
This is a deliberate constraint. Git is the source of truth for what is running; nothing gets changed by hand inside a running production system. When a cluster and a repository disagree, the repository wins at the next rollout - which is only a safe rule if nobody has been patching production directly in the meantime.
Who this is for
- Teams of five to fifty developers who need source control, CI and a registry, and don't want three separate SaaS contracts to manage them.
- Organisations under data residency requirements - GDPR, NIS2, DORA - where "where is our source code stored, and who can subpoena it?" has to have a documented answer.
- Open-source-first shops that already run Linux, Postgres and Keycloak, and want a provider who speaks the same stack.
- Companies replacing a hyperscaler devstack who want the migration operated, not just advised.
What we don't pretend
The deployment described here is single-node. It is sized and monitored for a team, not for a thousand-seat enterprise, and we do not currently offer a high-availability GitLab cluster. If your recovery time objective is measured in minutes rather than hours, say so early and we will tell you honestly whether we are the right fit.
Instances are monitored from outside: uptime probes, TLS certificate expiry alerts, disk and queue alerts. Keycloak's data is backed up to EU object storage with a nightly check that the backup actually exists; GitLab and the registry run on their own machine with daily block-level snapshots.
Getting started
Tell us how many developers, what you run today, and what has to keep working during the move. We come back with a migration plan and a quote - pricing depends on team size and how much of the existing setup we take over.
E-mail info@cybermindnet.eu or use the contact form.