Simplify Docker self-hosting configuration
This commit is contained in:
parent
2d01ce5196
commit
d490dde51f
@ -15,9 +15,11 @@ VITE_APP_ID=open-seo
|
||||
# # PORT=3001
|
||||
|
||||
# -------------------------------------------------------------
|
||||
# --- Docker self-hosting only (standalone local mode) ---
|
||||
# --- Docker self-hosting only (local mode) ---
|
||||
# See SELF_HOSTING_DOCKER.md
|
||||
# Docker compose runs with BYPASS_GATEWAY_LOCAL_ONLY=true.
|
||||
# Optional host/container port (defaults to 3001):
|
||||
# PORT=3001
|
||||
# Optional in .env because compose already sets it.
|
||||
# BYPASS_GATEWAY_LOCAL_ONLY=true
|
||||
# Optional override (defaults to open-seo):
|
||||
@ -26,4 +28,4 @@ VITE_APP_ID=open-seo
|
||||
# # See README.md for instructions for how to get this.
|
||||
# DATAFORSEO_API_KEY=
|
||||
|
||||
# Legacy gateway auth keys are not needed in standalone Docker mode.
|
||||
# Legacy gateway auth keys are not needed in Docker self-host mode.
|
||||
|
||||
@ -12,7 +12,7 @@ OpenSEO is an SEO tool for _the people_. If tools like Semrush or Ahrefs are too
|
||||
- [Community](#community)
|
||||
- [Pricing / Costs (Free + API costs)](#pricing--costs)
|
||||
- [Self Hosting (Deploy on Cloudflare) \[5-10 minutes\]](#self-hosting-deploy-on-cloudflare-5-10-minutes)
|
||||
- [Docker Self Hosting (Standalone OpenSEO)](#docker-self-hosting-standalone-openseo)
|
||||
- [Docker Self Hosting](#docker-self-hosting)
|
||||
- [Local Development](#local-development)
|
||||
- [Contributing](#contributing)
|
||||
- [SEO API Cost Reference](#seo-api-cost-reference)
|
||||
@ -144,14 +144,14 @@ npx wrangler secret put DATAFORSEO_API_KEY
|
||||
|
||||
Now you're all set! Go back to the gateway, click on the OpenSEO app, and start getting better at SEO!
|
||||
|
||||
## Docker Self Hosting (Standalone OpenSEO)
|
||||
## Docker Self Hosting
|
||||
|
||||
Quickstart:
|
||||
|
||||
1. `cp .env.example .env`
|
||||
2. Set `DATAFORSEO_API_KEY` in `.env`
|
||||
3. `docker compose up`
|
||||
4. Open `http://localhost:3001`
|
||||
4. Open `http://localhost:<PORT>` (default `3001`)
|
||||
|
||||
For runtime details, caveats, and troubleshooting, see [`SELF_HOSTING_DOCKER.md`](./SELF_HOSTING_DOCKER.md).
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Docker Self-Hosting (Standalone OpenSEO)
|
||||
# Docker Self-Hosting
|
||||
|
||||
This guide runs OpenSEO as a standalone local service without Every App Gateway.
|
||||
This guide runs OpenSEO as a local service without Every App Gateway.
|
||||
|
||||
In this mode, OpenSEO runs with `BYPASS_GATEWAY_LOCAL_ONLY=true`, so authentication and Gateway-managed user accounts are disabled.
|
||||
|
||||
@ -32,7 +32,7 @@ Required:
|
||||
|
||||
Optional:
|
||||
|
||||
- `OPENAI_API_KEY`
|
||||
- `PORT` (defaults to `3001`)
|
||||
- `VITE_APP_ID` (defaults to `open-seo`)
|
||||
- `BYPASS_GATEWAY_LOCAL_ONLY=true` (Docker compose already sets this)
|
||||
|
||||
@ -44,7 +44,7 @@ docker compose up
|
||||
|
||||
URL:
|
||||
|
||||
- OpenSEO: `http://localhost:3001`
|
||||
- OpenSEO: `http://localhost:<PORT>` (defaults to `3001`)
|
||||
|
||||
Boot behavior:
|
||||
|
||||
|
||||
11
compose.yaml
11
compose.yaml
@ -5,22 +5,21 @@ services:
|
||||
dockerfile: self-host/Dockerfile.selfhost
|
||||
working_dir: /app
|
||||
environment:
|
||||
- PORT=3001
|
||||
- PORT=${PORT:-3001}
|
||||
- BYPASS_GATEWAY_LOCAL_ONLY=true
|
||||
- VITE_APP_ID=${VITE_APP_ID:-open-seo}
|
||||
- VITE_GATEWAY_URL=${VITE_GATEWAY_URL:-http://localhost:3001}
|
||||
- GATEWAY_URL=${GATEWAY_URL:-http://localhost:3001}
|
||||
- VITE_GATEWAY_URL=${VITE_GATEWAY_URL:-http://localhost:${PORT:-3001}}
|
||||
- GATEWAY_URL=${GATEWAY_URL:-http://localhost:${PORT:-3001}}
|
||||
- DATAFORSEO_API_KEY=${DATAFORSEO_API_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
||||
- VITE_SHOW_DEVTOOLS=false
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"pnpm run db:migrate:local && pnpm exec vite dev --host 0.0.0.0 --port 3001",
|
||||
"pnpm run db:migrate:local && pnpm exec vite dev --host 0.0.0.0 --port ${PORT:-3001}",
|
||||
]
|
||||
ports:
|
||||
- "127.0.0.1:3001:3001"
|
||||
- "127.0.0.1:${PORT:-3001}:${PORT:-3001}"
|
||||
volumes:
|
||||
- .:/app
|
||||
- open_seo_node_modules:/app/node_modules
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
"drizzle.config.ts",
|
||||
// DB index re-exports schema for convenience
|
||||
"src/db/index.ts",
|
||||
// Docker self-host runtime entrypoint scripts
|
||||
"self-host/scripts/*.mjs",
|
||||
],
|
||||
"project": ["**/*.{js,mjs,ts,tsx}", "!src/routeTree.gen.ts"],
|
||||
"ignore": [
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
FROM node:22
|
||||
|
||||
ENV PNPM_HOME=/pnpm
|
||||
ENV PATH=$PNPM_HOME:$PATH
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
COPY self-host/scripts/resolve-gateway-tag.mjs self-host/scripts/download-archive.mjs /tmp/scripts/
|
||||
|
||||
ARG GATEWAY_RELEASE_TAG=
|
||||
RUN gateway_tag=$(node /tmp/scripts/resolve-gateway-tag.mjs) \
|
||||
&& echo "Downloading Gateway source for tag: ${gateway_tag}" \
|
||||
&& node /tmp/scripts/download-archive.mjs "https://github.com/every-app/every-app/archive/refs/tags/${gateway_tag}.tar.gz" /tmp/every-app-source.tar.gz \
|
||||
&& mkdir -p /tmp/every-app-source \
|
||||
&& tar -xzf /tmp/every-app-source.tar.gz -C /tmp/every-app-source \
|
||||
&& source_root=$(find /tmp/every-app-source -mindepth 1 -maxdepth 1 -type d | head -n 1) \
|
||||
&& cp -R "$source_root/apps/every-app-gateway/." /app \
|
||||
&& rm -rf /tmp/every-app-source /tmp/every-app-source.tar.gz /tmp/scripts
|
||||
|
||||
RUN pnpm install --frozen-lockfile
|
||||
@ -1,20 +0,0 @@
|
||||
// Downloads a file from a URL and writes it to a local path.
|
||||
// Usage: node self-host/scripts/download-archive.mjs <url> <output-path>
|
||||
|
||||
import { writeFileSync } from "node:fs";
|
||||
|
||||
const [url, outputPath] = process.argv.slice(2);
|
||||
|
||||
if (!url || !outputPath) {
|
||||
console.error(
|
||||
"Usage: node self-host/scripts/download-archive.mjs <url> <output-path>",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to download source archive: " + String(res.status));
|
||||
}
|
||||
|
||||
writeFileSync(outputPath, Buffer.from(await res.arrayBuffer()));
|
||||
@ -1,23 +0,0 @@
|
||||
// Resolves the gateway release tag to use for the selfhost Docker build.
|
||||
// If GATEWAY_RELEASE_TAG is set, prints it and exits.
|
||||
// Otherwise fetches the latest release tag from the GitHub API.
|
||||
|
||||
const tag = process.env.GATEWAY_RELEASE_TAG;
|
||||
if (tag) {
|
||||
process.stdout.write(tag);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const res = await fetch(
|
||||
"https://api.github.com/repos/every-app/every-app/releases/latest",
|
||||
);
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to resolve latest release: " + String(res.status));
|
||||
}
|
||||
|
||||
const parsed = await res.json();
|
||||
if (!parsed.tag_name) {
|
||||
throw new Error("Missing tag_name in latest release payload");
|
||||
}
|
||||
|
||||
process.stdout.write(parsed.tag_name);
|
||||
Loading…
x
Reference in New Issue
Block a user