240 lines
9.1 KiB
PowerShell
240 lines
9.1 KiB
PowerShell
# 在现有服务器上搭建 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
|
||
|