# 在现有服务器上搭建 Docker Registry # 使用方式:.\scripts\deploy\setup-registry-on-server.ps1 -Server 45.249.208.118 -Username root -Password "your-password" [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Server, [string]$Username = "root", [string]$Password, [string]$RemotePath = "/root/deploy", [switch]$EnableAuth, [string]$AuthUser = "admin", [string]$AuthPassword ) Write-Host "===> 在服务器上搭建 Docker Registry" -ForegroundColor Cyan Write-Host "服务器: $Server" -ForegroundColor Gray Write-Host "" # 检查 PuTTY 工具(用于密码认证) $usePlink = $false $puttyTools = @{ Plink = $null Pscp = $null } if ($Password) { $searchPaths = @( "C:\Program Files\PuTTY", "C:\Program Files (x86)\PuTTY", "$env:USERPROFILE\AppData\Local\Programs\PuTTY" ) foreach ($path in $searchPaths) { $plinkPath = Join-Path $path "plink.exe" $pscpPath = Join-Path $path "pscp.exe" if (Test-Path $plinkPath) { $puttyTools.Plink = $plinkPath } if (Test-Path $pscpPath) { $puttyTools.Pscp = $pscpPath } if ($puttyTools.Plink -and $puttyTools.Pscp) { $usePlink = $true break } } if ($usePlink) { Write-Host "使用 PuTTY 工具进行认证" -ForegroundColor Gray } else { Write-Host "未找到 PuTTY 工具,将使用 SSH 密钥或手动输入密码" -ForegroundColor Yellow } } # 服务器密钥(从之前的部署中获取) $hostKey = "SHA256:WZOtvC/+IWw29P8vyovSabmIRFkQ/Bnmhj+qhTshA4Q" # 辅助函数:执行 SSH 命令 function Invoke-SSHCmd { param([string]$Command) $sshTarget = "${Username}@${Server}" if ($usePlink -and $Password) { $output = & $puttyTools.Plink -batch -ssh -hostkey $hostKey -pw $Password $sshTarget $Command 2>&1 $output | ForEach-Object { Write-Host $_ -ForegroundColor Gray } return $LASTEXITCODE } else { ssh $sshTarget $Command return $LASTEXITCODE } } # 辅助函数:上传文件 function Upload-File { param([string]$LocalPath, [string]$RemotePath) $remoteTarget = "${Username}@${Server}:${RemotePath}/" if ($usePlink -and $Password) { $process = Start-Process -FilePath $puttyTools.Pscp -ArgumentList @( "-batch", "-hostkey", $hostKey, "-pw", $Password, $LocalPath, $remoteTarget ) -NoNewWindow -PassThru -Wait return $process.ExitCode } else { scp $LocalPath $remoteTarget return $LASTEXITCODE } } $scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path # 1. 检查 Docker 是否安装 Write-Host "===> 检查 Docker 环境" -ForegroundColor Cyan $checkDocker = Invoke-SSHCmd -Command "docker --version" if ($checkDocker -ne 0) { Write-Host "✗ Docker 未安装,请先安装 Docker" -ForegroundColor Red exit 1 } Write-Host "✓ Docker 已安装" -ForegroundColor Green $checkCompose = Invoke-SSHCmd -Command "docker compose version" if ($checkCompose -ne 0) { Write-Host "✗ Docker Compose 未安装,请先安装 Docker Compose" -ForegroundColor Red exit 1 } Write-Host "✓ Docker Compose 已安装" -ForegroundColor Green # 2. 上传 docker-compose.registry.yml Write-Host "" Write-Host "===> 上传 Registry 配置文件" -ForegroundColor Cyan $registryCompose = Join-Path (Split-Path -Parent $scriptPath) "..\docker-compose.registry.yml" $registryCompose = Resolve-Path $registryCompose -ErrorAction SilentlyContinue if (-not $registryCompose) { Write-Host "✗ 未找到 docker-compose.registry.yml" -ForegroundColor Red exit 1 } Write-Host "上传配置文件: $registryCompose" -ForegroundColor Gray $uploadResult = Upload-File -LocalPath $registryCompose -RemotePath $RemotePath if ($uploadResult -eq 0) { Write-Host "✓ 配置文件上传成功" -ForegroundColor Green } else { Write-Host "✗ 配置文件上传失败" -ForegroundColor Red exit 1 } # 3. 在服务器上创建 Registry 目录 Write-Host "" Write-Host "===> 创建 Registry 目录" -ForegroundColor Cyan $mkdirCmd = "mkdir -p ${RemotePath}/registry/data ${RemotePath}/registry/config" $mkdirResult = Invoke-SSHCmd -Command $mkdirCmd if ($mkdirResult -eq 0) { Write-Host "✓ 目录创建成功" -ForegroundColor Green } # 4. 配置认证(如果需要) if ($EnableAuth) { Write-Host "" Write-Host "===> 配置 Registry 认证" -ForegroundColor Cyan if (-not $AuthPassword) { $securePassword = Read-Host "请输入 Registry 密码" -AsSecureString $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword) $AuthPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) } # 在服务器上创建 htpasswd $authCmd = @" cd ${RemotePath} && \ docker run --rm --entrypoint htpasswd httpd:2 -Bbn $AuthUser $AuthPassword > registry/config/htpasswd && \ echo '认证文件已创建' "@ $authResult = Invoke-SSHCmd -Command $authCmd if ($authResult -eq 0) { Write-Host "✓ 认证配置成功" -ForegroundColor Green Write-Host " 用户名: $AuthUser" -ForegroundColor Gray Write-Host " 注意: 需要编辑 docker-compose.registry.yml 启用认证" -ForegroundColor Yellow } else { Write-Host "⚠ 认证配置失败,将使用无认证模式" -ForegroundColor Yellow } } # 5. 配置 Docker 允许不安全的 Registry Write-Host "" Write-Host "===> 配置 Docker 允许不安全的 Registry" -ForegroundColor Cyan $dockerConfigCmd = "mkdir -p /etc/docker && if [ ! -f /etc/docker/daemon.json ]; then echo '{}' > /etc/docker/daemon.json; fi && python3 -c `"import json; f=open('/etc/docker/daemon.json','r'); config=json.load(f); f.close(); config.setdefault('insecure-registries',[]); reg='$Server:5000'; config['insecure-registries']=[r for r in config['insecure-registries'] if r!=reg]+[reg]; f=open('/etc/docker/daemon.json','w'); json.dump(config,f,indent=2); f.close(); print('配置已更新' if reg not in config.get('insecure-registries',[]) else '配置已存在')\`"" $configResult = Invoke-SSHCmd -Command $dockerConfigCmd if ($configResult -eq 0) { Write-Host "✓ Docker 配置成功" -ForegroundColor Green # 重启 Docker Write-Host "重启 Docker 服务..." -ForegroundColor Gray $restartResult = Invoke-SSHCmd -Command "systemctl restart docker" if ($restartResult -eq 0) { Write-Host "✓ Docker 已重启" -ForegroundColor Green } else { Write-Host "⚠ Docker 重启失败,请手动重启" -ForegroundColor Yellow } } else { Write-Host "⚠ Docker 配置失败,请手动配置" -ForegroundColor Yellow Write-Host " 编辑 /etc/docker/daemon.json,添加:" -ForegroundColor Gray Write-Host " { `"insecure-registries`": [`"$Server:5000`"] }" -ForegroundColor Gray } # 6. 启动 Registry Write-Host "" Write-Host "===> 启动 Registry 服务" -ForegroundColor Cyan $startCmd = "cd ${RemotePath} && docker compose -f docker-compose.registry.yml up -d" $startResult = Invoke-SSHCmd -Command $startCmd if ($startResult -eq 0) { Write-Host "✓ Registry 启动成功" -ForegroundColor Green } else { Write-Host "✗ Registry 启动失败" -ForegroundColor Red Write-Host "请检查日志: docker compose -f docker-compose.registry.yml logs" -ForegroundColor Yellow exit 1 } # 等待服务启动 Write-Host "等待服务启动..." -ForegroundColor Gray Start-Sleep -Seconds 5 # 7. 测试 Registry Write-Host "" Write-Host "===> 测试 Registry" -ForegroundColor Cyan $testCmd = "curl -s http://localhost:5000/v2/ | head -1" $testResult = Invoke-SSHCmd -Command $testCmd if ($testResult -eq 0) { Write-Host "✓ Registry 运行正常" -ForegroundColor Green } else { Write-Host "⚠ Registry 测试失败,请检查日志" -ForegroundColor Yellow Write-Host "查看日志: docker compose -f docker-compose.registry.yml logs registry" -ForegroundColor Gray } # 8. 显示 Registry 信息 Write-Host "" Write-Host "===> Registry 搭建完成" -ForegroundColor Green Write-Host "" Write-Host "Registry 信息:" -ForegroundColor Cyan Write-Host " 地址: http://$Server:5000" -ForegroundColor Gray Write-Host " 镜像格式: $Server`:5000/youyidian/3d-material:latest" -ForegroundColor Gray if ($EnableAuth) { Write-Host " 认证: 已启用(用户名: $AuthUser)" -ForegroundColor Gray } else { Write-Host " 认证: 未启用(HTTP 模式)" -ForegroundColor Gray } Write-Host "" Write-Host "下一步:" -ForegroundColor Cyan Write-Host "1. 在本地配置 Docker 允许不安全的 Registry" -ForegroundColor Gray Write-Host "2. 测试推送镜像" -ForegroundColor Gray Write-Host "3. 运行 一键镜像部署.ps1 发布应用" -ForegroundColor Gray Write-Host "" Write-Host "测试命令:" -ForegroundColor Cyan Write-Host " # 测试连接" -ForegroundColor Gray Write-Host " curl http://$Server:5000/v2/" -ForegroundColor Gray Write-Host "" Write-Host " # 测试推送(在本地)" -ForegroundColor Gray Write-Host " docker tag hello-world:latest $Server`:5000/hello-world:latest" -ForegroundColor Gray Write-Host " docker push $Server`:5000/hello-world:latest" -ForegroundColor Gray