惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
S
SegmentFault 最新的问题
量子位
有赞技术团队
有赞技术团队
V
V2EX
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Jina AI
Jina AI
C
Check Point Blog
G
Google Developers Blog
博客园 - 叶小钗
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园_首页
T
Tailwind CSS Blog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
U
Unit 42

Superuser

OpenDev’s Quiet 15-Year Marathon – Superuser We Made an OpenStack Cloud Tell Its Own Story – Superuser Do the invisible security work, too – Superuser ALASCA/SCS Sovereign Cloud for International Telecommunication Union (ITU) – Superuser How the University at Buffalo Modernized Its Research Cloud with OpenStack – Superuser A Hybrid Private Cloud as an AI Factory – Superuser How India’s Payment Backbone Runs on Open Source – Superuser What AI Builders Can Learn From a Decade of Open Source CI – Superuser How Pinaka ZTi Builds Sovereign Clouds Governments Can Actually Trust – Superuser KDDI’s Private Cloud Supporting Communications – Superuser When Vietnam’s Cloud Infrastructure Is No Longer the Bottleneck – Superuser Sovereign AI Cloud – Superuser How France’s National Railway Runs on Open Source – Superuser Why Digital Sovereignty Depends on Invisible Labor – Superuser Ongoing Development and Next Steps for DOCOMO and Tacker – Superuser Why AI Agents Need Stronger Sandboxing and What the Kata Containers Community Is Doing About It – Superuser A Guide to Manila Security and Terraform Integration – Superuser A Strategic Growth Opportunity for Open Infrastructure – Superuser NTT DOCOMO’s Tacker Activity – Superuser NTT DOCOMO’s Journey of Virtualization for Mobile Networks – Superuser How Rapifuzz CyberKshetra Built a Scalable Cyber Range on OpenStack (and Cut Costs by 60%) Integration of the Octavia module (Load Balancer as a Service) in an OpenStack Cloud Environment – Part 2 – Superuser OpenStack Case Study: CloudVPS – Superuser The 10th China Open Source Hackathon Recap: Projects, Talks, and More – Superuser Inside CERN’s Open Data portal – Superuser Taking the OpenStack ops manuals to the next level – Superuser Making your first contact with OpenStack – Superuser How tech giant Tencent uses OpenStack – Superuser Managing port level security in OpenStack – Superuser Using Ansible 2.0 to launch a server on OpenStack – Superuser
From GitLab SaaS to Full Sovereignty: Hosting GitLab in a...
EL BOUKHARI Youcef · 2026-09-01 · via Superuser

The Initial Paradox :

When I started building my platform engineering setup on OpenStack, one detail bothered me. I chose OpenStack specifically for sovereignty: keeping my data and processing within a perimeter I control.

Yet, my CI/CD relied on GitLab.com a SaaS service hosted elsewhere.

The question arose: where does my code actually go? My repositories, pipeline secrets, artifacts, infrastructure state… all of this lived on an external platform. I had a sovereign private cloud, and on top of it, a non-sovereign entry point.

This article shares how I bridged that gap and above all, what I learned along the way about what “sovereign” really means.

Sovereignty Is Not Binary: Execution vs. Control

The first lesson was conceptual. I was already using a self-hosted GitLab Runner within my OpenStack tenant, thinking I had solved the issue. That was true… halfway.

Two planes must be distinguished:

  • The execution plane: where the code runs. With a runner in my tenant, my CI jobs run locally. Code is cloned, built, and tested within my perimeter. That part was sovereign.

  • The control plane: where the data lives. Repositories, Git history, CI variables (passwords, tokens), artifacts, logs, Terraform state… all of this remained on GitLab.com.

In other words, my execution was sovereign, but my control was not. The entry point of my entire system GitLab itself was external. If GitLab.com suffered an outage, a legal constraint, or a leak, my repositories and secrets would be affected. A sovereign runner only protects what happens during the job, not what is stored around it.

Why does this matter for a setup like mine? Because the control plane is where the keys are. My repositories don’t just hold application code — they hold Terraform state describing my entire infrastructure, CI variables containing cloud credentials, and the pipeline definitions that can create or destroy resources in my tenant. An external platform holding all of that means a single ToS change, account suspension, regional outage, or credential leak on their side becomes an incident on mine. I wasn’t trying to build something GitLab.com couldn’t handle; I was trying to remove the assumption that a third party would always be there, always be reachable, and always be under the same jurisdiction as my data.

To take the logic all the way, I needed to bring the control plane back: hosting GitLab entirely within my OpenStack cloud.

The Foundation: Preparing the OpenStack Environment :

Before installing GitLab, the infrastructure foundation must be robust. I provisioned an Ubuntu VM within my OpenStack tenant, ensuring it has the necessary network connectivity to reach the repositories for the Omnibus package installation.

To achieve this, I attached a Floating IP (FIP) to the instance. This allows the VM to communicate with the outside world while maintaining the ability to route traffic to and from my local environment.

I verified the network configuration with a simple ping test to ensure the instance could reach external mirrors, confirming that the egress traffic was correctly routed through the OpenStack network.

For this specific instance, we used these resources in terms of RAM and CPU to handle the entire creation process.

With network connectivity confirmed and the instance reachable, the infrastructure was ready for the GitLab installation.

Bringing the Control Plane Home: GitLab in the Tenant

I provisioned an Ubuntu VM via OpenStack (Nova for compute, Neutron for networking, Glance for images), then installed GitLab Omnibus the all-in-one package bundling Nginx, PostgreSQL, Redis, and Sidekiq.

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash

sudo EXTERNAL_URL="http://10.10.10.127" apt-get install -y gitlab-ee

First access used the generated root password, followed by essential security settings: disabling open registration and forcing private project visibility.

On a sovereign instance, no one should be able to create an account without approval.

Barbican: The Sovereign Brick for TLS

This is where OpenStack integration proves its value. Rather than leaving a TLS certificate lying around in a file, I stored it in Barbican, OpenStack’s secrets management service encrypted, with access control via Keystone.

openstack secret store --name 'gitlab-tls-crt' \
--secret-type 'opaque' --payload-content-type 'text/plain' \
--payload "$(cat gitlab.crt)"

openstack secret store --name 'gitlab-tls-key' \
--secret-type 'opaque' --payload-content-type 'text/plain' \
--payload "$(cat gitlab.key)"

As you can see, the certificate and the key have been created and securely stored in Barbican as well.

The certificate now lives in a vault managed by OpenStack, not in a stray file. I then enabled HTTPS on the GitLab side by pointing Nginx to this certificate and changing external_url to https://

A sudo gitlab-ctl reconfigure later, GitLab responded via HTTPS.

Closing the Loop: A 100% Sovereign Runner and Pipeline

Before registering the runner via the command line, it must be defined within the GitLab instance to generate the necessary authentication token.

  • Navigate to the Runner settings: In your GitLab project (or at the instance level for global access), go to Settings > CI/CD > Runners.
  • Create a new Runner: Click on the “New project runner” button.
  • Configure the platform: Select the operating system (e.g., Linux) and enter optional tags. Using the tag sovereign is highly recommended to ensure your jobs are strictly routed to your local OpenStack infrastructure.
  • Get the Token: After clicking “Create runner,” GitLab will display a unique registration token.

 

This token is the “handshake” secret that allows your local VM to securely authenticate with your sovereign GitLab instance.

Once you have this token, you can proceed to the registration command on your VM and before running the registration command, we prepare the local certificate authority by creating the certificate directory and copying GitLab’s self-signed TLS certificate into it.

Then, the gitlab-runner register command links the runner to our internal instance using the non-interactive mode. Key parameters include the Docker executor (–executor docker), host networking (–docker-network-mode host), the sovereign tag for job routing, and the TLS CA file path (–tls-ca-file) to ensure secure communication with our HTTPS-enabled GitLab server.

To make sure that the GitLab Runner was created successfully, we executed the following commands:

Once registered, a minimal .gitlab-ci.yml validated the loop:

As you can see, the job was executed successfully as expected on our GitLab Runner.

Key Takeaway: Sovereignty Is a Spectrum

The biggest lesson from this project is that there is no “sovereign / non-sovereign” toggle switch. There are levels:

All-SaaS (zero sovereignty).

– Self-hosted runners (sovereign execution, external control).
– Self-managed GitLab (sovereign control and execution).
– Beyond: internal object storage, private CA, high availability…
– Each level has a cost in resources, maintenance, and complexity. Moving from level 2 to level 3, as I did, brings true control plane sovereignty, but also hands me the responsibility for backups, updates, and GitLab        availability. What GitLab.com used to do for me, I now must do myself.

The right question is therefore not “am I sovereign?” but “what level of sovereignty does my context require, and am I willing to bear the cost?”

For my part, running that first pipeline entirely within my OpenStack cloud was worth every hour of debugging. And if you are undertaking a similar journey, I would be curious to exchange thoughts on your own trade-offs.

Thank you for reading. Feel free to share your feedback or questions.

Tags: ,

  • Author
  • Recent Posts