跳过正文

在AWS自建 Docker 私有仓库完整指南

· loading · loading ·
lixxix
作者
lixxix
关注科技,编程改变生活!

前言
#

在 AWS EC2 上部署 Docker 镜像有多种方式,当你有 SSL 证书并希望通过 Nginx 反向代理实现 HTTPS 访问和用户认证时,自建 Docker Registry 是最节省成本且完全自主的方案。本文记录从镜像部署到生产拉取的全流程。

一、部署 Registry 容器
#

Docker 官方提供了精简的 registry 镜像,直接运行即可:

docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name my-registry \
  -v /mnt/registry:/var/lib/registry \
  registry:2

参数说明:

  • -p 5000:5000:将主机 5000 端口映射到容器
  • -v /mnt/registry:/var/lib/registry重要,将镜像数据持久化到宿主机磁盘
  • --restart=always:服务器重启后自动启动

二、安装并配置 Nginx 反向代理
#

2.1 准备 SSL 证书
#

将 SSL 证书和私钥上传到服务器(以 docker.nasuyfw.com 为例):

# 创建证书目录
sudo mkdir -p /etc/nginx/certs

# 上传并命名证书文件
# /etc/nginx/certs/registry.crt
# /etc/nginx/certs/registry.key

2.2 创建 Nginx 配置文件
#

sudo vi /etc/nginx/conf.d/docker-registry.conf

写入以下内容:

upstream docker-registry {
    server 127.0.0.1:5000;
}

server {
    listen 443 ssl;
    server_name docker.nasuyfw.com;

    # SSL 证书路径
    ssl_certificate /etc/nginx/certs/registry.crt;
    ssl_certificate_key /etc/nginx/certs/registry.key;

    # SSL 优化配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 允许大文件上传(Docker 镜像通常很大)
    client_max_body_size 2000M;
    chunked_transfer_encoding on;

    location /v2/ {
        # 强制 Docker 客户端使用 HTTPS
        if ($http_user_agent ~* (docker)) {
            add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
        }

        proxy_pass                          http://docker-registry;
        proxy_set_header  Host              $http_host;
        proxy_set_header  X-Real-IP         $remote_addr;
        proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto $scheme;
        proxy_read_timeout                  900;
    }
}

注意:如果使用 HTTP 强制跳转 HTTPS,需另外配置 80 端口的 server 块。

2.3 处理 SELinux 问题(Amazon Linux 2023)
#

如果 Nginx 报 502 Bad Gateway,执行:

sudo setsebool -P httpd_can_network_connect 1

三、配置用户认证(Basic Auth)
#

3.1 安装 htpasswd 工具
#

sudo dnf install httpd-tools -y

3.2 创建用户和密码
#

sudo htpasswd -c /etc/nginx/.htpasswd admin
# 输入并确认密码

3.3 在 Nginx 配置中启用认证
#

location /v2/ { 块内添加:

auth_basic "Registry Realm";
auth_basic_user_file /etc/nginx/.htpasswd;

3.4 重启 Nginx
#

sudo nginx -t && sudo systemctl restart nginx

四、上传镜像到私有仓库
#

4.1 登录私有仓库
#

docker login docker.nasuyfw.com
# 输入用户名和密码

4.2 给镜像打标签
#

docker tag jiligame-jili:latest docker.nasuyfw.com/jiligame-jili:latest

4.3 推送到服务器
#

docker push docker.nasuyfw.com/jiligame-jili:latest

4.4 验证上传结果
#

curl -u admin:password https://docker.nasuyfw.com/v2/_catalog

返回 {"repositories":["jiligame-jili"]} 即表示成功。

五、拉取并运行镜像
#

在目标服务器上:

5.1 登录并拉取
#

docker login docker.nasuyfw.com
docker pull docker.nasuyfw.com/jiligame-jili:latest

5.2 运行容器
#

docker run -d \
  --name my-jili-game \
  -p 80:80 \
  --restart unless-stopped \
  docker.nasuyfw.com/jiligame-jili:latest

参数说明:

  • -d:后台运行
  • --restart unless-stopped:服务器重启后自动拉起

六、日常维护
#

查看容器状态
#

docker ps

查看实时日志
#

docker logs -f my-jili-game

更新镜像
#

docker pull docker.nasuyfw.com/jiligame-jili:latest
docker rm -f my-jili-game
docker run -d --name my-jili-game -p 80:80 --restart unless-stopped docker.nasuyfw.com/jiligame-jili:latest

七、常见问题排查
#

问题原因解决方案
413 Request Entity Too LargeNginx 上传大小限制配置 client_max_body_size 2000M
x509: certificate signed by unknown authority自签名证书未信任将 CRT 文件拷贝到 /etc/docker/certs.d/yourdomain.com/ca.crt
502 Bad GatewayRegistry 容器未启动或 SELinux 阻止检查 docker ps 并执行 setsebool

八、进阶:使用 Docker Compose 管理
#

创建 docker-compose.yml

services:
  registry:
    image: registry:2
    ports:
      - "5000:5000"
    volumes:
      - /mnt/registry:/var/lib/registry
    restart: always

更新只需运行:

docker-compose pull && docker-compose up -d

完整工作流总结:

  1. 开发环境docker build -> docker tag -> docker push
  2. 私有仓库:Nginx 接收 HTTPS 请求 -> 验证密码 -> 转发给 Registry 存储
  3. 生产环境docker pull -> docker run