docker更新
This commit is contained in:
+18
-13
@@ -1,13 +1,18 @@
|
||||
# 复制为 .env.docker,并通过 docker run --env-file .env.docker 使用。
|
||||
ASPNETCORE_ENVIRONMENT=Production
|
||||
ASPNETCORE_HTTP_PORTS=8080
|
||||
Database__Provider=MySql
|
||||
Database__ApplyMigrationsOnStartup=false
|
||||
Database__CommandTimeoutSeconds=30
|
||||
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;
|
||||
Jwt__Issuer=Jiaowu.Api
|
||||
Jwt__Audience=Jiaowu.Web
|
||||
Jwt__Key=REPLACE_WITH_AT_LEAST_32_RANDOM_BYTES
|
||||
Jwt__ExpireMinutes=60
|
||||
AllowedHosts=jiaowu.example.edu.cn
|
||||
Cors__Origins__0=https://jiaowu.example.edu.cn
|
||||
# 复制为 .env.docker,供 compose.example.yml 在运行时读取。
|
||||
# 空值必须在启动前填写。建议使用十六进制或只包含字母数字的随机值。
|
||||
JIAOWU_IMAGE=jiaowu:local
|
||||
JIAOWU_PORT=8080
|
||||
|
||||
MYSQL_DATABASE=jiaowu_demo
|
||||
MYSQL_USER=jiaowu
|
||||
MYSQL_PASSWORD=
|
||||
MYSQL_ROOT_PASSWORD=
|
||||
|
||||
JWT_KEY=
|
||||
ALLOWED_HOSTS=localhost
|
||||
CORS_ORIGIN=http://localhost:8080
|
||||
|
||||
# 仅首次创建演示管理员时使用;演示数据成功写入后删除下面三行。
|
||||
SEED_ADMIN_USERNAME=demo-admin
|
||||
SEED_ADMIN_PASSWORD=
|
||||
SEED_ADMIN_DISPLAY_NAME=演示环境管理员
|
||||
|
||||
@@ -182,42 +182,87 @@ git.biss.click/biss/academic-affairs-system
|
||||
会创建 Gitea Release;手动运行只保留工作流产物并推送
|
||||
`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
|
||||
Copy-Item -LiteralPath '.env.docker.example' -Destination '.env.docker'
|
||||
```
|
||||
|
||||
先使用迁移账号配置文件执行迁移,再使用应用账号配置文件启动容器;MySQL CA 文件通过
|
||||
只读卷挂载,不会进入镜像:
|
||||
Linux/macOS:
|
||||
|
||||
```powershell
|
||||
$image = 'git.biss.click/biss/academic-affairs-system:1.0.0'
|
||||
|
||||
$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 '容器启动失败。' }
|
||||
```bash
|
||||
cp .env.docker.example .env.docker
|
||||
```
|
||||
|
||||
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、访问日志和请求大小限制。
|
||||
|
||||
## 验证
|
||||
|
||||
@@ -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:
|
||||
Reference in New Issue
Block a user