mirror of
https://github.com/readest/readest.git
synced 2026-07-09 16:00:16 +00:00
feat(docker): add GHCR and Docker Hub image publishing (#4250)
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (rust) (push) Waiting to run
Publish Docker image / publish (push) Waiting to run
PR checks / rust_lint (push) Waiting to run
PR checks / build_web_app (push) Waiting to run
PR checks / test_web_app (push) Waiting to run
PR checks / build_tauri_app (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
Deploy to vercel on merge / build_and_deploy (push) Waiting to run
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (rust) (push) Waiting to run
Publish Docker image / publish (push) Waiting to run
PR checks / rust_lint (push) Waiting to run
PR checks / build_web_app (push) Waiting to run
PR checks / test_web_app (push) Waiting to run
PR checks / build_tauri_app (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
Deploy to vercel on merge / build_and_deploy (push) Waiting to run
* Add GHCR and Docker Hub image publishing with fully runtime-configurable pull-first Docker setup (#1) * feat: add container image publishing workflow and pull-based compose setup Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/23c31167-9e15-4d44-ab89-f267b8cd6304 * refine docker publishing workflow and pull-first compose docs Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/23c31167-9e15-4d44-ab89-f267b8cd6304 * chore: temporarily expose docker publish run results for pr branch Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/c946a2f2-2219-4dea-a829-61b287bc4859 * fix: update pinned SHAs for setup-qemu-action and setup-buildx-action to v3 heads Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/0db6957e-476b-48e0-acf3-bee6964c3b32 Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * chore: switch all workflow action refs from SHA pins to stable version tags Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/19334b37-9b4c-45df-9c3c-81a497cef8e8 Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * fix: restore missing `with:` blocks lost during SHA-to-tag substitution Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/f204f742-5b7d-4f05-9647-03b9db86ea3d Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * fix(ci): checkout submodules for docker image workflow Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/72309e8a-6c7c-4004-902a-565f67e5c15f Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * feat(docker): support runtime client env for pulled web image * refactor(web): serve runtime config via script endpoint * fix(web): escape runtime config script payload * fix: align docker runtime config with internal/public backend urls Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/3bbcb608-6202-4f9e-b288-5c95a259da93 Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * chore: align published workflow tags with docs * docs: clarify runtime config precedence and linux host mapping Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/3bbcb608-6202-4f9e-b288-5c95a259da93 * refactor: move storage/quota config from build args to runtime env Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/da9b749e-0b1c-47b9-b474-5009765b6ea6 Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * fix: load runtime config in pages router app shell Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/b375132c-8317-4c98-b437-ae48c0153e3d Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * fix: apply biome formatting for runtime config quota helpers Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/778f5d75-884e-401b-b7cb-4ab40bc64a11 Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> Co-authored-by: Amir Pourmand <pourmand1376@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: S3_PUBLIC_ENDPOINT, _document.tsx for beforeInteractive, runtimeConfig fallbacks, README port (#2) Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/4f92f818-c008-4caa-9684-d530500b5fb2 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> * fix: reformat runtimeConfig.ts to satisfy biome formatter (#3) Agent-Logs-Url: https://github.com/pourmand1376/readest/sessions/4eea77f4-67ab-4428-b59e-0b21be988037 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pourmand1376 <32064808+pourmand1376@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
ae81cd0151
commit
9ad43aa8b2
15 changed files with 352 additions and 53 deletions
|
|
@ -1,5 +1,7 @@
|
|||
# ip used by frontend/client-side urls to access the backend
|
||||
# (used in compose for SUPABASE_PUBLIC_URL)
|
||||
HOST_IP=localhost
|
||||
READEST_IMAGE=ghcr.io/readest/readest:latest
|
||||
|
||||
# db(psql) config
|
||||
# change to strong password, min 32 chars
|
||||
|
|
@ -42,10 +44,11 @@ SMTP_SENDER_NAME=Readest
|
|||
PGRST_DB_SCHEMAS=public,graphql_public
|
||||
|
||||
# s3 storage through MinIO
|
||||
OBJECT_STORAGE_TYPE=s3
|
||||
MINIO_ROOT_USER=minioadmin
|
||||
MINIO_ROOT_PASSWORD=minioadmin-secret-password
|
||||
S3_BUCKET_NAME=readest-files
|
||||
|
||||
# 1GB fixed quota for storage and 50k for translations
|
||||
STORAGE_FIXED_QUOTA=1073741824
|
||||
TRANSLATION_FIXED_QUOTA=50000
|
||||
TRANSLATION_FIXED_QUOTA=50000
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
| service | Image | Description |
|
||||
| --------------- | --------------------------- | ------------------------------------------------- |
|
||||
| **client** | from `../Dockerfile` | readest frontend |
|
||||
| **client** | `ghcr.io/readest/readest` | readest frontend |
|
||||
| **db** | `supabase/postgres` | psql db with supabase extensions |
|
||||
| **kong** | `kong:2.8.1` | api gateway routing requests to supabase services |
|
||||
| **auth** | `supabase/gotrue:v2.185.0` | auth service (email, JWT) |
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
| Port | Service |
|
||||
| ------ | ---------------- |
|
||||
| `3000` | readest |
|
||||
| `7000` | kong API gateway |
|
||||
| `8000` | kong API gateway |
|
||||
| `9000` | MinIO S3 API |
|
||||
| `9001` | MinIO console UI |
|
||||
|
||||
|
|
@ -40,16 +40,40 @@ update `docker/.env`:
|
|||
- `SERVICE_ROLE_KEY` payload: `{"role": "service_role"}`
|
||||
- set `MINIO_ROOT_PASSWORD` to a strong password
|
||||
|
||||
### 2. Start the Stack
|
||||
### 2. Start the Stack (pull prebuilt client image)
|
||||
|
||||
run from the `docker/` directory:
|
||||
|
||||
```bash
|
||||
cd docker
|
||||
docker compose up --build -d
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
the client image is built locally on first run. subsequent starts reuse the cached image.
|
||||
this pulls `${READEST_IMAGE}` (default: `ghcr.io/readest/readest:latest`) instead of building the client locally.
|
||||
the web client now reads `SUPABASE_PUBLIC_URL`, `SUPABASE_ANON_KEY`, `API_BASE_URL`, `OBJECT_STORAGE_TYPE`, `STORAGE_FIXED_QUOTA`, and `TRANSLATION_FIXED_QUOTA` from runtime
|
||||
container env, so custom self-hosted values work with pulled images.
|
||||
|
||||
if you prefer Docker Hub, set `READEST_IMAGE` in `docker/.env`, for example:
|
||||
|
||||
```env
|
||||
READEST_IMAGE=docker.io/your-dockerhub-username/readest:latest
|
||||
```
|
||||
|
||||
replace `your-dockerhub-username` with the Docker Hub namespace that publishes your `readest` image.
|
||||
for official images, use the namespace configured for this repository's Docker Hub publishing secrets.
|
||||
|
||||
published tags:
|
||||
- `latest`: published from release events
|
||||
- `<release-tag>` (for example `v1.2.3`): published from release events
|
||||
- `main`: rolling image from the default branch
|
||||
- `sha-<commit>`: immutable commit tag
|
||||
|
||||
### Build locally instead of pulling
|
||||
|
||||
```bash
|
||||
cd docker
|
||||
docker compose -f compose.yaml -f compose.build.yaml up --build -d
|
||||
```
|
||||
|
||||
### 3. Access
|
||||
|
||||
|
|
@ -58,7 +82,7 @@ the client image is built locally on first run. subsequent starts reuse the cach
|
|||
|
||||
### Hot Reload (development)
|
||||
|
||||
to develop using the compose stack, set the build target on `client` to `development-stage`, which'll runs the next.js dev server. to enable hot reload, uncomment the `volumes` block in the `client` service in `compose.yaml`:
|
||||
to develop using the compose stack, use local builds (`compose.yaml` + `compose.build.yaml`) and set the build target on `client` to `development-stage` in `compose.build.yaml`, which runs the next.js dev server. to enable hot reload, uncomment the `volumes` block in the `client` service in `compose.yaml`:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
|
|
@ -90,18 +114,10 @@ docker compose down -v
|
|||
|
||||
## Building the Dockerfile standalone
|
||||
|
||||
the `Dockerfile` requires Build args for the next.js public env vars (they are inlined at build time)
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--target production-stage \
|
||||
--build-arg NEXT_PUBLIC_SUPABASE_URL=http://localhost:7000 \
|
||||
--build-arg NEXT_PUBLIC_SUPABASE_ANON_KEY=<anon-key> \
|
||||
--build-arg NEXT_PUBLIC_APP_PLATFORM=web \
|
||||
--build-arg NEXT_PUBLIC_API_BASE_URL=http://localhost:3000 \
|
||||
--build-arg NEXT_PUBLIC_OBJECT_STORAGE_TYPE=s3 \
|
||||
--build-arg NEXT_PUBLIC_STORAGE_FIXED_QUOTA=1073741824 \
|
||||
--build-arg NEXT_PUBLIC_TRANSLATION_FIXED_QUOTA=50000 \
|
||||
-t readest-client \
|
||||
.
|
||||
```
|
||||
|
|
@ -110,13 +126,23 @@ run the built image:
|
|||
|
||||
```bash
|
||||
docker run -p 3000:3000 \
|
||||
-e SUPABASE_URL=http://kong:8000 \
|
||||
-e SUPABASE_URL=http://host.docker.internal:8000 \
|
||||
-e SUPABASE_PUBLIC_URL=http://localhost:8000 \
|
||||
-e SUPABASE_ANON_KEY=<anon-key> \
|
||||
-e SUPABASE_ADMIN_KEY=<service-role-key> \
|
||||
-e S3_ENDPOINT=http://localhost:9000 \
|
||||
-e API_BASE_URL=http://localhost:3000 \
|
||||
-e OBJECT_STORAGE_TYPE=s3 \
|
||||
-e S3_ENDPOINT=http://host.docker.internal:9000 \
|
||||
-e S3_PUBLIC_ENDPOINT=http://localhost:9000 \
|
||||
-e S3_REGION=us-east-1 \
|
||||
-e S3_BUCKET_NAME=readest-files \
|
||||
-e S3_ACCESS_KEY_ID=<minio-user> \
|
||||
-e S3_SECRET_ACCESS_KEY=<minio-password> \
|
||||
-e STORAGE_FIXED_QUOTA=1073741824 \
|
||||
-e TRANSLATION_FIXED_QUOTA=50000 \
|
||||
readest-client
|
||||
```
|
||||
|
||||
on Linux, some Docker setups do not resolve `host.docker.internal` by default.
|
||||
in that case, either replace it with your host IP or run with:
|
||||
`--add-host=host.docker.internal:host-gateway`.
|
||||
|
|
|
|||
10
docker/compose.build.yaml
Normal file
10
docker/compose.build.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
services:
|
||||
client:
|
||||
build:
|
||||
context: ..
|
||||
target: production-stage
|
||||
args:
|
||||
NEXT_PUBLIC_SUPABASE_URL: http://${HOST_IP}:${KONG_HTTP_PORT:-8000}
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${ANON_KEY}
|
||||
NEXT_PUBLIC_APP_PLATFORM: web
|
||||
NEXT_PUBLIC_API_BASE_URL: http://${HOST_IP}:3000
|
||||
|
|
@ -119,17 +119,8 @@ services:
|
|||
|
||||
client:
|
||||
container_name: readest-client
|
||||
build:
|
||||
context: ..
|
||||
target: production-stage
|
||||
args:
|
||||
NEXT_PUBLIC_SUPABASE_URL: http://${HOST_IP}:${KONG_HTTP_PORT:-8000}
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${ANON_KEY}
|
||||
NEXT_PUBLIC_APP_PLATFORM: web
|
||||
NEXT_PUBLIC_API_BASE_URL: http://${HOST_IP}:3000
|
||||
NEXT_PUBLIC_OBJECT_STORAGE_TYPE: s3
|
||||
NEXT_PUBLIC_STORAGE_FIXED_QUOTA: ${STORAGE_FIXED_QUOTA}
|
||||
NEXT_PUBLIC_TRANSLATION_FIXED_QUOTA: ${TRANSLATION_FIXED_QUOTA}
|
||||
image: ${READEST_IMAGE:-ghcr.io/readest/readest:latest}
|
||||
pull_policy: missing
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
|
@ -143,13 +134,19 @@ services:
|
|||
# - /app/packages/foliate-js/node_modules
|
||||
environment:
|
||||
SUPABASE_URL: http://kong:8000
|
||||
SUPABASE_PUBLIC_URL: http://${HOST_IP}:${KONG_HTTP_PORT:-8000}
|
||||
SUPABASE_ANON_KEY: ${ANON_KEY}
|
||||
SUPABASE_ADMIN_KEY: ${SERVICE_ROLE_KEY}
|
||||
S3_ENDPOINT: http://${HOST_IP}:9000
|
||||
API_BASE_URL: ${SITE_URL}
|
||||
S3_ENDPOINT: http://minio:9000
|
||||
S3_PUBLIC_ENDPOINT: http://${HOST_IP}:9000
|
||||
S3_REGION: us-east-1
|
||||
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
|
||||
S3_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
|
||||
S3_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
|
||||
OBJECT_STORAGE_TYPE: ${OBJECT_STORAGE_TYPE:-s3}
|
||||
STORAGE_FIXED_QUOTA: ${STORAGE_FIXED_QUOTA:-1073741824}
|
||||
TRANSLATION_FIXED_QUOTA: ${TRANSLATION_FIXED_QUOTA:-50000}
|
||||
depends_on:
|
||||
- kong
|
||||
- minio
|
||||
|
|
@ -157,4 +154,4 @@ services:
|
|||
volumes:
|
||||
db-config:
|
||||
db-data:
|
||||
minio-data:
|
||||
minio-data:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue