Skip to content

Commit f3a53a4

Browse files
authored
Container registry (#122)
* Added docs to setup local container registry * Added reasoning for local registry
1 parent 31a8ca3 commit f3a53a4

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
---
2+
title: "Container Registry"
3+
description: "A description on how to run a local container registry with GMT"
4+
date: 2025-06-26T01:49:15+00:00
5+
weight: 1009
6+
---
7+
8+
GMT does **not** come with a container registry bundled. But since it builds on *docker* it can benefit from it's capability to query a private container registry.
9+
10+
Here we just want to show you the steps we took to get it running. Please consult the manuals of the respective tool vendors for configuration details
11+
12+
## Why would you set up a container registry
13+
14+
GMT will download images on measurement and keep them in the cache by default. If you just measure software inside their containers this usually poses no issue.
15+
But if you also want to caputre and evaluate host level metrics you will notice that over time the disk will fill up with images.
16+
17+
To always have a clean system you can instruct GMT to delete images on every run and pull images fresh. To not incur the costly network traffic every time you can pull these images only from the local network, effectively centralizing the location where images are kept.
18+
19+
If you run GMT in cluster mode you will then benefit from having the machines always with a clean file sytem and pulling from a central registry that keeps the images cached.
20+
21+
## Container Registry
22+
23+
We choose [registry](https://hub.docker.com/_/registry) which is the *CNCF* supported and most used library. It comes with a reference
24+
implementation that is suffcient for local or setups behind NATs.
25+
26+
Our compose file for the registry:
27+
28+
```yml
29+
services:
30+
registry:
31+
image: registry:3
32+
container_name: registry
33+
restart: always
34+
# ports: # do not make available directly to the outside
35+
# - "5001:5000" # internal, accessed via nginx
36+
environment:
37+
REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io
38+
REGISTRY_STORAGE_DELETE_ENABLED: "false"
39+
OTEL_TRACES_EXPORTER: none
40+
volumes:
41+
- /mnt/cluster_caches/docker:/var/lib/registry # we expect a storage system mounted on /mnt/cluster_caches/docker ... for instance an SSD
42+
43+
nginx:
44+
image: nginx:alpine
45+
container_name: registry-nginx
46+
restart: always
47+
ports:
48+
- "5000:5000"
49+
volumes:
50+
- ./nginx.conf:/etc/nginx/nginx.conf:ro
51+
```
52+
53+
Our *NGINX* file:
54+
55+
```nginx
56+
57+
worker_processes 1;
58+
59+
events { worker_connections 1024; }
60+
61+
http {
62+
server {
63+
listen 5000;
64+
65+
location /v2/ {
66+
limit_except GET HEAD { # we do not want to let people store images. Unsure if OPTIONS should also be allowed ...
67+
deny all;
68+
}
69+
proxy_pass http://registry:5000;
70+
}
71+
}
72+
}
73+
```
74+
75+
To have these servers always running we use a *systemd* service in `~/.config/systemd/user/container-registry.service`:
76+
77+
```bash
78+
[Unit]
79+
Description=Start Container Registry with NGINX
80+
81+
[Service]
82+
ExecStart=%h/container-registry/startup-docker.sh
83+
Type=simple
84+
Restart=on-failure
85+
RestartSec=5s
86+
StartLimitBurst=10
87+
StartLimitInterval=0
88+
89+
[Install]
90+
WantedBy=default.target]
91+
```
92+
93+
And a startup script in `~/container-registry/startup-docker.sh`:
94+
95+
```bash
96+
#!/bin/bash
97+
docker context use rootless
98+
docker compose -f ~/container-registry/compose.yml up -d
99+
```
100+
101+
Since the container registry we created is *insecure* (aka not using TLS) *docker* needs special allowance to use it.
102+
103+
In the `daemon.json`:
104+
105+
```json
106+
{
107+
...
108+
"insecure-registries": ["YOUR_IP:5000"],
109+
}
110+
```
111+
112+
### Security
113+
114+
It is highly recommended to have docker rootless active for the docker daemon on the machine that runs the registry!
115+
116+
See [Docker Rootless →]({{< relref "installation/installation-linux" >}}) how to do that.
117+
118+
TLS is only required if your registry is public accessible. If you have it local or behind a NAT with only
119+
controlled machines, it is not needed.
120+
121+
### Set your registry as default
122+
123+
In the `daemon.json`:
124+
125+
```json
126+
{
127+
...
128+
"registry-mirrors": ["http://YOUR_IP:5000"]
129+
}
130+
```
131+
132+
### Limit access to only your registry
133+
134+
The default *docker CLI* will always fail-over to Docker Hub.
135+
136+
If you do not want that you should block it on DNS level, which is the safest.
137+
138+
Add to `/etc/hosts`:
139+
140+
```log
141+
0.0.0.0 registry-1.docker.io auth.docker.io
142+
```
143+
144+
### Test your registry
145+
146+
Try with *curl*:
147+
148+
- `$ curl -s http://YOUR_IP:5000/v2/_catalog`

0 commit comments

Comments
 (0)