迁移 TraceCD 部署到 HK-1
Some checks failed
Java Maven 3.9.9 & JDK 26 CI/CD Pipeline / build-and-deploy (push) Failing after 1m9s

This commit is contained in:
Lee 2026-08-19 17:57:55 +08:00
parent fe95fce777
commit 4bff3b8a2f
11 changed files with 256 additions and 12 deletions

View File

@ -30,7 +30,7 @@ jobs:
shell: sh
run: |
echo "🚀 开始构建 JDK 26 镜像: ${IMAGE_NAME}:${{ gitea.sha }}"
docker build -t ${IMAGE_NAME}:${{ gitea.sha }} .
DOCKER_BUILDKIT=0 docker build --memory=700m -t ${IMAGE_NAME}:${{ gitea.sha }} .
docker tag ${IMAGE_NAME}:${{ gitea.sha }} ${IMAGE_NAME}:latest
- name: 3. 旧容器清理与新容器平滑重启
@ -43,10 +43,15 @@ jobs:
echo "🔄 正在启动全新 JDK 26 容器环境..."
docker run -d \
--name ${CONTAINER_NAME} \
-p ${APP_PORT}:${APP_PORT} \
--restart no \
-m 512m \
-e JAVA_TOOL_OPTIONS="-Xms128m -Xmx384m -XX:+UseG1GC" \
--network tracecd-net \
-p 127.0.0.1:${APP_PORT}:${APP_PORT} \
--restart unless-stopped \
--memory 384m \
--memory-swap 768m \
--cpus 0.75 \
--pids-limit 256 \
--env-file /opt/tracecd/app.env \
-e JAVA_TOOL_OPTIONS="-Xms64m -Xmx256m -XX:+UseSerialGC" \
${IMAGE_NAME}:latest
- name: 4. 服务健康检查 (HTTP 探活)

8
.gitignore vendored
View File

@ -1,4 +1,10 @@
target/
deploy/.env
deploy/stack.env
deploy/app.env
deploy/runner-token
deploy/data/
.migration-private/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
@ -36,4 +42,4 @@ build/
.vscode/
### Mac OS ###
.DS_Store
.DS_Store

View File

@ -2,6 +2,9 @@
FROM maven:3.9.16-eclipse-temurin-26 AS builder
WORKDIR /app
# 1C/1G 部署机上限制 Maven 峰值内存,避免构建挤占运行中的服务。
ENV MAVEN_OPTS="-Xms64m -Xmx384m -XX:+UseSerialGC"
# 1. 配置阿里云 Maven 镜像加速下载(可选,国内服务器强烈推荐)
RUN mkdir -p /root/.m2
RUN echo '<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"><mirrors><mirror><id>aliyunmaven</id><mirrorOf>*</mirrorOf><name>阿里云公共仓库</name><url>https://maven.aliyun.com/repository/public</url></mirror></mirrors></settings>' > /root/.m2/settings.xml

39
deploy/README.md Normal file
View File

@ -0,0 +1,39 @@
# TraceCD deployment on HK-1
The production stack lives at `/opt/tracecd` on `156.238.122.140` and is sized for a 1-core, 1-GiB host.
## Services
- MySQL 8.0.40: Docker-only `tracecd-net`; no host port is published.
- Gitea 1.22.6: host ports 3000 and 2222 are mapped, but remain blocked by the host firewall unless explicitly opened.
- Gitea Actions runner: capacity 1, label `centos-env`, Docker socket access.
- TraceCD: built by Gitea Actions, bound to `127.0.0.1:8080` and served by host Nginx.
- Nginx: `t.1633292.cn` on port 80. Port 443 remains owned by Xray.
## Bootstrap
Copy `compose.yaml`, `runner-config.yaml`, `nginx-tracecd.conf`, and `bootstrap-env.sh` to `/opt/tracecd`. Then run:
```bash
cd /opt/tracecd
chmod 700 bootstrap-env.sh
./bootstrap-env.sh
install -m 644 nginx-tracecd.conf /etc/nginx/conf.d/tracecd.conf
nginx -t && systemctl reload nginx
docker compose pull
docker compose up -d
```
`bootstrap-env.sh` creates random database and bootstrap passwords in `stack.env` and `app.env`, both mode 0600. Add `DEEPSEEK_API_KEY` and `MIMO_API_KEY` to `app.env` on the server; never commit either file.
## Operations
```bash
cd /opt/tracecd
docker compose ps
docker compose logs --tail 100 mysql gitea runner
docker stats --no-stream
curl -I -H 'Host: t.1633292.cn' http://127.0.0.1/
```
The workflow in `.gitea/workflows/deploy.yaml` builds on pushes to `dev`, joins the application to `tracecd-net`, loads `/opt/tracecd/app.env`, and replaces only `trace-container`.

6
deploy/app.env.example Normal file
View File

@ -0,0 +1,6 @@
SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/tracecd?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME=tracecd
SPRING_DATASOURCE_PASSWORD=replace-with-stack-env-mysql-password
DEEPSEEK_API_KEY=replace-with-secret
MIMO_API_KEY=replace-with-secret
APP_DEFAULT_PASSWORD=replace-with-secret

33
deploy/bootstrap-env.sh Normal file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
cd /opt/tracecd
umask 077
if [[ -e stack.env || -e app.env ]]; then
echo "Refusing to overwrite existing secret environment files." >&2
exit 1
fi
mysql_root_password="$(openssl rand -hex 24)"
mysql_app_password="$(openssl rand -hex 24)"
app_default_password="$(openssl rand -hex 16)"
{
printf 'MYSQL_ROOT_PASSWORD=%s\n' "$mysql_root_password"
printf 'MYSQL_PASSWORD=%s\n' "$mysql_app_password"
printf 'GITEA_HOST=156.238.122.140\n'
} > stack.env
{
printf '%s\n' 'SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/tracecd?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&createDatabaseIfNotExist=true'
printf 'SPRING_DATASOURCE_USERNAME=tracecd\n'
printf 'SPRING_DATASOURCE_PASSWORD=%s\n' "$mysql_app_password"
printf 'DEEPSEEK_API_KEY=\n'
printf 'MIMO_API_KEY=\n'
printf 'APP_DEFAULT_PASSWORD=%s\n' "$app_default_password"
} > app.env
chmod 600 stack.env app.env
ln -s stack.env .env
echo "Created protected environment files."

95
deploy/compose.yaml Normal file
View File

@ -0,0 +1,95 @@
services:
mysql:
image: mysql:8.0.40
container_name: tracecd-mysql
restart: unless-stopped
env_file: stack.env
environment:
MYSQL_DATABASE: tracecd
MYSQL_USER: tracecd
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_0900_ai_ci
- --performance-schema=OFF
- --innodb-buffer-pool-size=128M
- --innodb-log-buffer-size=8M
- --max-connections=20
- --table-open-cache=200
- --skip-log-bin
volumes:
- ./data/mysql:/var/lib/mysql
networks:
- tracecd-net
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p$$MYSQL_ROOT_PASSWORD --silent"]
interval: 10s
timeout: 5s
retries: 12
mem_limit: 320m
memswap_limit: 640m
cpus: 0.55
pids_limit: 256
gitea:
image: gitea/gitea:1.22.6
container_name: gitea
restart: unless-stopped
depends_on:
mysql:
condition: service_healthy
env_file: stack.env
environment:
USER_UID: 1000
USER_GID: 1000
GITEA__database__DB_TYPE: mysql
GITEA__database__HOST: mysql:3306
GITEA__database__NAME: gitea
GITEA__database__USER: root
GITEA__database__PASSWD: ${MYSQL_ROOT_PASSWORD}
GITEA__server__DOMAIN: ${GITEA_HOST}
GITEA__server__SSH_DOMAIN: ${GITEA_HOST}
GITEA__server__ROOT_URL: http://${GITEA_HOST}:3000/
GITEA__server__SSH_PORT: 2222
GITEA__service__DISABLE_REGISTRATION: "true"
GITEA__actions__ENABLED: "true"
volumes:
- ./data/gitea:/data
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
networks:
- tracecd-net
mem_limit: 256m
memswap_limit: 512m
cpus: 0.35
pids_limit: 256
runner:
image: gitea/act_runner:latest
container_name: gitea-runner
restart: unless-stopped
depends_on:
- gitea
env_file: stack.env
environment:
GITEA_INSTANCE_URL: http://gitea:3000
GITEA_RUNNER_NAME: hk1-low-memory-runner
GITEA_RUNNER_LABELS: centos-env:docker://docker:cli
GITEA_RUNNER_REGISTRATION_TOKEN_FILE: /run/secrets/runner_token
CONFIG_FILE: /data/config.yaml
volumes:
- ./data/runner:/data
- ./runner-config.yaml:/data/config.yaml:ro
- ./runner-token:/run/secrets/runner_token:ro
- /var/run/docker.sock:/var/run/docker.sock
networks:
- tracecd-net
mem_limit: 128m
memswap_limit: 256m
cpus: 0.25
pids_limit: 128
networks:
tracecd-net:
name: tracecd-net

19
deploy/nginx-tracecd.conf Normal file
View File

@ -0,0 +1,19 @@
server {
listen 80;
listen [::]:80;
server_name t.1633292.cn;
client_max_body_size 10m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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_connect_timeout 10s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}

34
deploy/runner-config.yaml Normal file
View File

@ -0,0 +1,34 @@
log:
level: info
runner:
file: .runner
capacity: 1
timeout: 3h
shutdown_timeout: 30s
fetch_timeout: 5s
fetch_interval: 2s
fetch_interval_max: 10s
labels:
- "centos-env:docker://docker:cli"
cache:
enabled: false
container:
network: bridge
privileged: false
options: "-v /opt/tracecd/app.env:/opt/tracecd/app.env:ro"
valid_volumes: []
docker_host: ""
force_pull: false
force_rebuild: false
require_docker: true
docker_timeout: 30s
bind_workdir: false
host:
workdir_parent: ""
metrics:
enabled: false

4
deploy/stack.env.example Normal file
View File

@ -0,0 +1,4 @@
# Copy to stack.env on the server and keep mode 0600.
MYSQL_ROOT_PASSWORD=replace-with-a-random-value
MYSQL_PASSWORD=replace-with-a-different-random-value
GITEA_HOST=156.238.122.140

View File

@ -24,9 +24,9 @@ spring:
# MySQL 数据源
datasource:
url: jdbc:mysql://192.168.2.5:3306/tracecd?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&createDatabaseIfNotExist=true
username: root
password: root
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://mysql:3306/tracecd?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&createDatabaseIfNotExist=true}
username: ${SPRING_DATASOURCE_USERNAME:tracecd}
password: ${SPRING_DATASOURCE_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
# Session 存储方式
@ -61,13 +61,13 @@ logging:
# DeepSeek API
deepseek:
api-key: ${DEEPSEEK_API_KEY:sk-732e5f5f1f07454492022401f0a2bf40}
api-key: ${DEEPSEEK_API_KEY}
base-url: https://api.deepseek.com/chat/completions
model: deepseek-v4-flash
# MIMO ASR API
mimo:
api-key: ${MIMO_API_KEY:sk-cqttr117tzllfolonxztu4qa5208liota2llfut458ixx2m1}
api-key: ${MIMO_API_KEY}
base-url: https://api.xiaomimimo.com/v1/chat/completions
model: mimo-v2.5-asr
@ -75,4 +75,4 @@ mimo:
app:
sql-max-retries: 5 # SQL 生成最大重试次数
default-username: admin # 默认用户名
default-password: admin123 # 默认密码(首次启动自动创建)
default-password: ${APP_DEFAULT_PASSWORD}