Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
file: deploy/Dockerfile
platforms: linux/amd64
push: ${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}
tags: |
Expand Down Expand Up @@ -266,4 +266,3 @@ jobs:
done
echo "生产环境外部健康检查失败" >&2
exit 1

2 changes: 1 addition & 1 deletion deploy/CI-CD-DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ Compose 与脚本作业执行:

```text
.github/workflows/ci-cd.yml
Dockerfile
deploy/Dockerfile
.dockerignore
design/vue/Dockerfile
design/vue/.dockerignore
Expand Down
3 changes: 1 addition & 2 deletions Dockerfile → deploy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ USER app

EXPOSE 8080

HEALTHCHECK --interval=15s --timeout=5s --start-period=20s --retries=5 \
HEALTHCHECK --interval=60s --timeout=5s --start-period=20s --retries=5 \
CMD ["python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health', timeout=3)"]

ENTRYPOINT ["/app/solvify-agent"]

35 changes: 33 additions & 2 deletions deploy/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,37 @@ wait_for_health() {
return 1
}

# 等待指定服务进入运行状态
wait_for_running() {
local service_name="$1"
local deadline=$((SECONDS + HEALTH_TIMEOUT_SECONDS))
local container_id
local container_status

while (( SECONDS < deadline )); do
container_id="$(compose_command ps -q "$service_name" 2>/dev/null || true)"
if [[ -n "$container_id" ]]; then
container_status="$(docker inspect \
--format '{{.State.Status}}' \
"$container_id" 2>/dev/null || true)"
case "$container_status" in
running)
log "${service_name} 已进入运行状态"
return 0
;;
exited|dead)
log "${service_name} 状态异常:${container_status}"
return 1
;;
esac
fi
sleep 3
done

log "${service_name} 启动等待超时"
return 1
}

# 输出有限诊断信息且不读取配置文件
print_diagnostics() {
compose_command ps || true
Expand All @@ -98,7 +129,7 @@ rollback() {
compose_command up -d --no-deps backend || return 1
wait_for_health backend || return 1
compose_command up -d --no-deps frontend || return 1
wait_for_health frontend || return 1
wait_for_running frontend || return 1

log "上一版本恢复完成"
}
Expand Down Expand Up @@ -190,7 +221,7 @@ main() {

log "更新前端"
compose_command up -d --no-deps frontend
wait_for_health frontend
wait_for_running frontend

ln -sfn "$SCRIPT_DIR" "$SOLVIFY_ROOT/current"
docker image prune -f >/dev/null
Expand Down
4 changes: 0 additions & 4 deletions design/vue/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,3 @@ COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/dist /usr/share/nginx/html

EXPOSE 80

HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=5 \
CMD wget -q -O /dev/null http://127.0.0.1/health || exit 1

31 changes: 29 additions & 2 deletions internal/service/auth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,35 @@ func (s *authService) SendEmailCode(emailStr string) error {
}

// 3. 调用邮件组件把验证码发送给目标邮箱
subject := "Ryne 博客验证码"
body := fmt.Sprintf("<h1>您的验证码是: %s</h1><p>有效期 5 分钟,请勿泄露给他人。</p>", code)
subject := "Solvify 邮箱验证码"
body := fmt.Sprintf(`
<table width="100%%" cellpadding="0" cellspacing="0" border="0" style="background-color:#f1f5f9;padding:32px 16px;font-family:Arial,'Microsoft YaHei',sans-serif;color:#0f172a;">
<tr>
<td align="center">
<table width="560" cellpadding="0" cellspacing="0" border="0" style="width:100%%;max-width:560px;background-color:#ffffff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden;">
<tr>
<td style="background-color:#0f172a;padding:22px 30px;color:#ffffff;font-size:20px;font-weight:600;">
Solvify
</td>
</tr>
<tr>
<td style="padding:32px 30px 26px;">
<h1 style="margin:0 0 14px;font-size:22px;line-height:1.4;font-weight:600;color:#0f172a;">验证您的邮箱</h1>
<p style="margin:0;font-size:14px;line-height:1.8;color:#475569;">您好,您正在进行 Solvify 邮箱验证,请使用以下验证码完成操作:</p>
<div style="margin:24px 0;padding:20px 12px;text-align:center;background-color:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;font-size:30px;line-height:1.2;font-weight:600;letter-spacing:8px;color:#0f172a;">%s</div>
<p style="margin:0;font-size:14px;line-height:1.8;color:#475569;">验证码将在 5 分钟后失效。</p>
<div style="margin-top:22px;padding:10px 14px;background-color:#f8fafc;border-left:3px solid #64748b;font-size:13px;line-height:1.7;color:#64748b;">如果这不是您本人的操作,请忽略此邮件。请勿向任何人泄露验证码。</div>
</td>
</tr>
<tr>
<td style="padding:18px 30px;border-top:1px solid #e2e8f0;font-size:12px;line-height:1.6;color:#94a3b8;">
此邮件由 Solvify 系统自动发送,请勿直接回复。
</td>
</tr>
</table>
</td>
</tr>
</table>`, code)
if err := email.SendEmail(emailStr, subject, body); err != nil {
return apperrors.NewWithErr(apperrors.CodeInternalError, "发送邮件失败", err)
}
Expand Down