docker更新

This commit is contained in:
2026-07-25 21:21:25 +08:00 Unverified
parent 1595d6f0c0
commit 2e940f7f30
3 changed files with 192 additions and 41 deletions
+18 -13
View File
@@ -1,13 +1,18 @@
# 复制为 .env.docker并通过 docker run --env-file .env.docker 使用 # 复制为 .env.docker供 compose.example.yml 在运行时读取
ASPNETCORE_ENVIRONMENT=Production # 空值必须在启动前填写。建议使用十六进制或只包含字母数字的随机值。
ASPNETCORE_HTTP_PORTS=8080 JIAOWU_IMAGE=jiaowu:local
Database__Provider=MySql JIAOWU_PORT=8080
Database__ApplyMigrationsOnStartup=false
Database__CommandTimeoutSeconds=30 MYSQL_DATABASE=jiaowu_demo
ConnectionStrings__MySql=Server=db.example.edu.cn;Port=3306;Database=jiaowu;User=APP_USER;Password=REPLACE_WITH_A_STRONG_PASSWORD;SslMode=VerifyFull;SslCa=/run/secrets/mysql-ca.pem; MYSQL_USER=jiaowu
Jwt__Issuer=Jiaowu.Api MYSQL_PASSWORD=
Jwt__Audience=Jiaowu.Web MYSQL_ROOT_PASSWORD=
Jwt__Key=REPLACE_WITH_AT_LEAST_32_RANDOM_BYTES
Jwt__ExpireMinutes=60 JWT_KEY=
AllowedHosts=jiaowu.example.edu.cn ALLOWED_HOSTS=localhost
Cors__Origins__0=https://jiaowu.example.edu.cn CORS_ORIGIN=http://localhost:8080
# 仅首次创建演示管理员时使用;演示数据成功写入后删除下面三行。
SEED_ADMIN_USERNAME=demo-admin
SEED_ADMIN_PASSWORD=
SEED_ADMIN_DISPLAY_NAME=演示环境管理员
+73 -28
View File
@@ -182,42 +182,87 @@ git.biss.click/biss/academic-affairs-system
会创建 Gitea Release;手动运行只保留工作流产物并推送 会创建 Gitea Release;手动运行只保留工作流产物并推送
`manual-<run-number>``sha-<commit>` 镜像标签。 `manual-<run-number>``sha-<commit>` 镜像标签。
本地使用 Docker 时,先复制并编辑配置: 仓库提供跨 Windows、Linux 和 macOS Docker Desktop 使用的
[`compose.example.yml`](compose.example.yml)。它包含 MySQL 8.4、一次性数据库迁移、
Web 服务和一个默认关闭的演示数据工具服务。数据库数据保存在命名卷中,MySQL 端口不
暴露到宿主机;容器日志默认轮转为 3 个 10 MB 文件。
先复制并编辑配置。PowerShell
```powershell ```powershell
Copy-Item -LiteralPath '.env.docker.example' -Destination '.env.docker' Copy-Item -LiteralPath '.env.docker.example' -Destination '.env.docker'
``` ```
先使用迁移账号配置文件执行迁移,再使用应用账号配置文件启动容器;MySQL CA 文件通过 Linux/macOS
只读卷挂载,不会进入镜像:
```powershell ```bash
$image = 'git.biss.click/biss/academic-affairs-system:1.0.0' cp .env.docker.example .env.docker
$migrateArgs = @(
'run', '--rm'
'--env-file', '.env.docker.migrate'
'--mount', 'type=bind,source=C:\certs\mysql-ca.pem,target=/run/secrets/mysql-ca.pem,readonly'
$image
'--migrate-only'
)
& docker @migrateArgs
if ($LASTEXITCODE -ne 0) { throw '数据库迁移失败。' }
$runArgs = @(
'run', '--detach'
'--name', 'jiaowu'
'--restart', 'unless-stopped'
'--env-file', '.env.docker'
'--publish', '8080:8080'
'--mount', 'type=bind,source=C:\certs\mysql-ca.pem,target=/run/secrets/mysql-ca.pem,readonly'
$image
)
& docker @runArgs
if ($LASTEXITCODE -ne 0) { throw '容器启动失败。' }
``` ```
Docker 镜像不包含 `.env`、数据库密码 JWT 密钥。容器以非 root 用户运行,监听 `.env.docker` 中所有密码 JWT 空值填成独立随机值;`JWT_KEY` 至少使用 64 个
随机十六进制字符。该文件已被
`.gitignore` 排除,不要提交;Compose 通过 `--env-file` 在运行时插值并把应用需要的
配置传入容器,镜像构建过程不需要也不会得到这些值。
如需在当前机器构建镜像,保留 `JIAOWU_IMAGE=jiaowu:local` 并执行:
```powershell
$composeArgs = @(
'--file', 'compose.example.yml'
'--env-file', '.env.docker'
'build', 'app'
)
& docker compose @composeArgs
if ($LASTEXITCODE -ne 0) { throw 'Docker 镜像构建失败。' }
```
也可以把 `JIAOWU_IMAGE` 改成工作流发布的明确版本标签,例如
`git.biss.click/biss/academic-affairs-system:1.0.0`。正常启动不会写入演示数据:
```powershell
$composeArgs = @(
'--file', 'compose.example.yml'
'--env-file', '.env.docker'
'up', '--detach', 'app'
)
& docker compose @composeArgs
if ($LASTEXITCODE -ne 0) { throw 'Compose 启动失败。' }
```
Compose 会先等待 MySQL 健康,再执行 `migrate`;只有迁移成功才启动 `app`。首次需要
演示数据时,应在**尚未启动 app 的全新空库**上单独执行:
```powershell
$composeArgs = @(
'--file', 'compose.example.yml'
'--env-file', '.env.docker'
'run', '--rm', 'demo-data'
)
& docker compose @composeArgs
if ($LASTEXITCODE -ne 0) { throw '演示数据写入失败。' }
```
`demo-data` 使用 `tools` profile,因此普通 `docker compose up` 不会执行它;显式指定
该服务时 Compose 会自动启用其 profile,并启动 MySQL、执行迁移后再写入数据。应用自身
还会强制检查确认参数和空业务库,检测到已有业务数据会拒绝写入。成功后,从
`.env.docker` 删除三个 `SEED_ADMIN_*` 配置,再启动 `app`
Linux/macOS 的 Compose 参数完全相同,可直接运行:
```bash
docker compose -f compose.example.yml --env-file .env.docker build app
docker compose -f compose.example.yml --env-file .env.docker run --rm demo-data
docker compose -f compose.example.yml --env-file .env.docker up -d app
docker compose -f compose.example.yml --env-file .env.docker logs --follow app
```
示例中应用与 MySQL 位于 Compose 私有网络,所以内部连接使用
`SslMode=Disabled`,MySQL 未映射宿主机端口。这适合独立演示环境;正式生产连接外部
MySQL 时仍应使用前文的 `SslMode=VerifyFull` 和 CA,并拆分具备 DDL 权限的迁移账号与
仅具备业务 DML 权限的应用账号。官方 MySQL 镜像通过 `MYSQL_USER` 创建的账号会获得
示例数据库的全部权限,因此这个一体化 Compose 不能替代生产环境的最小权限设计。
Docker 镜像不包含 `.env`、数据库密码或 JWT 密钥。应用容器以非 root 用户运行并监听
8080 端口;生产环境仍应由反向代理负责 HTTPS、访问日志和请求大小限制。 8080 端口;生产环境仍应由反向代理负责 HTTPS、访问日志和请求大小限制。
## 验证 ## 验证
+101
View File
@@ -0,0 +1,101 @@
name: jiaowu-demo
x-jiaowu-image: &jiaowu-image
image: "${JIAOWU_IMAGE:-jiaowu:local}"
build:
context: .
dockerfile: Dockerfile
x-jiaowu-environment: &jiaowu-environment
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_HTTP_PORTS: "8080"
Database__Provider: MySql
Database__ApplyMigrationsOnStartup: "false"
Database__CommandTimeoutSeconds: "30"
ConnectionStrings__MySql: "Server=mysql;Port=3306;Database=${MYSQL_DATABASE:-jiaowu_demo};User=${MYSQL_USER:-jiaowu};Password=${MYSQL_PASSWORD:?请在 .env.docker 中设置 MYSQL_PASSWORD};SslMode=Disabled;"
Jwt__Issuer: Jiaowu.Api
Jwt__Audience: Jiaowu.Web
Jwt__Key: "${JWT_KEY:?请在 .env.docker 中设置 JWT_KEY}"
Jwt__ExpireMinutes: "60"
AllowedHosts: "${ALLOWED_HOSTS:-localhost}"
Cors__Origins__0: "${CORS_ORIGIN:-http://localhost:8080}"
SeedAdmin__UserName: "${SEED_ADMIN_USERNAME:-}"
SeedAdmin__Password: "${SEED_ADMIN_PASSWORD:-}"
SeedAdmin__DisplayName: "${SEED_ADMIN_DISPLAY_NAME:-}"
x-json-logging: &json-logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
mysql:
image: mysql:8.4
restart: unless-stopped
environment:
MYSQL_DATABASE: "${MYSQL_DATABASE:-jiaowu_demo}"
MYSQL_USER: "${MYSQL_USER:-jiaowu}"
MYSQL_PASSWORD: "${MYSQL_PASSWORD:?请在 .env.docker 中设置 MYSQL_PASSWORD}"
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:?请在 .env.docker 中设置 MYSQL_ROOT_PASSWORD}"
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_0900_ai_ci
healthcheck:
test:
- CMD-SHELL
- MYSQL_PWD="$${MYSQL_ROOT_PASSWORD}" mysqladmin ping --host=127.0.0.1 --user=root --silent
interval: 5s
timeout: 5s
retries: 20
start_period: 30s
volumes:
- mysql-data:/var/lib/mysql
logging: *json-logging
migrate:
<<: *jiaowu-image
command:
- --migrate-only
environment: *jiaowu-environment
depends_on:
mysql:
condition: service_healthy
restart: "no"
init: true
logging: *json-logging
app:
<<: *jiaowu-image
environment: *jiaowu-environment
depends_on:
mysql:
condition: service_healthy
migrate:
condition: service_completed_successfully
ports:
- "${JIAOWU_PORT:-8080}:8080"
restart: unless-stopped
init: true
logging: *json-logging
# 工具型一次性服务:普通 docker compose up 不会执行它。
demo-data:
<<: *jiaowu-image
profiles:
- tools
command:
- --seed-demo-data
- --confirm-production-demo-data
environment: *jiaowu-environment
depends_on:
mysql:
condition: service_healthy
migrate:
condition: service_completed_successfully
restart: "no"
init: true
logging: *json-logging
volumes:
mysql-data: