From 2605eccb6419acc62bfe0384e7cb568038965cdd Mon Sep 17 00:00:00 2001 From: infosave2007 Date: Wed, 1 Jul 2026 11:23:09 +0300 Subject: [PATCH] feat: Docker image + ghcr publishing - multi-stage Dockerfile (non-root, embeds SPA, default config, ~160MB) + .dockerignore - .github/workflows/docker.yml: push to ghcr.io/infosave2007/cortiq-gateway (master -> :edge/:sha amd64; tags -> :X.Y.Z/:latest, linux/amd64+arm64) - README (EN+RU): docker run instructions; CHANGELOG - verified locally: image builds, container serves /healthz + /admin Co-Authored-By: Claude Opus 4.8 (1M context) --- .dockerignore | 10 ++++++++ .github/workflows/docker.yml | 47 ++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 3 +++ Dockerfile | 25 +++++++++++++++++++ README.md | 8 ++++++ README.ru.md | 9 +++++++ 6 files changed, 102 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/workflows/docker.yml create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6fe18bc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +target +.git +.github +docs +bench +config/gateway.toml +config/secrets.toml +config/stats.jsonl +*.log +.DS_Store diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..aa201ee --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,47 @@ +name: Docker + +# Publishes container images to GitHub Container Registry (ghcr.io). +# master push -> :edge, :sha (amd64, fast) +# tag v* -> :X.Y.Z, :X.Y, :latest, :sha (linux/amd64 + linux/arm64) +on: + push: + branches: [master] + tags: ["v*"] + workflow_dispatch: + +permissions: + contents: read + packages: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} + type=raw,value=edge,enable={{is_default_branch}} + type=sha,format=short + - uses: docker/build-push-action@v6 + with: + context: . + # multi-arch only for release tags (arm64 under emulation is slow) + platforms: ${{ startsWith(github.ref, 'refs/tags/v') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/CHANGELOG.md b/CHANGELOG.md index b36b7c3..3be93a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). (competitors have no semantic task router). - **Router docs** (`docs/ROUTER.md` + `.ru.md`): what the allaigate/cortiq-router does, how to point the gateway at it, API contract, pricing, and the current `LAUNCH1` $1 promo. +- **Docker image**: multi-stage `Dockerfile` (non-root, ~160 MB) + `docker.yml` workflow + publishing to `ghcr.io/infosave2007/cortiq-gateway` (`:latest`, `:X.Y.Z`, `:edge`; + linux/amd64 + arm64 on release tags). `docker run` works out of the box. ## [0.2.1] - 2026-06-30 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f3fbf3a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# ---- build stage ------------------------------------------------------------ +FROM rust:1-slim AS builder +WORKDIR /app +# the admin SPA (web/) is embedded at compile time via rust-embed, so it must be present +COPY Cargo.toml Cargo.lock ./ +COPY src ./src +COPY web ./web +RUN cargo build --release + +# ---- runtime stage ---------------------------------------------------------- +FROM debian:bookworm-slim +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates \ + && rm -rf /var/lib/apt/lists/* \ + && useradd -r -u 10001 cortiq \ + && mkdir -p /app/config +COPY --from=builder /app/target/release/cortiq-gateway /usr/local/bin/cortiq-gateway +# ship the example as the default config so `docker run` works out of the box +COPY config/gateway.example.toml /app/config/gateway.toml +RUN chown -R 10001:10001 /app +WORKDIR /app +USER cortiq +EXPOSE 9000 +ENTRYPOINT ["cortiq-gateway"] +CMD ["--config", "/app/config/gateway.toml"] diff --git a/README.md b/README.md index 9c85abe..6afac0c 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,11 @@ One OpenAI-compatible endpoint → automatic model selection from your pool ## 📦 Install ```bash +# Docker (GitHub Container Registry) +docker run -p 9000:9000 -e CORTIQ_ADMIN_TOKEN=secret \ + -v "$PWD/config:/app/config" ghcr.io/infosave2007/cortiq-gateway:latest +# → admin console at http://localhost:9000/admin + # from crates.io cargo install cortiq-gateway @@ -60,6 +65,9 @@ cd cortiq-gateway cargo build --release # ./target/release/cortiq-gateway ``` +The image ships a default config and runs out of the box; mount `/app/config` (with a +`gateway.toml`) to use your own. Tags: `:latest`, `:X.Y.Z`, `:edge` (linux/amd64 + arm64). + --- ## 🖥️ Admin console diff --git a/README.ru.md b/README.ru.md index 5ca874b..b546564 100644 --- a/README.ru.md +++ b/README.ru.md @@ -48,6 +48,11 @@ ## 📦 Установка ```bash +# Docker (GitHub Container Registry) +docker run -p 9000:9000 -e CORTIQ_ADMIN_TOKEN=secret \ + -v "$PWD/config:/app/config" ghcr.io/infosave2007/cortiq-gateway:latest +# → панель на http://localhost:9000/admin + # с crates.io cargo install cortiq-gateway @@ -57,6 +62,10 @@ cd cortiq-gateway cargo build --release # ./target/release/cortiq-gateway ``` +Образ идёт с дефолтным конфигом и работает из коробки; смонтируйте `/app/config` +(с `gateway.toml`), чтобы использовать свой. Теги: `:latest`, `:X.Y.Z`, `:edge` +(linux/amd64 + arm64). + --- ## 🖥️ Панель управления