mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-13 10:22:21 +02:00
Merge pull request #6085 from Glitch3dPenguin/fix/5728-ghcr-registry-image
fix(docker): immutable sha-pinned main image tag + registry image with build fallback in compose
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
name: ci / docker publish
|
name: ci / docker publish
|
||||||
|
|
||||||
# Build the Odysseus image and publish to GHCR.
|
# Build the Odysseus image and publish to GHCR.
|
||||||
# push to main -> :latest, :X.Y.Z (curated release; main is fast-forwarded at releases)
|
# push to main -> :latest, :X.Y.Z, :X.Y.Z-<sha> (curated release; main is fast-forwarded at releases;
|
||||||
# push to dev -> :dev, :X.Y.Z-dev.<sha> (rolling dev + an immutable, traceable pin)
|
# :X.Y.Z-<sha> is an immutable, traceable prod pin — APP_VERSION may
|
||||||
|
# not move between builds, so the bare :X.Y.Z tag alone is mutable)
|
||||||
|
# push to dev -> :dev, :X.Y.Z-dev.<sha> (rolling dev + an immutable, traceable pin)
|
||||||
# Multi-arch (linux/amd64 + linux/arm64): each arch builds on its own native
|
# Multi-arch (linux/amd64 + linux/arm64): each arch builds on its own native
|
||||||
# runner and pushes by digest, then a merge job stitches the digests into one
|
# runner and pushes by digest, then a merge job stitches the digests into one
|
||||||
# manifest list and applies the tags (faster + cleaner than QEMU emulation).
|
# manifest list and applies the tags (faster + cleaner than QEMU emulation).
|
||||||
@@ -120,6 +122,7 @@ jobs:
|
|||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
type=raw,value=${{ steps.ver.outputs.version }},enable=${{ github.ref == 'refs/heads/main' }}
|
type=raw,value=${{ steps.ver.outputs.version }},enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
|
type=raw,value=${{ steps.ver.outputs.version }}-${{ steps.ver.outputs.short }},enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
type=raw,value=dev,enable=${{ github.ref == 'refs/heads/dev' }}
|
type=raw,value=dev,enable=${{ github.ref == 'refs/heads/dev' }}
|
||||||
type=raw,value=${{ steps.ver.outputs.version }}-dev.${{ steps.ver.outputs.short }},enable=${{ github.ref == 'refs/heads/dev' }}
|
type=raw,value=${{ steps.ver.outputs.version }}-dev.${{ steps.ver.outputs.short }},enable=${{ github.ref == 'refs/heads/dev' }}
|
||||||
- name: Create manifest list + push tags
|
- name: Create manifest list + push tags
|
||||||
@@ -135,8 +138,16 @@ jobs:
|
|||||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||||
- name: Inspect
|
- name: Inspect
|
||||||
run: |
|
run: |
|
||||||
if [ "$GITHUB_REF" = "refs/heads/main" ]; then ref=latest; else ref=dev; fi
|
# main: verify both the mutable :latest and the immutable :X.Y.Z-<sha> prod pin
|
||||||
docker buildx imagetools inspect "${REGISTRY}/${IMAGE_NAME}:${ref}"
|
# actually resolved in the registry; dev: verify :dev.
|
||||||
|
if [ "$GITHUB_REF" = "refs/heads/main" ]; then
|
||||||
|
refs=("latest" "${{ steps.ver.outputs.version }}-${{ steps.ver.outputs.short }}")
|
||||||
|
else
|
||||||
|
refs=("dev")
|
||||||
|
fi
|
||||||
|
for ref in "${refs[@]}"; do
|
||||||
|
docker buildx imagetools inspect "${REGISTRY}/${IMAGE_NAME}:${ref}"
|
||||||
|
done
|
||||||
env:
|
env:
|
||||||
REGISTRY: ${{ env.REGISTRY }}
|
REGISTRY: ${{ env.REGISTRY }}
|
||||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ docker compose up -d --build
|
|||||||
|
|
||||||
Open `http://localhost:7000` when the containers are healthy. The first admin password is printed in `docker compose logs odysseus`.
|
Open `http://localhost:7000` when the containers are healthy. The first admin password is printed in `docker compose logs odysseus`.
|
||||||
|
|
||||||
|
The compose files pull the official multi-arch image `ghcr.io/odysseus-dev/odysseus` (published by CI on every push to `main` and `dev`) and only build locally if the pull fails — so this also works on hosts without a build toolchain, e.g. as a [Portainer](https://www.portainer.io/) stack.
|
||||||
|
|
||||||
|
**Production deployments:** pin the immutable tag instead of `:latest`. `:latest` and bare `:X.Y.Z` tags move on every push to `main`, but `:X.Y.Z-<sha>` (e.g. `1.0.2-7c8070f`) always refers to one specific build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ODYSSEUS_IMAGE=ghcr.io/odysseus-dev/odysseus:1.0.2-7c8070f docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
Native installs, GPU notes, Windows/macOS instructions, HTTPS, and configuration live in the [setup guide](website/setup.md).
|
Native installs, GPU notes, Windows/macOS instructions, HTTPS, and configuration live in the [setup guide](website/setup.md).
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|||||||
@@ -12,6 +12,15 @@
|
|||||||
# host's numeric render group id when needed. See docker/gpu.amd.yml for details.
|
# host's numeric render group id when needed. See docker/gpu.amd.yml for details.
|
||||||
services:
|
services:
|
||||||
odysseus:
|
odysseus:
|
||||||
|
# Official multi-arch GHCR image (linux/amd64 + linux/arm64), published by
|
||||||
|
# the "ci / docker publish" workflow on every push to main and dev.
|
||||||
|
# Docker pulls this image when it is reachable, and only falls back to the
|
||||||
|
# local build below when the pull fails (e.g. no network on the host), so
|
||||||
|
# hosts without a build toolchain (Portainer stacks, etc.) get the
|
||||||
|
# registry build. For production, pin an immutable tag via ODYSSEUS_IMAGE
|
||||||
|
# - e.g. ghcr.io/odysseus-dev/odysseus:1.0.2-7c8070f (X.Y.Z-<sha>) - since
|
||||||
|
# :latest and bare :X.Y.Z tags move on every main push.
|
||||||
|
image: ${ODYSSEUS_IMAGE:-ghcr.io/odysseus-dev/odysseus:latest}
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- "${APP_BIND:-127.0.0.1}:${APP_PORT:-7000}:7000"
|
- "${APP_BIND:-127.0.0.1}:${APP_PORT:-7000}:7000"
|
||||||
|
|||||||
@@ -11,6 +11,15 @@
|
|||||||
# for setup details.
|
# for setup details.
|
||||||
services:
|
services:
|
||||||
odysseus:
|
odysseus:
|
||||||
|
# Official multi-arch GHCR image (linux/amd64 + linux/arm64), published by
|
||||||
|
# the "ci / docker publish" workflow on every push to main and dev.
|
||||||
|
# Docker pulls this image when it is reachable, and only falls back to the
|
||||||
|
# local build below when the pull fails (e.g. no network on the host), so
|
||||||
|
# hosts without a build toolchain (Portainer stacks, etc.) get the
|
||||||
|
# registry build. For production, pin an immutable tag via ODYSSEUS_IMAGE
|
||||||
|
# - e.g. ghcr.io/odysseus-dev/odysseus:1.0.2-7c8070f (X.Y.Z-<sha>) - since
|
||||||
|
# :latest and bare :X.Y.Z tags move on every main push.
|
||||||
|
image: ${ODYSSEUS_IMAGE:-ghcr.io/odysseus-dev/odysseus:latest}
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- "${APP_BIND:-127.0.0.1}:${APP_PORT:-7000}:7000"
|
- "${APP_BIND:-127.0.0.1}:${APP_PORT:-7000}:7000"
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
services:
|
services:
|
||||||
odysseus:
|
odysseus:
|
||||||
|
# Official multi-arch GHCR image (linux/amd64 + linux/arm64), published by
|
||||||
|
# the "ci / docker publish" workflow on every push to main and dev.
|
||||||
|
# Docker pulls this image when it is reachable, and only falls back to the
|
||||||
|
# local build below when the pull fails (e.g. no network on the host), so
|
||||||
|
# hosts without a build toolchain (Portainer stacks, etc.) get the
|
||||||
|
# registry build. For production, pin an immutable tag via ODYSSEUS_IMAGE
|
||||||
|
# — e.g. ghcr.io/odysseus-dev/odysseus:1.0.2-7c8070f (X.Y.Z-<sha>) — since
|
||||||
|
# :latest and bare :X.Y.Z tags move on every main push.
|
||||||
|
image: ${ODYSSEUS_IMAGE:-ghcr.io/odysseus-dev/odysseus:latest}
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- "${APP_BIND:-127.0.0.1}:${APP_PORT:-7000}:7000"
|
- "${APP_BIND:-127.0.0.1}:${APP_PORT:-7000}:7000"
|
||||||
|
|||||||
@@ -30,6 +30,24 @@ docker compose up -d --build
|
|||||||
```
|
```
|
||||||
To include optional extras in the image (PDF viewer, Office extraction; includes AGPL PyMuPDF), build with `docker compose build --build-arg INSTALL_OPTIONAL=true` before `up`.
|
To include optional extras in the image (PDF viewer, Office extraction; includes AGPL PyMuPDF), build with `docker compose build --build-arg INSTALL_OPTIONAL=true` before `up`.
|
||||||
|
|
||||||
|
**Official Docker images.** The compose files reference the official multi-arch image `ghcr.io/odysseus-dev/odysseus`, which CI (the `ci / docker publish` workflow) publishes on every push to `main` and `dev`. When the image is reachable, Compose pulls it instead of building — so the same files work on hosts without a build toolchain (Portainer stacks, Coolify, etc.). `--build` forces a local build regardless.
|
||||||
|
|
||||||
|
Tag scheme:
|
||||||
|
|
||||||
|
| Tag | Meaning |
|
||||||
|
| --- | --- |
|
||||||
|
| `:latest`, `:X.Y.Z` | Latest curated build from `main`. **Mutable** — re-pushed on every push to `main`, even without a version bump. |
|
||||||
|
| `:X.Y.Z-<sha>` | Immutable build pin (e.g. `1.0.2-7c8070f`). One tag, one build, forever. **Use this in production.** |
|
||||||
|
| `:dev`, `:X.Y.Z-dev.<sha>` | Rolling `dev` branch builds; the `<sha>` form is also immutable. |
|
||||||
|
|
||||||
|
For production, pin the immutable tag by overriding the image in `.env` (or the stack's environment variables):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ODYSSEUS_IMAGE=ghcr.io/odysseus-dev/odysseus:1.0.2-7c8070f
|
||||||
|
```
|
||||||
|
|
||||||
|
Browse current tags at <https://github.com/odysseus-dev/odysseus/pkgs/container/odysseus>. (Until this package is made public and linked to the repo by an org owner, pulls fall back to the local build automatically — that fallback is intentional.)
|
||||||
|
|
||||||
Open `http://localhost:7000` when the containers are healthy. Docker Compose
|
Open `http://localhost:7000` when the containers are healthy. Docker Compose
|
||||||
binds the web UI to `127.0.0.1` by default. If the port is taken, set
|
binds the web UI to `127.0.0.1` by default. If the port is taken, set
|
||||||
`APP_PORT=7001` in `.env` and recreate the container. Set `APP_BIND=0.0.0.0`
|
`APP_PORT=7001` in `.env` and recreate the container. Set `APP_BIND=0.0.0.0`
|
||||||
|
|||||||
Reference in New Issue
Block a user