Standalone OpenSEO docker
This commit is contained in:
parent
c20ea9f851
commit
2acf943346
23
.env.example
23
.env.example
@ -15,22 +15,15 @@ VITE_APP_ID=open-seo
|
|||||||
# # PORT=3001
|
# # PORT=3001
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# --- Docker self-hosting only (see SELF_HOSTING_DOCKER.md) ---
|
# --- Docker self-hosting only (standalone local mode) ---
|
||||||
# For Docker, set GATEWAY_URL and VITE_GATEWAY_URL to:
|
# See SELF_HOSTING_DOCKER.md
|
||||||
# http://every-app-gateway.localhost:3000
|
# Docker compose runs with BYPASS_GATEWAY_LOCAL_ONLY=true.
|
||||||
# VITE_GATEWAY_URL=http://every-app-gateway.localhost:3000
|
# Optional in .env.local because compose already sets it.
|
||||||
# GATEWAY_URL=http://every-app-gateway.localhost:3000
|
# BYPASS_GATEWAY_LOCAL_ONLY=true
|
||||||
#
|
# Optional override (defaults to open-seo):
|
||||||
# Optional: pin to a specific Gateway release tag.
|
# VITE_APP_ID=open-seo
|
||||||
# By default the latest release is pulled automatically (recommended).
|
|
||||||
# GATEWAY_RELEASE_TAG=
|
|
||||||
|
|
||||||
# # See README.md for instructions for how to get this.
|
# # See README.md for instructions for how to get this.
|
||||||
# DATAFORSEO_API_KEY=
|
# DATAFORSEO_API_KEY=
|
||||||
|
|
||||||
# Required for Gateway auth when running Docker self-host.
|
# Legacy gateway auth keys are not needed in standalone Docker mode.
|
||||||
# Generate with: pnpm run docker:generate-secrets
|
|
||||||
# Validate with: pnpm run docker:check-env
|
|
||||||
# BETTER_AUTH_SECRET=
|
|
||||||
# JWT_PRIVATE_KEY=""
|
|
||||||
# JWT_PUBLIC_KEY=""
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ OpenSEO is an SEO tool for _the people_. If tools like Semrush or Ahrefs are too
|
|||||||
- [Community](#community)
|
- [Community](#community)
|
||||||
- [Pricing / Costs (Free + API costs)](#pricing--costs)
|
- [Pricing / Costs (Free + API costs)](#pricing--costs)
|
||||||
- [Self Hosting (Deploy on Cloudflare) \[5-10 minutes\]](#self-hosting-deploy-on-cloudflare-5-10-minutes)
|
- [Self Hosting (Deploy on Cloudflare) \[5-10 minutes\]](#self-hosting-deploy-on-cloudflare-5-10-minutes)
|
||||||
- [Docker Self Hosting (Gateway + OpenSEO)](#docker-self-hosting-gateway--openseo)
|
- [Docker Self Hosting (Standalone OpenSEO)](#docker-self-hosting-standalone-openseo)
|
||||||
- [Local Development](#local-development)
|
- [Local Development](#local-development)
|
||||||
- [Contributing](#contributing)
|
- [Contributing](#contributing)
|
||||||
- [SEO API Cost Reference](#seo-api-cost-reference)
|
- [SEO API Cost Reference](#seo-api-cost-reference)
|
||||||
@ -144,9 +144,9 @@ 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!
|
Now you're all set! Go back to the gateway, click on the OpenSEO app, and start getting better at SEO!
|
||||||
|
|
||||||
## Docker Self Hosting (Gateway + OpenSEO)
|
## Docker Self Hosting (Standalone OpenSEO)
|
||||||
|
|
||||||
If you want a single Docker Compose command that runs both Every App Gateway and OpenSEO together, see [`SELF_HOSTING_DOCKER.md`](./SELF_HOSTING_DOCKER.md).
|
If you want a single Docker Compose command that runs OpenSEO locally without Gateway auth, see [`SELF_HOSTING_DOCKER.md`](./SELF_HOSTING_DOCKER.md).
|
||||||
|
|
||||||
This runtime uses local dev servers to emulate Cloudflare Worker bindings. It is intended for **local use only** — do not expose ports directly to the public internet. For remote access, use [Tailscale](https://tailscale.com/). For internet-facing deployments, use the Cloudflare deployment path above. See the [security and runtime caveats](./SELF_HOSTING_DOCKER.md#security-and-runtime-caveats) in the Docker guide for details.
|
This runtime uses local dev servers to emulate Cloudflare Worker bindings. It is intended for **local use only** — do not expose ports directly to the public internet. For remote access, use [Tailscale](https://tailscale.com/). For internet-facing deployments, use the Cloudflare deployment path above. See the [security and runtime caveats](./SELF_HOSTING_DOCKER.md#security-and-runtime-caveats) in the Docker guide for details.
|
||||||
|
|
||||||
|
|||||||
@ -1,30 +1,21 @@
|
|||||||
# Docker Self-Hosting
|
# Docker Self-Hosting (Standalone OpenSEO)
|
||||||
|
|
||||||
This guide runs both Every App Gateway and OpenSEO with one Docker Compose command.
|
This guide runs OpenSEO as a standalone local service without Every App Gateway.
|
||||||
|
|
||||||
OpenSEO is an app built on Every App so things like authentication and user management are delegated to the Gateway. Every App is built with deployment to Cloudflare as its target with the goal of making self hosting more accessible to people not already running home labs. Because of that design principle, self hosting with docker is a bit complicated right now, but will hopefully will get smoother over time.
|
In this mode, OpenSEO runs with `BYPASS_GATEWAY_LOCAL_ONLY=true`, so authentication and Gateway-managed user accounts are disabled.
|
||||||
|
|
||||||
The stack uses local Cloudflare-compatible runtime behavior (`wrangler` + Vite/worker runtime) so bindings and auth behavior stay close to Workers while running on your own machine or server.
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Docker Desktop (or Docker Engine + Docker Compose)
|
- Docker Desktop (or Docker Engine + Docker Compose)
|
||||||
|
|
||||||
## Runtime model
|
|
||||||
|
|
||||||
- OpenSEO runs from this repository source in containerized local runtime mode.
|
|
||||||
- Gateway is built from `apps/every-app-gateway` source at a release tag in https://github.com/every-app/every-app
|
|
||||||
|
|
||||||
Default gateway release policy:
|
|
||||||
|
|
||||||
- Source: `every-app/every-app` releases
|
|
||||||
- Tag: latest release (recommended)
|
|
||||||
|
|
||||||
You can optionally pin to a specific release by setting `GATEWAY_RELEASE_TAG` in your env file.
|
|
||||||
|
|
||||||
## Security and runtime caveats
|
## Security and runtime caveats
|
||||||
|
|
||||||
This stack runs local dev servers to emulate Cloudflare Worker bindings — this is currently the best way to self-host outside Cloudflare, but it means dev-only surfaces (HMR, verbose errors, broader file-serving) are exposed on the serving ports. Do not expose these ports directly to the public internet. If you need remote access, use [Tailscale](https://tailscale.com/) instead of a public tunnel. For internet-facing deployments, use the [Cloudflare deployment path](./README.md#self-hosting-deploy-on-cloudflare-5-10-minutes).
|
This stack runs local dev servers to emulate Cloudflare Worker bindings and is intended for local use only.
|
||||||
|
|
||||||
|
- Do not expose these ports directly to the public internet.
|
||||||
|
- There is no Gateway auth in this mode.
|
||||||
|
- If you need remote access, use [Tailscale](https://tailscale.com/) instead of a public tunnel.
|
||||||
|
- For internet-facing deployments with auth, use the [Cloudflare deployment path](./README.md#self-hosting-deploy-on-cloudflare-5-10-minutes).
|
||||||
|
|
||||||
## 1) Configure env values
|
## 1) Configure env values
|
||||||
|
|
||||||
@ -36,24 +27,15 @@ cp .env.example .env.local
|
|||||||
|
|
||||||
Set values as needed in `.env.local`.
|
Set values as needed in `.env.local`.
|
||||||
|
|
||||||
Important values:
|
Required:
|
||||||
|
|
||||||
- `GATEWAY_URL` and `VITE_GATEWAY_URL` should be set to `http://every-app-gateway.localhost:3000` for local Docker networking and JWT issuer consistency.
|
- `DATAFORSEO_API_KEY`
|
||||||
- Add a host entry for `every-app-gateway.localhost` if needed:
|
|
||||||
- macOS/Linux: add `127.0.0.1 every-app-gateway.localhost` to `/etc/hosts`
|
|
||||||
- Windows: add `127.0.0.1 every-app-gateway.localhost` to `C:\Windows\System32\drivers\etc\hosts`
|
|
||||||
- If you use a different host or port, set both `GATEWAY_URL` and `VITE_GATEWAY_URL` to the same origin.
|
|
||||||
- `DATAFORSEO_API_KEY` is required for OpenSEO SEO-data workflows.
|
|
||||||
- See [README: DataForSEO API Key Setup](./README.md#dataforseo-api-key-setup-5-minutes).
|
|
||||||
- `BETTER_AUTH_SECRET`, `JWT_PRIVATE_KEY`, and `JWT_PUBLIC_KEY` are required for gateway auth (see how to generate them below)
|
|
||||||
|
|
||||||
Generate auth values with:
|
Optional:
|
||||||
|
|
||||||
```bash
|
- `OPENAI_API_KEY`
|
||||||
pnpm run docker:generate-secrets
|
- `VITE_APP_ID` (defaults to `open-seo`)
|
||||||
```
|
- `BYPASS_GATEWAY_LOCAL_ONLY=true` (Docker compose already sets this)
|
||||||
|
|
||||||
Copy the printed lines into `.env.local`.
|
|
||||||
|
|
||||||
Validate env before startup:
|
Validate env before startup:
|
||||||
|
|
||||||
@ -61,85 +43,43 @@ Validate env before startup:
|
|||||||
pnpm run docker:check-env
|
pnpm run docker:check-env
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2) Start both services with one command
|
## 2) Start OpenSEO
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm run docker:up
|
pnpm run docker:up
|
||||||
```
|
```
|
||||||
|
|
||||||
URLs:
|
URL:
|
||||||
|
|
||||||
- Gateway: `http://every-app-gateway.localhost:3000`
|
|
||||||
- OpenSEO: `http://localhost:3001`
|
- OpenSEO: `http://localhost:3001`
|
||||||
|
|
||||||
Gateway boot behavior:
|
Boot behavior:
|
||||||
|
|
||||||
- Resolves the latest gateway release tag (unless explicitly pinned).
|
- Uses dependencies installed during image build.
|
||||||
- Pulls gateway source for that tag, installs dependencies during image build, and runs in local runtime mode.
|
|
||||||
- Applies local D1 migrations on start.
|
- Applies local D1 migrations on start.
|
||||||
- Persists local gateway Wrangler/D1 state in Docker volume `every_app_gateway_wrangler_state`.
|
- Starts local dev runtime (Vite).
|
||||||
|
|
||||||
OpenSEO boot behavior:
|
|
||||||
|
|
||||||
- Uses dependencies installed during image build, then applies local D1 migrations on start.
|
|
||||||
- Starts local dev runtime (Vite). See [Security and runtime caveats](#security-and-runtime-caveats) above.
|
|
||||||
|
|
||||||
## 3) Bootstrap Gateway and app access
|
|
||||||
|
|
||||||
1. Open `http://every-app-gateway.localhost:3000/sign-up` and create the owner account.
|
|
||||||
2. In Gateway admin (`/admin/apps`), add OpenSEO:
|
|
||||||
- App ID: `open-seo`
|
|
||||||
- App URL: `http://localhost:3001`
|
|
||||||
- Or whatever port you have this running at
|
|
||||||
3. Start using OpenSEO by accessing it through Gateway: `http://every-app-gateway.localhost:3000/`.
|
|
||||||
|
|
||||||
## Optional: Run only one service
|
|
||||||
|
|
||||||
Run gateway only:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm run docker:check-env
|
|
||||||
docker compose -f self-host/docker-compose.yml --env-file .env.local up --build gateway
|
|
||||||
```
|
|
||||||
|
|
||||||
Run OpenSEO only (expects gateway already reachable at `GATEWAY_URL`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm run docker:check-env
|
|
||||||
docker compose -f self-host/docker-compose.yml --env-file .env.local up --build open-seo
|
|
||||||
```
|
|
||||||
|
|
||||||
## Updating gateway version
|
|
||||||
|
|
||||||
By default this stack pulls the latest published gateway release (recommended).
|
|
||||||
|
|
||||||
To pin to a specific gateway release instead:
|
|
||||||
|
|
||||||
1. Set `GATEWAY_RELEASE_TAG` in `.env.local` (for example `gateway-v0.1.11`).
|
|
||||||
2. Rebuild gateway:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose -f self-host/docker-compose.yml --env-file .env.local build --no-cache gateway
|
|
||||||
docker compose -f self-host/docker-compose.yml --env-file .env.local up -d gateway
|
|
||||||
```
|
|
||||||
|
|
||||||
When tracking latest, rebuild gateway with `--no-cache` to pull newer gateway source for the latest tag.
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
- `Issuer must be provided` or `signature verification failed`: make sure `GATEWAY_URL` and `VITE_GATEWAY_URL` both point to `http://every-app-gateway.localhost:3000`, then clear browser cookies/storage for `localhost` and `every-app-gateway.localhost` and sign in again.
|
|
||||||
- OpenSEO env values seem stale: restart OpenSEO:
|
- OpenSEO env values seem stale: restart OpenSEO:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -f self-host/docker-compose.yml --env-file .env.local up -d --build open-seo
|
docker compose -f self-host/docker-compose.yml --env-file .env.local up -d --build open-seo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- If migrations fail on first run, rebuild and retry:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run docker:down
|
||||||
|
pnpm run docker:up
|
||||||
|
```
|
||||||
|
|
||||||
## Stop and cleanup
|
## Stop and cleanup
|
||||||
|
|
||||||
Stop stack:
|
Stop stack:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -f self-host/docker-compose.yml --env-file .env.local down
|
pnpm run docker:down
|
||||||
```
|
```
|
||||||
|
|
||||||
Stop and remove Docker volumes:
|
Stop and remove Docker volumes:
|
||||||
@ -147,9 +87,3 @@ Stop and remove Docker volumes:
|
|||||||
```bash
|
```bash
|
||||||
docker compose -f self-host/docker-compose.yml --env-file .env.local down -v
|
docker compose -f self-host/docker-compose.yml --env-file .env.local down -v
|
||||||
```
|
```
|
||||||
|
|
||||||
To reset only the gateway local DB state explicitly:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker volume rm every_app_gateway_wrangler_state
|
|
||||||
```
|
|
||||||
|
|||||||
@ -2,6 +2,11 @@ FROM node:22
|
|||||||
|
|
||||||
ENV PNPM_HOME=/pnpm
|
ENV PNPM_HOME=/pnpm
|
||||||
ENV PATH=$PNPM_HOME:$PATH
|
ENV PATH=$PNPM_HOME:$PATH
|
||||||
|
ENV PORT=3001
|
||||||
|
ENV BYPASS_GATEWAY_LOCAL_ONLY=true
|
||||||
|
ENV VITE_APP_ID=open-seo
|
||||||
|
ENV VITE_GATEWAY_URL=http://localhost:3001
|
||||||
|
ENV GATEWAY_URL=http://localhost:3001
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
@ -1,28 +1,4 @@
|
|||||||
services:
|
services:
|
||||||
gateway:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: self-host/Dockerfile.gateway-selfhost
|
|
||||||
args:
|
|
||||||
GATEWAY_RELEASE_TAG: ${GATEWAY_RELEASE_TAG:-}
|
|
||||||
env_file:
|
|
||||||
- ../.env.local
|
|
||||||
command:
|
|
||||||
[
|
|
||||||
"sh",
|
|
||||||
"-c",
|
|
||||||
"pnpm run db:migrate:local && pnpm exec vite dev --host 0.0.0.0 --port 3000",
|
|
||||||
]
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:3000:3000"
|
|
||||||
volumes:
|
|
||||||
- ../.env.local:/app/.env:ro
|
|
||||||
- gateway_wrangler_state:/app/.wrangler/state
|
|
||||||
networks:
|
|
||||||
selfhost:
|
|
||||||
aliases:
|
|
||||||
- every-app-gateway.localhost
|
|
||||||
|
|
||||||
open-seo:
|
open-seo:
|
||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
@ -30,9 +6,10 @@ services:
|
|||||||
working_dir: /app
|
working_dir: /app
|
||||||
environment:
|
environment:
|
||||||
- PORT=3001
|
- PORT=3001
|
||||||
- VITE_APP_ID=${VITE_APP_ID}
|
- BYPASS_GATEWAY_LOCAL_ONLY=true
|
||||||
- VITE_GATEWAY_URL=${VITE_GATEWAY_URL}
|
- VITE_APP_ID=${VITE_APP_ID:-open-seo}
|
||||||
- GATEWAY_URL=${GATEWAY_URL}
|
- VITE_GATEWAY_URL=${VITE_GATEWAY_URL:-http://localhost:3001}
|
||||||
|
- GATEWAY_URL=${GATEWAY_URL:-http://localhost:3001}
|
||||||
- DATAFORSEO_API_KEY=${DATAFORSEO_API_KEY}
|
- DATAFORSEO_API_KEY=${DATAFORSEO_API_KEY}
|
||||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
||||||
- VITE_SHOW_DEVTOOLS=false
|
- VITE_SHOW_DEVTOOLS=false
|
||||||
@ -42,22 +19,13 @@ services:
|
|||||||
"-c",
|
"-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 3001",
|
||||||
]
|
]
|
||||||
depends_on:
|
|
||||||
- gateway
|
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:3001:3001"
|
- "127.0.0.1:3001:3001"
|
||||||
volumes:
|
volumes:
|
||||||
- ..:/app
|
- ..:/app
|
||||||
- open_seo_node_modules:/app/node_modules
|
- open_seo_node_modules:/app/node_modules
|
||||||
- open_seo_pnpm_store:/pnpm/store
|
- open_seo_pnpm_store:/pnpm/store
|
||||||
networks:
|
|
||||||
- selfhost
|
|
||||||
|
|
||||||
networks:
|
|
||||||
selfhost:
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
gateway_wrangler_state:
|
|
||||||
name: every_app_gateway_wrangler_state
|
|
||||||
open_seo_node_modules:
|
open_seo_node_modules:
|
||||||
open_seo_pnpm_store:
|
open_seo_pnpm_store:
|
||||||
|
|||||||
@ -45,15 +45,7 @@ if (!existsSync(envPath)) {
|
|||||||
|
|
||||||
const env = parseEnvFile(envPath);
|
const env = parseEnvFile(envPath);
|
||||||
|
|
||||||
const requiredKeys = [
|
const requiredKeys = ["DATAFORSEO_API_KEY"];
|
||||||
"GATEWAY_URL",
|
|
||||||
"VITE_GATEWAY_URL",
|
|
||||||
"VITE_APP_ID",
|
|
||||||
"DATAFORSEO_API_KEY",
|
|
||||||
"BETTER_AUTH_SECRET",
|
|
||||||
"JWT_PRIVATE_KEY",
|
|
||||||
"JWT_PUBLIC_KEY",
|
|
||||||
];
|
|
||||||
|
|
||||||
const missingKeys = requiredKeys.filter((key) => isBlank(env[key]));
|
const missingKeys = requiredKeys.filter((key) => isBlank(env[key]));
|
||||||
if (missingKeys.length > 0) {
|
if (missingKeys.length > 0) {
|
||||||
@ -61,32 +53,13 @@ if (missingKeys.length > 0) {
|
|||||||
for (const key of missingKeys) {
|
for (const key of missingKeys) {
|
||||||
console.error(`- ${key}`);
|
console.error(`- ${key}`);
|
||||||
}
|
}
|
||||||
console.error("\nGenerate auth keys with: pnpm run docker:generate-secrets");
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env.GATEWAY_URL !== env.VITE_GATEWAY_URL) {
|
if (isBlank(env.BYPASS_GATEWAY_LOCAL_ONLY)) {
|
||||||
console.error(
|
console.warn(
|
||||||
"GATEWAY_URL and VITE_GATEWAY_URL must match for auth issuer consistency.",
|
"Warning: BYPASS_GATEWAY_LOCAL_ONLY is not set in .env.local. Docker sets it automatically.",
|
||||||
);
|
);
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!env.JWT_PRIVATE_KEY.includes("BEGIN PRIVATE KEY")) {
|
|
||||||
console.error("JWT_PRIVATE_KEY does not look like a PEM private key.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!env.JWT_PUBLIC_KEY.includes("BEGIN PUBLIC KEY")) {
|
|
||||||
console.error("JWT_PUBLIC_KEY does not look like a PEM public key.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env.BETTER_AUTH_SECRET.trim().length < 32) {
|
|
||||||
console.error(
|
|
||||||
"BETTER_AUTH_SECRET is too short. Generate a new one with docker:generate-secrets.",
|
|
||||||
);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Env validation passed: ${envPath}`);
|
console.log(`Env validation passed: ${envPath}`);
|
||||||
|
|||||||
3
worker-configuration.d.ts
vendored
3
worker-configuration.d.ts
vendored
@ -12,6 +12,7 @@ declare namespace Cloudflare {
|
|||||||
VITE_APP_ID: string;
|
VITE_APP_ID: string;
|
||||||
VITE_GATEWAY_URL: string;
|
VITE_GATEWAY_URL: string;
|
||||||
GATEWAY_URL: string;
|
GATEWAY_URL: string;
|
||||||
|
GATEWAY_APP_API_TOKEN: string;
|
||||||
EVERY_APP_GATEWAY: Fetcher /* every-app-gateway */;
|
EVERY_APP_GATEWAY: Fetcher /* every-app-gateway */;
|
||||||
SITE_AUDIT_WORKFLOW: Workflow<Parameters<import("./src/server").SiteAuditWorkflow['run']>[0]['payload']>;
|
SITE_AUDIT_WORKFLOW: Workflow<Parameters<import("./src/server").SiteAuditWorkflow['run']>[0]['payload']>;
|
||||||
}
|
}
|
||||||
@ -21,7 +22,7 @@ type StringifyValues<EnvType extends Record<string, unknown>> = {
|
|||||||
[Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
|
[Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
|
||||||
};
|
};
|
||||||
declare namespace NodeJS {
|
declare namespace NodeJS {
|
||||||
interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "VITE_APP_ID" | "VITE_GATEWAY_URL" | "GATEWAY_URL">> {}
|
interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "VITE_APP_ID" | "VITE_GATEWAY_URL" | "GATEWAY_URL" | "GATEWAY_APP_API_TOKEN">> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin runtime types
|
// Begin runtime types
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user