0%

如何部署私有Docker Registry

How To Set Up a Private Docker Registry

Docker Registry是一个管理Docker容器镜像存储和传递的应用程序。注册表集中了容器镜像,减少了开发人员的构建时间。

Docker Hub是一个免费的公共注册表,可以托管您的自定义Docker镜像,但有些情况下您可能不希望您的镜像公开可用。镜像通常包含运行应用程序所需的所有代码,因此在使用专有软件时,使用私有注册表可能更可取。

1. 安装和配置Docker Registry

新建docker-registry目录,存储images

1
2
3
4
5
mkdir ~/docker-registry
cd ~/docker-registry
mkdir data
# 创建 docker-compose文件
vim docker-compose.yml

~/docker-registry/docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
version: '3'

services:
registry:
image: registry:latest
ports:
- "5000:5000"
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
volumes:
- ./data:/data

将第一个服务命名为 registry ,并将其图像设置为 registry ,使用最新版本。然后,在 ports 下,将主机上的端口 5000 映射到容器的端口 5000 ,这将允许您向服务器的端口 5000 发送请求,并将请求转发到注册表。

environment 部分,将 REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY 变量设置为 /data ,指定它应该存储数据路径。然后,在 volumes 部分,您将主机文件系统上的 /data 目录映射到容器中的 /data ,它充当一个透传。实际上,数据将存储在主机上。

1
2
# 启动
docker-compose up

在这一步中,已经创建了一个Docker Compose配置,该配置启动了一个在端口 5000 上监听的Docker Registry。在接下来的步骤中,您将在您的域名上公开它并设置身份验证。

2. 设置NGINX转发

这里使用Ubuntu22.04设置,不同的发行版本配置路径会有不同

1
sudo vim /etc/nginx/sites-available/your_domain.conf

Nginx 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
server_name xxxxx.com;

location / {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}

proxy_pass http://localhost:5000;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html;
}

# listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/nginx/cert/xxxx.cert.pem;
ssl_certificate_key /etc/nginx/cert/xxxxxx.key.pem;
}

注:这里配置了HTTPS的证书,需要自己进行签名

重启NGINX

1
sudo systemctl restart nginx

访问 https://your_domain/v2 并返回了一个 {} 的响应。代码 200 表示容器成功处理了该请求,说明NGINX转发已经配置成功

3.设置身份验证(可选)

若暴露在公网中,建议增加身份验证

Nginx允许您为其管理的站点设置HTTP身份验证,您可以使用它来限制对Docker Registry的访问。为了实现这一点,您将创建一个带有 htpasswd 的身份验证文件,并向其中添加将被接受的用户名和密码组合。这个过程将启用对您的注册表的身份验证。

1
2
3
4
5
6
7
8
9
10
# 安装apache2-utils
sudo apt install apache2-utils -y
# 在 ~/docker-registry/auth 下存储带有凭据的身份验证文件。
mkdir ~/docker-registry/auth
cd ~/docker-registry/auth
# 创建第一个用户,将 username 替换为您想要使用的用户名。使用 -B 标志指示使用 bcrypt 算法,这是Docker所要求的。
htpasswd -Bc registry.password username

## 注意:要添加更多用户,请重新运行上一个命令,不包括 -c, -c 创建一个新文件,因此删除它将更新现有文件。
htpasswd -B registry.password username

编辑 docker-compose 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3'

services:
registry:
image: registry:latest
ports:
- "5000:5000"
environment:
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry
REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
volumes:
- ./auth:/auth
- ./data:/data

指定使用HTTP身份验证并提供创建的文件路径的环境变量。对于 REGISTRY_AUTH ,您指定了 htpasswd 作为其值,这是您正在使用的身份验证方案,并将 REGISTRY_AUTH_HTPASSWD_PATH 设置为身份验证文件的路径。 REGISTRY_AUTH_HTPASSWD_REALM 表示 htpasswd 领域的名称。

然后重新运行

1
docker-compose up

4. 设置自动启动

通过指示Docker Compose始终保持运行状态,确保注册表容器在每次系统启动或崩溃后都会启动。

1
vim docker-compose.yml
1
2
3
4
...
registry:
restart: always
...

restart 设置为 always 可以确保容器在重新启动后仍然存在。完成后,请保存并关闭文件。

现在可以通过传入 -d 来将您的注册表作为后台进程启动。

1
docker-compose up -d

5. 设置NGINX上传文件的大小

在将image推送到register之前,需要确保register能够处理大文件上传。Nginx中文件上传的默认大小限制是 1m ,这对于Docker image来说远远不够。为了提高它,修改位于 /etc/nginx/nginx.conf 的主Nginx配置文件。

1
sudo vim /etc/nginx/nginx.conf

增加

1
2
3
4
5
6
...
http {
client_max_body_size 16384m;
...
}
...
1
2
# 重新启动
sudo systemctl restart nginx

在这一步中,您更新了Nginx允许的文件大小。现在您可以将大型image上传到Docker Registry,而不会被Nginx阻止传输或出现错误。

6. 发布image到Docker register

我们将使用Docker Hub中的Ubuntu image进行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
docker run -t -i ubuntu /bin/bash
# -i 和 -t 标志为您提供对容器的交互式shell访问。


# 一旦进入,通过运行以下命令创建一个名为 SUCCESS 的文件:
touch /SUCCESS
# 退出容器的Shell
exit


# 从刚刚自定义的容器中创建一个新图像:
docker commit $(docker ps -lq) test-image

# 登录到你的私有Docker register(第三步设置的用户名密码,如果没有设置,则可忽略这步)
docker login https://your_domain
# 登录成功会输出:Login Succeeded

# 重命名Image
docker tag test-image your_domain/test-image

# 推送到image
docker push your_domain/test-image

7. 从register中拉取image

现在你已经将图像推送到了你的私有仓库,你将尝试从中拉取。

1
2
3
4
5
# 登录
docker login https://your_domain

# pull
docker pull your_domain/test-image

总结

在教程中,设置自己的私有Docker注册表并将Docker镜像发布到其中。如介绍中所提到的,您还可以使用TravisCI或类似的CI工具来自动将镜像推送到私有注册表。

通过在工作流程中利用Docker容器,您可以确保包含代码的镜像在任何机器上(无论是在生产环境还是开发环境中)都会产生相同的行为。有关编写Docker文件的更多信息,您可以访问官方文档中的最佳实践部分。