Docker自建harbor私有仓库
一、安装 Docker 和 Docker Compose
# 安装 Docker
curl -fsSL https://get.docker.com | bash
# 启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
二、配置启动 Harbor
1. 下载 Harbor
cd /sg-work/harbor/
wget https://github.com/goharbor/harbor/releases/download/v2.12.1/harbor-online-installer-v2.12.1.tgz
tar --transform='s/harbor/harbor-offline/' -xvf harbor-offline-installer-v2.12.1.tgz
cd harbor-offline

下载 harbor-offline-installer-v2.12.3.tgz 记得开启代理!
2. 配置 Harbor
# 复制配置文件
cp harbor.yml.tmpl harbor.yml
# 查看配置文件的前50行
cat harbor.yml | head -n 30
# 修改Harbor 配置文件内容
sed -i 's/^hostname: .*/hostname: 192.168.1.20/' harbor.yml
sed -i '/^http:/,/^$/s/^ port: .*/ port: 8456/' harbor.yml
sed -i '/^https:/,/^[[:space:]]*#*[[:space:]]*strong_ssl_ciphers:/ s/^/#/' harbor.yml

3. 运行安装脚本
# 安装 Harbor
sudo ./install.sh
注意: 如果本地安装的有nginx ,替换 Harbor 中 Nginx 的名称或者是更改前置 nginx 的容器名称
sed -i "s/container_name: nginx/container_name: nginx-harbor/g" docker-compose.yml

4. 验证安装
# 检查容器状态
docker compose ps
# 查看日志
docker compose logs

访问:http://192.168.1.20:8456/
**用户名:**admin
**密码:**Harbor12345

5. 开启harbor的https
使用自签名证书(测试环境推荐):
# 在 harbor 挂映射的本地木 /data/ 下生成证书
mkdir -p /data/cert/ && cd /data/cert
# 生成CA私钥
openssl genrsa -out ca.key 4096
# 生成CA证书
openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=TestHarbor/CN=TestHarbor-CA"
# 生成服务器私钥
openssl genrsa -out harbor.key 4096
#生成证书签名请求 CN 替换成你的ip
openssl req -new -key harbor.key -out harbor.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=TestHarbor/CN=192.168.1.20"
# IP.1 替换成你的 IP
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
IP.1=192.168.1.20
IP.2=218.249.73.244
EOF
# 生成证书
openssl x509 -req -in harbor.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out harbor.crt -days 365 -extfile v3.ext

修改 harbor.yml 配置文件:
vim harbor.yml

停止Harbor:
docker compose down -v
重新加载配置:
./prepare
访问:http://192.168.1.20:8456/
**用户名:**admin
**密码:**Harbor12345

将证书添加到 Docker 信任目录:
# 创建 Docker 证书目录(注意包含端口号)
mkdir -p /etc/docker/certs.d/192.168.1.20:8443
# 复制证书到 Docker 信任目录
cp /data/cert/harbor.crt /etc/docker/certs.d/192.168.1.20:8443:8443/
# 重启 Docker 服务
sudo systemctl restart docker
控制台登录 Harbor:
docker login https://192.168.1.20:8443
docker login https://218.249.73.244:8443

如果有外网访问需求,配置外网 ip 后是直接可以访问 web 界面的,通过控制台使用外网IP 登录 Harbor, 就需要重新生成并配置证书:
#!/bin/bash
cd /sg-work/harbor/harbor-offline/
echo "=== 停止Harbor服务 ==="
docker-compose down
echo "=== 备份旧证书 ==="
if [ -f /data/cert/harbor.crt ]; then
mv harbor.crt harbor.crt.old.$(date +%Y%m%d_%H%M%S)
fi
if [ -f /data/cert/harbor.key ]; then
mv harbor.key harbor.key.old.$(date +%Y%m%d_%H%M%S)
fi
cd /data/cert/
echo "=== 创建新的证书配置文件 ==="
cat > harbor-cert.conf << 'EOF'
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = CN
ST = Beijing
L = Beijing
O = Harbor Registry
OU = IT Department
CN = 218.249.73.244
[v3_req]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = harbor.local
DNS.2 = localhost
DNS.3 = harbor
IP.1 = 192.168.1.20
IP.2 = 218.249.73.244
IP.3 = 127.0.0.1
EOF
echo "=== 生成新的私钥 ==="
openssl genrsa -out harbor.key 4096
echo "=== 生成证书签名请求 ==="
openssl req -new -key harbor.key -out harbor.csr -config harbor-cert.conf
echo "=== 生成自签名证书(包含SAN扩展) ==="
openssl x509 -req -days 365 -in harbor.csr -signkey harbor.key -out harbor.crt -extensions v3_req -extfile harbor-cert.conf
echo "=== 验证新证书的SAN字段 ==="
echo "Subject Alternative Name 内容:"
openssl x509 -in harbor.crt -text -noout | grep -A 5 "Subject Alternative Name"
echo ""
echo "=== 验证证书包含的IP地址 ==="
if openssl x509 -in harbor.crt -text -noout | grep -q "218.249.73.244"; then
echo "✓ 新证书包含外网IP 218.249.73.244"
else
echo "✗ 新证书不包含外网IP 218.249.73.244"
exit 1
fi
if openssl x509 -in harbor.crt -text -noout | grep -q "192.168.1.20"; then
echo "✓ 新证书包含内网IP 192.168.1.20"
else
echo "✗ 新证书不包含内网IP 192.168.1.20"
exit 1
fi
openssl s_client -connect 192.168.1.20:8443 -servername 192.168.1.20 -CAfile /data/cert/harbor.crt < /dev/null
openssl s_client -connect 218.249.73.244:8443 -servername 218.249.73.244 -CAfile /data/cert/harbor.crt < /dev/null
echo "=== 设置证书权限 ==="
chmod 600 harbor.key
chmod 644 harbor.crt
echo "=== 更新Docker证书信任 ==="
mkdir -p /etc/docker/certs.d/192.168.1.20:8443
mkdir -p /etc/docker/certs.d/218.249.73.244:8443
cp harbor.crt /etc/docker/certs.d/192.168.1.20:8443/ca.crt
cp harbor.crt /etc/docker/certs.d/218.249.73.244:8443/ca.crt
cd /sg-work/harbor/harbor-offline/
echo "=== 重新准备Harbor配置 ==="
./prepare
echo "=== 启动Harbor服务 ==="
docker-compose up -d
echo "=== 等待服务启动 ==="
sleep 30
echo "=== 验证Harbor服务状态 ==="
docker-compose ps
cd /data/cert/
echo "=== 清理临时文件 ==="
rm -f harbor.csr harbor-cert.conf
echo "证书重新生成完成!"
重要!!!! /etc/docker/certs.d/218.249.73.244:8443/ca.crt
下的证书名称必须是 ca.crt
。
配置 harbor.yml:
vim harbor.yml
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 218.249.73.244 # 配置成外网 ip
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 8456
# https related config
https:
# # https port for harbor, default is 443
port: 8443
# # The path of cert and key files for nginx
certificate: /data/cert/harbor.crt
private_key: /data/cert/harbor.key
测试登录:

四、配置前置代理 Nginx
1. 启动前置 Nginx
docker run -d \
--name sg-nginx --restart always \
-p 80:80 -p 443:443 -p 8786:8786 -p 8987:8987 -p 8457:8457 -p 8443:8443 \
-e "TZ=Asia/Shanghai" \
-v /sg-work/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /sg-work/nginx/conf.d:/etc/nginx/conf.d \
-v /sg-work/nginx/logs:/var/log/nginx \
-v /sg-work/nginx/certs:/etc/nginx/certs \
-v /sg-work/nginx/html:/usr/share/nginx/html \
nginx:alpine
-v /sg-work/nginx/nginx.conf:/etc/nginx/nginx.conf
- 使用 -v 参数挂载主机的 /sg-work/nginx/nginx.conf 文件到容器内的 /etc/nginx/nginx.conf 路径。这是 Nginx 的主配置文件,用于定义 Nginx 的核心配置。
-v /sg-work/nginx/conf.d:/etc/nginx/conf.d
- 将主机目录 /sg-work/nginx/conf.d 挂载到容器内的 /etc/nginx/conf.d 目录。通常 Nginx 的站点配置文件(如虚拟主机配置)存储在此目录。
-v /sg-work/nginx/logs:/var/log/nginx
- 将主机目录 /sg-work/nginx/logs 挂载到容器内的 /var/log/nginx 目录。Nginx 的日志文件(如 access.log 和 error.log)将存储在主机上的 /sg-work/nginx/logs 目录,便于持久化日志。
-v /sg-work/nginx/certs:/etc/nginx/certs
- 将主机目录 /sg-work/nginx/certs 挂载到容器内的 /etc/nginx/certs 目录。这通常用于存储 SSL/TLS 证书文件,以支持 HTTPS。
-v /sg-work/nginx/html:/usr/share/nginx/html
- 将主机目录 /sg-work/nginx/html 挂载到容器内的 /usr/share/nginx/html 目录。这是 Nginx 的默认静态文件目录,用于存放网页内容(如 HTML、CSS、JS 文件)。
nginx:alpine
- 指定容器使用的镜像为 nginx:alpine。alpine 是一个轻量级的 Linux 发行版,因此该镜像非常小巧,适合生产环境使用。
2. Nginx 配置
创建 harbor.conf ,然后将文件复制到/sg-work/nginx/conf.d 目下,重启 Nginx 使配置生效:
vim /sg-work/nginx/conf.d/harbor.conf
# 外网HTTPS访问 - 8457端口
server {
listen 8457 ssl;
server_name 218.249.73.244;
# SSL 证书配置
ssl_certificate /etc/nginx/certs/server.crt; # 自签名证书存放路径
ssl_certificate_key /etc/nginx/certs/server.key; # 自签名私钥存放路径
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 访问日志
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Harbor 主界面代理配置
location / {
proxy_pass http://192.168.1.20:8456;
proxy_set_header Host $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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 重要:传递原始请求信息
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Host $host:$server_port;
# 处理WebSocket升级(如果Harbor使用WebSocket)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲区设置
proxy_buffering off;
proxy_request_buffering off;
}
# Docker Registry API 代理配置
location /v2/ {
proxy_pass http://192.168.1.20:8456/v2/;
proxy_set_header Host $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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Registry特殊配置
proxy_set_header X-Original-URI $request_uri;
client_max_body_size 0;
chunked_transfer_encoding on;
}
}
# 内网HTTP访问重定向到HTTPS - 8456端口
server {
listen 8456;
server_name 218.249.73.244;
# 将所有HTTP请求重定向到HTTPS
return 301 https://$server_name:8457$request_uri;
}
# 内网直接访问支持 - 新增内网专用配置
server {
listen 8458; # 内网专用端口
server_name 192.168.1.20;
# 内网HTTP访问配置
location / {
proxy_pass http://192.168.1.20:8456;
proxy_set_header Host 192.168.1.20:8458; # 关键:使用内网地址
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 http; # 关键:明确使用http协议
proxy_set_header X-Forwarded-Host 192.168.1.20:8458;
proxy_set_header X-Forwarded-Port 8458;
proxy_http_version 1.1;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
}
location /v2/ {
proxy_pass http://192.168.1.20:8456/v2/;
proxy_set_header Host 192.168.1.20:8458;
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 http;
proxy_set_header X-Forwarded-Host 192.168.1.20:8458;
client_max_body_size 0;
chunked_transfer_encoding on;
}
}
3. Harbor.yml 配置修改
# 主机名设置为内网IP
hostname: 192.168.1.20
# HTTP配置 - Harbor内部使用
http:
port: 8456
# 注释掉HTTPS配置 - 由Nginx处理
# https:
# port: 8457
# certificate: /path/to/cert
# private_key: /path/to/key
# 外部访问URL - 设置为外网HTTPS地址
external_url: https://218.249.73.244:8457
4. 重启 Nginx 以及访问方式
# 重启
docker restart sg-nginx
外网访问
- 推荐:
https://218.249.73.244:8457
✅ - HTTP重定向:
http://218.249.73.244:8456
→https://218.249.73.244:8457
✅
- 推荐:
内网访问
- 新增:
http://192.168.1.20:8458
✅ (专门为内网配置) - 直接:
http://192.168.1.20:8456
❌ (可能有CSRF问题)
- 新增:
五、配置防火墙和访问控制
1. 基础 iptables 规则设置
# 清空现有规则(谨慎操作)
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
# 设置默认策略
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
2. 允许本地回环和已建立的连接
# 允许本地回环
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# 允许已建立的连接
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
4. 配置特定外网 IP 访问
# 允许特定外网IP访问 Harbor
iptables -I DOCKER-USER -s 218.17.30.27 -j ACCEPT
iptables -I DOCKER-USER 2 -s 218.249.73.242 -j ACCEPT
5. 拒绝其他外网访问 Harbor
# 拒绝其他所有外网IP访问 Harbor 端口
sudo iptables -A INPUT -p tcp --dport 8443 -j REJECT --reject-with tcp-reset
sudo iptables -A INPUT -p tcp --dport 80 -j REJECT --reject-with tcp-reset
7. 保存 iptables 规则
# Ubuntu/Debian 系统
sudo apt-get install iptables-persistent
sudo iptables-save > /etc/iptables/rules.v4
# CentOS/RHEL 系统
sudo service iptables save
# 或者
sudo iptables-save > /etc/sysconfig/iptables
# 手动保存到文件
sudo iptables-save > /etc/iptables.rules
# 设置开机自动加载(Ubuntu/Debian)
echo '#!/bin/bash' | sudo tee /etc/network/if-pre-up.d/iptables
echo 'iptables-restore < /etc/iptables/rules.v4' | sudo tee -a /etc/network/if-pre-up.d/iptables
sudo chmod +x /etc/network/if-pre-up.d/iptables
9. 查看和管理 iptables 规则
# 查看当前规则
sudo iptables -L -n -v
# 查看特定端口的规则
sudo iptables -L -n | grep -E '(8443|80)'
# 查看规则编号
sudo iptables -L INPUT --line-numbers
# 删除特定规则(按行号)
sudo iptables -D INPUT 行号
# 插入新规则到指定位置
sudo iptables -I INPUT 7 -s 218.249.73.242 -p tcp --dport 8443 -j ACCEPT
10. 测试访问控制
# 从允许的IP测试访问
curl -k https://你的公网IP:8443
# 从内网测试访问
curl -k https://内网IP:8443
# 检查端口是否开放
nmap -p 8443 你的公网IP
# 查看连接状态
netstat -tlnp | grep 8443
六、客户端配置(Docker 使用自签证书)
1. 在客户端机器上创建证书目录
# 创建 Docker 证书目录(注意端口号)
sudo mkdir -p /etc/docker/certs.d/你的公网IP:8443
# 复制证书到客户端
scp root@你的公网IP:/opt/harbor/certs/harbor.crt /etc/docker/certs.d/你的公网IP:8443/ca.crt
# 重启 Docker 服务
sudo systemctl restart docker
2. 或者配置 Docker daemon 忽略 SSL 验证(不推荐生产环境)
# 编辑 Docker daemon 配置
sudo vim /etc/docker/daemon.json
# 添加以下内容
{
"insecure-registries": ["你的公网IP:8443"]
}
# 重启 Docker
sudo systemctl restart docker
七、使用 Harbor
1. 访问 Harbor Web 界面
- URL:
https://你的公网IP:8443
- 用户名:
admin
- 密码:
Harbor12345
2. Docker 命令行使用
# 登录 Harbor
docker login 你的公网IP:8443
# 标记镜像
docker tag nginx:latest 你的公网IP:8443/library/nginx:latest
# 推送镜像
docker push 你的公网IP:8443/library/nginx:latest
# 拉取镜像
docker pull 你的公网IP:8443/library/nginx:latest
八、Harbor 管理命令
1.启动/停止 Harbor
cd /opt/harbor
# 停止 Harbor
docker-compose down
# 启动 Harbor
docker-compose up -d
# 重启 Harbor
docker-compose restart
2.备份和恢复
# 备份数据
tar -czf harbor-backup-$(date +%Y%m%d).tar.gz /data
# 升级前备份配置
cp harbor.yml harbor.yml.bak