ci: build and publish multi-platform Docker images to GHCR

This commit is contained in:
SIMKEEP committed 2026-10-06 20:30:08 +08:00
1 parent 8f3e935067
commit 226c99708d
6 files changed
+144 -15

No files matched your search

+1
View File
@@ -1,6 +1,7 @@
*
!Dockerfile
!requirements.txt
!LICENSE
!index.html
!style.css
!app.js
+2
View File
@@ -5,6 +5,8 @@ SIMKEEP_SECURE_COOKIES=0
SIMKEEP_DB=data/simkeep.db
# Docker Compose 公网端口;改端口时同步修改 SIMKEEP_PUBLIC_URL。
SIMKEEP_PORT=5180
# Docker Compose 镜像;使用预构建镜像时改为 ghcr.io/rest-rain/simkeep:latest。
SIMKEEP_IMAGE=simkeep:local
# 可选的公共默认通知服务;用户也可在网页单独配置自己的服务。
# 从 BotFather 获取 Token。可选用户名不包含 @;留空会自动查询。
+73
View File
@@ -0,0 +1,73 @@
name: Docker image
on:
push:
branches: [main]
tags: ["v[0-9]*"]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build and publish
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
packages: write
steps:
- name: Check out source
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
with:
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate image tags and labels
id: metadata
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ghcr.io/${{ github.repository }}
flavor: latest=false
tags: |
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}},enable=${{ !contains(github.ref_name, '-') }}
type=sha
labels: |
org.opencontainers.image.licenses=MIT
- name: Build and publish image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
+1 -1
View File
@@ -7,7 +7,7 @@ RUN python scripts/build.py
FROM python:3.12-slim AS runtime
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 SIMKEEP_DB=/app/data/simkeep.db SIMKEEP_STATIC_DIR=/app/dist
COPY requirements.txt .
COPY requirements.txt LICENSE ./
RUN pip install --no-cache-dir -r requirements.txt
COPY server ./server
COPY scripts/backup.py scripts/restore.py ./scripts/
+20 -7
View File
@@ -58,7 +58,7 @@ SIMKEEP 是一个可自行部署的 SIM / eSIM 管理平台。把开通日期、
## Docker 部署
需要 Docker Engine 和 Docker Compose 插件。镜像会自动构建前端,服务器无需安装 Node.js 或 Python。
需要 Docker Engine 和 Docker Compose 插件。可直接使用 GHCR 镜像,支持 `amd64` / `arm64`,服务器无需安装 Node.js 或 Python。
下载仓库并进入项目目录后执行:
@@ -67,17 +67,27 @@ cp .env.example .env
chmod 600 .env
```
编辑 `.env`,把 `SIMKEEP_PUBLIC_URL` 改成自己的访问地址,例如 `http://your-server:5180`。本机试用可保留 `http://localhost:5180`。
编辑 `.env`,把 `SIMKEEP_PUBLIC_URL` 改成自己的访问地址,例如 `http://your-server:5180`,并设置镜像:
```dotenv
SIMKEEP_IMAGE=ghcr.io/rest-rain/simkeep:latest
```
本机试用可保留 `http://localhost:5180`。`latest` 对应 `main` 的最新构建;需要固定版本时使用对应版本标签。
```bash
docker compose up -d --build --wait
docker compose pull web
docker compose up -d --no-build --wait web
docker compose ps
```
打开 `http://localhost:5180` 或设置的服务器地址,点击“创建账号”。没有预置管理员、初始密码或演示资料。
也可从源码构建:在 `.env` 中设置 `SIMKEEP_IMAGE=simkeep:local`,然后执行 `docker compose up -d --build --wait`。
| 配置项 | 默认值 | 用途 |
| --- | --- | --- |
| `SIMKEEP_IMAGE` | `simkeep:local` | 镜像名称;使用 GHCR 镜像时填写上面的地址 |
| `SIMKEEP_PUBLIC_URL` | `http://localhost:5180` | 网页访问地址和提醒中的链接 |
| `SIMKEEP_PORT` | `5180` | 宿主机端口;修改时同步调整访问地址 |
| `SIMKEEP_BIND_ADDRESS` | `0.0.0.0` | 宿主机监听地址 |
@@ -85,7 +95,7 @@ docker compose ps
数据保存于命名卷 `simkeep_simkeep-data` 中的 `/app/data/simkeep.db`。容器重启和镜像更新会保留数据。使用单个 Web worker 和一个提醒调度进程。
详见 [Docker 部署与恢复说明](docs/DOCKER.md)。
GitHub Actions 在推送 `main` 或 `v1.0.0` 这样的版本标签时自动构建并发布镜像,也支持手动触发。首次发布后,仓库维护者需将 GHCR 包设为 Public,其他人才能匿名拉取。详见 [Docker 部署、自动构建与恢复说明](docs/DOCKER.md)。
## 通知配置
@@ -126,16 +136,19 @@ docker compose cp web:/app/data/backups ./docker-backups
备份包含账号、卡片、历史和个人通知密钥,应放在受保护的位置。不要只复制正在使用的主数据库文件而遗漏 WAL。
更新代码和镜像:
使用 GHCR 镜像时,拉取更新并重建容器:
```bash
docker compose up -d --build --wait
docker compose pull web
docker compose up -d --no-build --wait web
```
使用源码构建时,更新代码后执行 `docker compose up -d --build --wait`。
修改 `.env` 后,需要重建容器加载新环境变量:
```bash
docker compose up -d --force-recreate --wait web
docker compose up -d --no-build --force-recreate --wait web
```
`docker compose restart` 不会加载修改后的 `.env`。不要执行 `docker compose down -v`,它会删除数据卷。
+47 -7
View File
@@ -1,10 +1,10 @@
# Docker Compose 部署
需要 Docker Engine 与 Docker Compose 插件。镜像构建会自动打包前端,不需要宿主机安装 Node.js、npm 或 Python。应用使用单个 Uvicorn worker,后台续期提醒与 Web 同时启动。
需要 Docker Engine 与 Docker Compose 插件。预构建镜像包含前端与后端,支持 `linux/amd64` 和 `linux/arm64`,不需要宿主机安装 Node.js、npm 或 Python。应用使用单个 Uvicorn worker,后台续期提醒与 Web 同时启动。
## 在新服务器部署
进入包含 Dockerfile 和 compose.yml 的 simkeep 目录,准备配置:
进入仓库目录,准备配置;使用预构建镜像时只需 `compose.yml`、`.env.example` 和自己的 `.env`:
```bash
test -f .env || cp .env.example .env
@@ -13,8 +13,15 @@ chmod 600 .env
编辑 `.env`,将 `SIMKEEP_PUBLIC_URL` 改为实际访问地址,例如 `http://服务器IP:5180`。`SIMKEEP_PORT` 控制宿主机端口,默认 5180;改端口时同步修改公网地址。保持 HTTP 时使用 `SIMKEEP_SECURE_COOKIES=0`。每个用户登录网页的“通知设置”,点击“配置 Telegram / 配置邮件”保存自己的凭据;不需要修改 `.env` 或重启。`.env` 中的通知凭据仅作为可选公共默认服务。
在 `.env` 中将镜像改为:
```dotenv
SIMKEEP_IMAGE=ghcr.io/rest-rain/simkeep:latest
```
```bash
docker compose up -d --build --wait
docker compose pull web
docker compose up -d --no-build --wait web
docker compose ps
```
@@ -22,18 +29,51 @@ docker compose ps
默认 Compose 项目名为 `simkeep`,持久化卷为 `simkeep_simkeep-data`,数据库位于容器 `/app/data/simkeep.db`。保持项目名即可复用同一个卷。容器重启、镜像更新及普通 `docker compose down` 都会保留卷;`docker compose down -v` 会删除数据卷。
## 更新、配置与日志
### 从源码构建
更新代码并重新构建镜像:
需要完整仓库。在 `.env` 中设置 `SIMKEEP_IMAGE=simkeep:local`,然后执行:
```bash
docker compose up -d --build --wait
```
构建时自动打包前端,宿主机同样无需安装应用依赖。
## GitHub 自动构建镜像
工作流位于 [docker-image.yml](../.github/workflows/docker-image.yml),镜像发布到 `ghcr.io/rest-rain/simkeep`,同时构建 `amd64` 与 `arm64`。发布使用 GitHub 自动提供的 `GITHUB_TOKEN`,无需配置 Docker Hub 账号或额外的访问令牌。
| 触发方式 | 发布标签 |
| --- | --- |
| 推送 `main` | `latest`、`main`、`sha-提交短编号` |
| 推送版本标签,例如 `v1.2.3` | `1.2.3`、`1.2`、`sha-提交短编号` |
| 推送预发布标签,例如 `v1.2.3-rc.1` | `1.2.3-rc.1`、`sha-提交短编号` |
| 在 Actions 中手动运行 | 所选分支或版本对应的标签 |
| 向 `main` 提交 Pull Request | 仅验证构建,不发布 |
`latest` 只随 `main` 更新。使用正式版本标签部署时,例如设置 `SIMKEEP_IMAGE=ghcr.io/rest-rain/simkeep:1.2.3`,可避免跟随开发分支更新。
在仓库的 **Actions → Docker image** 查看构建结果,或点击 **Run workflow** 手动运行。仓库需启用 GitHub Actions;工作流已经声明 `contents: read` 和 `packages: write` 权限。
**首次发布后**,GHCR 包默认为 Private,即使源码仓库是公开的。维护者打开 [SIMKEEP 的包设置](https://github.com/users/rest-rain/packages/container/simkeep/settings),在 **Change visibility** 中改为 **Public**,即可匿名拉取。构建成功前包设置页面可能尚不存在。拉取提示 `denied` 时,先确认工作流已成功及包的可见性。
构建只读取 `.dockerignore` 允许的应用文件,不传入服务器 `.env`、数据库或通知密钥。镜像内附带 MIT LICENSE。
## 更新、配置与日志
使用预构建镜像时:
```bash
docker compose pull web
docker compose up -d --no-build --wait web
```
使用源码镜像时,更新代码后执行 `docker compose up -d --build --wait`。更新镜像会重建容器,数据仍保存在原命名卷中。
修改 `.env` 后重建容器加载新配置:
```bash
docker compose up -d --force-recreate --wait web
docker compose up -d --no-build --force-recreate --wait web
```
仅执行 `docker compose restart` 不会加载修改后的环境配置。日常查看或重启:
@@ -64,7 +104,7 @@ docker compose cp web:/app/data/backups ./docker-backups
```bash
docker compose stop web
docker compose run --rm --no-deps -T --entrypoint python web scripts/restore.py --replace < restore.db
docker compose up -d --wait
docker compose up -d --no-build --wait web
```
恢复容器以应用用户读取标准输入,不需要 root 或修改宿主机备份权限。它检查数据库完整性与 SIMKEEP 表结构,临时生成恢复库后替换;未传 --replace 时会拒绝覆盖现有库。恢复容器只执行数据库操作,不启动提醒进程。使用 `docker compose -p 其他项目名` 时,以上所有命令也须带相同项目名。