GitLab.com的GitLab CI如何访问NAT后Docker内的已注册本地Runner?
Great question! This is a super common point of confusion when setting up self-hosted runners, especially behind home routers with NAT. Let’s break down the mechanics in plain terms:
1. The Runner Initiates the Connection — GitLab Doesn’t Reach Out to You
The biggest key here is that GitLab never tries to find or connect to your runner directly. Instead, your runner is the one constantly checking in with GitLab’s API, asking: "Hey, do you have any jobs for me to run?"
When you registered your runner, you provided your GitLab project’s URL and registration token. This info gets saved in the runner’s config.toml file (inside the Docker container). Once the runner starts up, it uses this config to send regular HTTPS requests to GitLab.com’s API (usually every 3 seconds by default) to look for pending jobs.
2. Your NAT Router Handles IP Address Translation
Since your laptop is behind a NAT router with a private IP (like 192.168.x.x), the router acts as a middleman for all outgoing traffic:
- When your Docker runner sends a poll request to GitLab, the router replaces the source IP (your laptop’s private IP) with its own public IP, and assigns a temporary port to the connection.
- GitLab receives the request from your router’s public IP, processes it, and sends a response back to that public IP + temporary port.
- The router checks its internal connection table, matches the incoming response to the original runner request, and forwards it back to your laptop (and then to the Docker container).
GitLab never needs to know your private IP — it only ever communicates with your router’s public IP, and the router takes care of routing traffic to the correct device and process.
3. Docker Container Network Plays Nice With Your Laptop’s Network
Your runner running inside a Docker container uses the container’s default bridged network, which connects to your laptop’s network stack. This means:
- The container can access the internet through your laptop’s network interface, just like any other app on your machine.
- Outgoing requests from the container go through your laptop’s OS first, then through your NAT router — the router’s translation works exactly the same way as it does for your browser or other apps.
4. Tags Are Just for Job Matching (Not Networking)
Quick side note on the tags you set during registration: tags don’t affect the communication mechanism at all. They’re just a filter — when you define a job in your .gitlab-ci.yml with specific tags, only runners that have those matching tags will pick up and run that job. It’s a way to assign certain jobs to certain runners, not a networking feature.
To Sum It Up
The whole system works because your runner starts the conversation with GitLab, which bypasses NAT’s restriction on incoming connections. Your router handles the IP address translation, and Docker’s network setup lets the runner access the internet through your laptop. GitLab only ever sees your router’s public IP, but since the runner initiated the connection, the response can find its way back to you seamlessly.
内容的提问来源于stack exchange,提问作者Badr

