chore: publish OpenSEO Docker images and use image-first self-host flow (#18)
* chore: add published Docker image workflow and self-host image flow * fix: align Docker publish and build paths Use the canonical GHCR image name and correct Dockerfile path references so CI publishing and documented local builds work as expected. * fix: restore Docker self-host runtime defaults Use the full Node base image and expose Compose env vars to the Cloudflare Vite runtime so local self-hosting keeps auth bindings and outbound HTTPS working.
This commit is contained in:
parent
b9c1061934
commit
33173f5c04
11
.dockerignore
Normal file
11
.dockerignore
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.git
|
||||||
|
.github
|
||||||
|
.logs
|
||||||
|
.wrangler
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
coverage
|
||||||
|
*.log
|
||||||
|
Dockerfile
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
@ -7,6 +7,9 @@
|
|||||||
# Optional app port
|
# Optional app port
|
||||||
# PORT=3001
|
# PORT=3001
|
||||||
|
|
||||||
|
# Optional image tag override for Docker self-hosting
|
||||||
|
# OPEN_SEO_IMAGE=ghcr.io/every-app/open-seo:latest
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Auth mode
|
# Auth mode
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|||||||
57
.github/workflows/docker-image.yml
vendored
Normal file
57
.github/workflows/docker-image.yml
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
name: Publish Docker image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract Docker metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ghcr.io/every-app/open-seo
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=tag
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=sha,prefix=sha-
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: Dockerfile.selfhost
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
# Use the full Node image so workerd has a working CA trust store for outbound HTTPS.
|
||||||
FROM node:22
|
FROM node:22
|
||||||
|
|
||||||
ENV PNPM_HOME=/pnpm
|
ENV PNPM_HOME=/pnpm
|
||||||
@ -8,5 +9,10 @@ WORKDIR /app
|
|||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
|
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml ./
|
||||||
|
|
||||||
RUN pnpm install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 3001
|
||||||
|
|
||||||
|
CMD ["sh", "-c", "pnpm run db:migrate:local && pnpm exec vite dev --host 0.0.0.0 --port ${PORT:-3001}"]
|
||||||
|
|||||||
15
README.md
15
README.md
@ -81,6 +81,7 @@ printf '%s' 'YOUR_LOGIN:YOUR_PASSWORD' | base64
|
|||||||
4. Set this as `DATAFORSEO_API_KEY` in your environment file:
|
4. Set this as `DATAFORSEO_API_KEY` in your environment file:
|
||||||
|
|
||||||
- Docker self-hosting: `.env`
|
- Docker self-hosting: `.env`
|
||||||
|
- Cloudflare: Set it in the workers UI
|
||||||
- Local development: `.env.local`
|
- Local development: `.env.local`
|
||||||
|
|
||||||
## Self-hosting
|
## Self-hosting
|
||||||
@ -113,9 +114,21 @@ Quickstart:
|
|||||||
|
|
||||||
1. `cp .env.example .env`
|
1. `cp .env.example .env`
|
||||||
2. Set `DATAFORSEO_API_KEY` in `.env`
|
2. Set `DATAFORSEO_API_KEY` in `.env`
|
||||||
3. `docker compose up`
|
3. `docker compose up -d`
|
||||||
4. Open `http://localhost:<PORT>` (default `3001`)
|
4. Open `http://localhost:<PORT>` (default `3001`)
|
||||||
|
|
||||||
|
Docker Compose passes `.env` values into the container, and the Docker self-host flow enables `CLOUDFLARE_INCLUDE_PROCESS_ENV=true` so the Cloudflare Vite runtime can read them as Worker bindings.
|
||||||
|
|
||||||
|
By default, `compose.yaml` pulls the published image from GHCR:
|
||||||
|
|
||||||
|
- `ghcr.io/every-app/open-seo:latest`
|
||||||
|
|
||||||
|
Use a pinned version tag in `.env` if preferred:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
OPEN_SEO_IMAGE=ghcr.io/every-app/open-seo:v1.2.3
|
||||||
|
```
|
||||||
|
|
||||||
For more info, see [`SELF_HOSTING_DOCKER.md`](./SELF_HOSTING_DOCKER.md).
|
For more info, see [`SELF_HOSTING_DOCKER.md`](./SELF_HOSTING_DOCKER.md).
|
||||||
|
|
||||||
## Cloudflare Self-Hosting
|
## Cloudflare Self-Hosting
|
||||||
|
|||||||
@ -4,6 +4,10 @@ Run OpenSEO locally with Docker.
|
|||||||
|
|
||||||
In Docker mode, OpenSEO uses `AUTH_MODE=local_noauth` (no auth checks, local admin user `admin@localhost`).
|
In Docker mode, OpenSEO uses `AUTH_MODE=local_noauth` (no auth checks, local admin user `admin@localhost`).
|
||||||
|
|
||||||
|
The default `compose.yaml` uses the published GHCR image:
|
||||||
|
|
||||||
|
- `ghcr.io/every-app/open-seo:latest`
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Docker Desktop (or Docker Engine + Docker Compose)
|
- Docker Desktop (or Docker Engine + Docker Compose)
|
||||||
@ -12,15 +16,36 @@ In Docker mode, OpenSEO uses `AUTH_MODE=local_noauth` (no auth checks, local adm
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
docker compose up
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Set `DATAFORSEO_API_KEY` in `.env`, then open `http://localhost:<PORT>` (default `3001`).
|
Set `DATAFORSEO_API_KEY` in `.env`, then open `http://localhost:<PORT>` (default `3001`).
|
||||||
|
|
||||||
|
Docker Compose passes `.env` values into the container, and `compose.yaml` enables `CLOUDFLARE_INCLUDE_PROCESS_ENV=true` so the Cloudflare Vite runtime can read them as Worker bindings during local self-hosting.
|
||||||
|
|
||||||
Optional env values:
|
Optional env values:
|
||||||
|
|
||||||
- `PORT` (defaults to `3001`)
|
- `PORT` (defaults to `3001`)
|
||||||
- `AUTH_MODE=local_noauth` (already set in compose)
|
- `AUTH_MODE=local_noauth` (already set in compose)
|
||||||
|
- `OPEN_SEO_IMAGE` (defaults to `ghcr.io/every-app/open-seo:latest`)
|
||||||
|
|
||||||
|
## Pin to a specific image tag
|
||||||
|
|
||||||
|
Set `OPEN_SEO_IMAGE` in `.env` and restart:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
OPEN_SEO_IMAGE=ghcr.io/every-app/open-seo:v1.2.3
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build your own image locally
|
||||||
|
|
||||||
|
If you are testing local code changes, build and run a local tag:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -f Dockerfile.selfhost -t open-seo:local .
|
||||||
|
OPEN_SEO_IMAGE=open-seo:local docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
## Common commands
|
## Common commands
|
||||||
|
|
||||||
@ -30,10 +55,10 @@ Optional env values:
|
|||||||
docker compose up -d open-seo
|
docker compose up -d open-seo
|
||||||
```
|
```
|
||||||
|
|
||||||
- Rebuild image (after dependency or Docker config changes):
|
- Pull latest published image and restart:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up --build
|
docker compose pull && docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
- Stop:
|
- Stop:
|
||||||
|
|||||||
21
compose.yaml
21
compose.yaml
@ -1,26 +1,17 @@
|
|||||||
services:
|
services:
|
||||||
open-seo:
|
open-seo:
|
||||||
build:
|
image: ${OPEN_SEO_IMAGE:-ghcr.io/every-app/open-seo:latest}
|
||||||
context: .
|
restart: unless-stopped
|
||||||
dockerfile: Dockerfile.selfhost
|
|
||||||
working_dir: /app
|
|
||||||
environment:
|
environment:
|
||||||
|
# Required for local Docker self-hosting: exposes Compose env vars to cloudflare:workers bindings.
|
||||||
|
- CLOUDFLARE_INCLUDE_PROCESS_ENV=true
|
||||||
- PORT=${PORT:-3001}
|
- PORT=${PORT:-3001}
|
||||||
- AUTH_MODE=local_noauth
|
- AUTH_MODE=local_noauth
|
||||||
- DATAFORSEO_API_KEY=${DATAFORSEO_API_KEY}
|
- DATAFORSEO_API_KEY=${DATAFORSEO_API_KEY}
|
||||||
- VITE_SHOW_DEVTOOLS=false
|
- VITE_SHOW_DEVTOOLS=false
|
||||||
command:
|
|
||||||
[
|
|
||||||
"sh",
|
|
||||||
"-c",
|
|
||||||
"pnpm run db:migrate:local && pnpm exec vite dev --host 0.0.0.0 --port ${PORT:-3001}",
|
|
||||||
]
|
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:${PORT:-3001}:${PORT:-3001}"
|
- "127.0.0.1:${PORT:-3001}:${PORT:-3001}"
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- open_seo_data:/app/.wrangler
|
||||||
- open_seo_node_modules:/app/node_modules
|
|
||||||
- open_seo_pnpm_store:/pnpm/store
|
|
||||||
volumes:
|
volumes:
|
||||||
open_seo_node_modules:
|
open_seo_data:
|
||||||
open_seo_pnpm_store:
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user