From 5f045727ffe7fb6ecc66022870cd1deb840f5e76 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Mon, 20 Apr 2026 17:30:20 +0400 Subject: [PATCH 01/11] add docker directory with several docker composes --- README.md | 8 ++ apps/ensindexer/.env.local.example | 1 + apps/ensrainbow/.env.local.example | 2 +- docker-compose.yml | 127 ------------------ docker/.env.docker-compose | 16 +++ docker/README.md | 86 ++++++++++++ docker/docker-compose.devnet.yml | 75 +++++++++++ docker/docker-compose.orchestrator.yml | 19 +++ docker/docker-compose.yml | 67 +++++++++ docker/services/devnet.yml | 17 +++ docker/services/ensadmin.yml | 17 +++ docker/services/ensapi.yml | 19 +++ docker/services/ensindexer.yml | 21 +++ docker/services/ensrainbow.yml | 19 +++ docker/services/postgres.yml | 8 ++ package.json | 2 +- .../integration-test-env/src/orchestrator.ts | 6 +- 17 files changed, 380 insertions(+), 130 deletions(-) delete mode 100644 docker-compose.yml create mode 100644 docker/.env.docker-compose create mode 100644 docker/README.md create mode 100644 docker/docker-compose.devnet.yml create mode 100644 docker/docker-compose.orchestrator.yml create mode 100644 docker/docker-compose.yml create mode 100644 docker/services/devnet.yml create mode 100644 docker/services/ensadmin.yml create mode 100644 docker/services/ensapi.yml create mode 100644 docker/services/ensindexer.yml create mode 100644 docker/services/ensrainbow.yml create mode 100644 docker/services/postgres.yml diff --git a/README.md b/README.md index e56e1a5cab..12dc0e6d8b 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,14 @@ ENSNode is a modern, multichain indexer for ENS. It supports backwards-compatibl Documentation for the ENSNode suite of apps is available at [ensnode.io](https://ensnode.io). +## Running with Docker + +```bash +docker compose -f docker/docker-compose.yml up -d +``` + +See [`docker/README.md`](docker/README.md) for all use cases and commands. + ## Contributions We welcome community contributions and feedback—please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information. diff --git a/apps/ensindexer/.env.local.example b/apps/ensindexer/.env.local.example index cd5b3d948d..3a40b68470 100644 --- a/apps/ensindexer/.env.local.example +++ b/apps/ensindexer/.env.local.example @@ -243,6 +243,7 @@ ENSRAINBOW_URL=http://localhost:3223 # https://ensnode.io/ensrainbow/usage/available-label-sets # # LABEL_SET_ID: see https://ensnode.io/ensrainbow/concepts/glossary#label-set-id. +# Should match ensrainbow LABEL_SET_ID LABEL_SET_ID=subgraph # LABEL_SET_VERSION: see https://ensnode.io/ensrainbow/concepts/glossary#label-set-version. diff --git a/apps/ensrainbow/.env.local.example b/apps/ensrainbow/.env.local.example index 7eb88231b3..837519561f 100644 --- a/apps/ensrainbow/.env.local.example +++ b/apps/ensrainbow/.env.local.example @@ -16,7 +16,7 @@ LOG_LEVEL=info DB_SCHEMA_VERSION=3 # Label set ID (see https://ensnode.io/ensrainbow/concepts/glossary#label-set-id) -LABEL_SET_ID=ens-test-env +LABEL_SET_ID=subgraph # Label set version (see https://ensnode.io/ensrainbow/concepts/glossary#label-set-version) LABEL_SET_VERSION=0 diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 1f04274da8..0000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,127 +0,0 @@ -services: - ensindexer: - container_name: ensindexer - image: ghcr.io/namehash/ensnode/ensindexer:latest - ports: - - "42069:42069" - environment: - # Override environment variables to point to docker instances - ENSDB_URL: postgresql://postgres:password@postgres:5432/postgres - ENSINDEXER_SCHEMA_NAME: docker_compose_ensindexer_schema - ENSRAINBOW_URL: http://ensrainbow:3223 - env_file: - # NOTE: must define apps/ensindexer/.env.local (see apps/ensindexer/.env.local.example) - # Copy .env.local.example to .env.local and configure all required values - - path: ./apps/ensindexer/.env.local - required: true - healthcheck: - test: ["CMD", "curl", "--fail", "-s", "http://localhost:42069/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 5m - start_interval: 1s - depends_on: - ensrainbow: - condition: service_healthy - postgres: - condition: service_started - - ensapi: - container_name: ensapi - image: ghcr.io/namehash/ensnode/ensapi:latest - ports: - - "4334:4334" - environment: - # Override environment variables to point to docker instances - ENSDB_URL: postgresql://postgres:password@postgres:5432/postgres - ENSINDEXER_SCHEMA_NAME: docker_compose_ensindexer_schema - env_file: - # NOTE: must define apps/ensapi/.env.local (see apps/ensapi/.env.local.example) - # Copy .env.local.example to .env.local and configure all required values - - path: ./apps/ensapi/.env.local - required: true - healthcheck: - test: ["CMD", "curl", "--fail", "-s", "http://localhost:4334/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 1m - start_interval: 1s - depends_on: - postgres: - condition: service_started - - ensrainbow: - container_name: ensrainbow - image: ghcr.io/namehash/ensnode/ensrainbow:latest - ports: - - "3223:3223" - env_file: - # NOTE: Optionally define apps/ensrainbow/.env.local (see apps/ensrainbow/.env.local.example) - - path: ./apps/ensrainbow/.env.local - required: false - volumes: - - ensrainbow_data:/app/apps/ensrainbow/data - restart: unless-stopped - healthcheck: - test: ["CMD", "wget", "-q", "--spider", "http://localhost:3223/health"] - interval: 30s - timeout: 3s - retries: 3 - start_period: 20m - start_interval: 1s - - ensadmin: - container_name: ensadmin - image: ghcr.io/namehash/ensnode/ensadmin:latest - ports: - - "4173:4173" - environment: - # Override environment variables to point to docker instances - # NOTE: must be host-accessible (i.e. http://localhost) - ENSADMIN_PUBLIC_URL: http://localhost:4173 - # NOTE: must be host-accessible (i.e. http://localhost) - NEXT_PUBLIC_SERVER_CONNECTION_LIBRARY: http://localhost:4334 - env_file: - # NOTE: can define apps/ensadmin/.env.local (see apps/ensadmin/.env.local.example) - - path: ./apps/ensadmin/.env.local - required: false - depends_on: - ensapi: - condition: service_started - - postgres: - container_name: postgres - image: postgres:17 - environment: - POSTGRES_DB: postgres - POSTGRES_USER: postgres - POSTGRES_PASSWORD: password - ports: - - "5432:5432" - volumes: - - postgres_data:/var/lib/postgresql/data - - devnet: - container_name: devnet - image: ghcr.io/ensdomains/contracts-v2:main-e8696c6 - command: ./script/runDevnet.ts --testNames - pull_policy: always - ports: - - "8545:8545" - environment: - ANVIL_IP_ADDR: "0.0.0.0" - healthcheck: - test: ["CMD", "curl", "--fail", "-s", "http://localhost:8000/health"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 30s - start_interval: 1s - -volumes: - postgres_data: - driver: local - ensrainbow_data: - driver: local diff --git a/docker/.env.docker-compose b/docker/.env.docker-compose new file mode 100644 index 0000000000..d8c682539d --- /dev/null +++ b/docker/.env.docker-compose @@ -0,0 +1,16 @@ +# Shared Docker Compose environment variables +# Used by docker/docker-compose.yml and its variants + + +# Postgres +POSTGRES_DB=postgres +POSTGRES_USER=postgres +POSTGRES_PASSWORD=password + +# Internal service URLs (container-to-container) +ENSDB_URL=postgresql://postgres:password@postgres:5432/postgres +ENSRAINBOW_URL=http://ensrainbow:3223 + +# ENS Admin +ENSADMIN_PUBLIC_URL=http://localhost:4173 +NEXT_PUBLIC_SERVER_CONNECTION_LIBRARY=http://localhost:4334 diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000000..6cf5c2211a --- /dev/null +++ b/docker/README.md @@ -0,0 +1,86 @@ +# Docker Compose + +All commands are run from the **monorepo root**. + +## Files + +| File | Purpose | +|------|---------| +| `docker/docker-compose.yml` | Base stack — ensindexer, ensapi, ensrainbow, ensadmin, postgres. Targets mainnet with default .env.local | +| `docker/docker-compose.devnet.yml` | Full stack against local devnet (`ens-test-env`). Includes all base services + devnet. | +| `docker/docker-compose.orchestrator.yml` | Minimal infra for CI — devnet + postgres only. Used by `orchestrator.ts`. | +| `docker/services/*.yml` | Individual service definitions. Extended by the compose files above. | +| `docker/.env.docker-compose` | Shared env defaults (postgres credentials, internal service URLs). Usually is placed after .env.local so wil override it by design | + +> To inspect the fully resolved config for any compose file (resolves all `extends`): +> ```bash +> docker compose -f docker/docker-compose.yml config +> ``` + +## Use cases + +### Mainnet + +**1. Configure environment files** (one-time setup): + +```bash +cp apps/ensindexer/.env.local.example apps/ensindexer/.env.local +cp apps/ensapi/.env.local.example apps/ensapi/.env.local +cp apps/ensrainbow/.env.local.example apps/ensrainbow/.env.local +``` + +Edit both files and set your RPC endpoints (e.g. `RPC_URL_1`, `ALCHEMY_API_KEY`) and any other required values. + +**2. Start/stop the stack:** + +```bash +# Start full stack in background +docker compose -f docker/docker-compose.yml up -d + +# Stop +docker compose -f docker/docker-compose.yml down + +# Stop and remove volumes +docker compose -f docker/docker-compose.yml down -v +``` + +### Local devnet (for developers) + +All config is inlined — no `.env.local` files required. + +```bash +# Start full stack against devnet +docker compose -f docker/docker-compose.devnet.yml up -d + +# Start only devnet + core services (no ensadmin) +docker compose -f docker/docker-compose.devnet.yml up -d devnet postgres ensrainbow ensindexer ensapi + +# Start only devnet (quick local EVM node, also shows data information about devnet) +docker compose -f docker/docker-compose.devnet.yml up devnet +# or +pnmp devnet + +# Stop +docker compose -f docker/docker-compose.devnet.yml down +``` + +### Build images locally + +```bash +# Build all images +pnpm docker:build:ensnode + +# Build a specific image +pnpm docker:build:ensindexer +pnpm docker:build:ensapi +pnpm docker:build:ensrainbow +pnpm docker:build:ensadmin +``` + +### CI / integration tests + +Used internally by `orchestrator.ts` via testcontainers. Starts devnet + postgres only. + +```bash +pnpm test:integration:ci +``` diff --git a/docker/docker-compose.devnet.yml b/docker/docker-compose.devnet.yml new file mode 100644 index 0000000000..8d2c6bcbd0 --- /dev/null +++ b/docker/docker-compose.devnet.yml @@ -0,0 +1,75 @@ +services: + ensindexer: + extends: + file: services/ensindexer.yml + service: ensindexer + environment: + # This is strange but RPC_URL_1 and RPC_URL_1337 doesnt work. + # Only this chain id will replace localhost:8545 with correct domain + RPC_URL_15658733: http://devnet:8545 + ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 + LABEL_SET_ID: ens-test-env + LABEL_SET_VERSION: 0 + PLUGINS: subgraph,ensv2 + NAMESPACE: ens-test-env + env_file: + - path: ./.env.docker-compose + required: true + depends_on: + ensrainbow: + condition: service_healthy + postgres: + condition: service_started + devnet: + condition: service_healthy + + ensapi: + extends: + file: services/ensapi.yml + service: ensapi + environment: + ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 + env_file: + - path: ./.env.docker-compose + required: true + + ensrainbow: + extends: + file: services/ensrainbow.yml + service: ensrainbow + environment: + LABEL_SET_ID: ens-test-env + LABEL_SET_VERSION: 0 + DB_SCHEMA_VERSION: 3 + env_file: + - path: ./.env.docker-compose + required: true + + ensadmin: + extends: + file: services/ensadmin.yml + service: ensadmin + env_file: + - path: ./.env.docker-compose + required: true + + postgres: + extends: + file: services/postgres.yml + service: postgres + env_file: + - path: ./.env.docker-compose + required: true + + devnet: + extends: + file: services/devnet.yml + service: devnet + +volumes: + # Docker Compose requires volumes used by services to be declared in each + # compose file that references them — they cannot be inherited via `extends`. + postgres_data: + driver: local + ensrainbow_data: + driver: local diff --git a/docker/docker-compose.orchestrator.yml b/docker/docker-compose.orchestrator.yml new file mode 100644 index 0000000000..40a2551d38 --- /dev/null +++ b/docker/docker-compose.orchestrator.yml @@ -0,0 +1,19 @@ +# Minimal compose for CI integration tests. +# Provides only the infrastructure services needed by orchestrator.ts: +# devnet (local EVM) and postgres (database). +services: + devnet: + extends: + file: services/devnet.yml + service: devnet + + postgres: + extends: + file: services/postgres.yml + service: postgres + +volumes: + # Docker Compose requires volumes used by services to be declared in each + # compose file that references them — they cannot be inherited via `extends`. + postgres_data: + driver: local diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000000..0217f8a95b --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,67 @@ +services: + ensindexer: + extends: + file: services/ensindexer.yml + service: ensindexer + environment: + ENSINDEXER_SCHEMA_NAME: docker_ensindexer_v1 + env_file: + # NOTE: must define apps/ensindexer/.env.local (see apps/ensindexer/.env.local.example) + - path: ../apps/ensindexer/.env.local + required: true + # Loaded last so docker-compose values (ENSDB_URL, etc.) override .env.local + - path: ./.env.docker-compose + required: true + + ensapi: + extends: + file: services/ensapi.yml + service: ensapi + environment: + ENSINDEXER_SCHEMA_NAME: docker_ensindexer_v1 + env_file: + # NOTE: must define apps/ensapi/.env.local (see apps/ensapi/.env.local.example) + - path: ../apps/ensapi/.env.local + required: true + # Loaded last so docker-compose values (ENSDB_URL, etc.) override .env.local + - path: ./.env.docker-compose + required: true + + ensrainbow: + extends: + file: services/ensrainbow.yml + service: ensrainbow + env_file: + # NOTE: Optionally define apps/ensrainbow/.env.local (see apps/ensrainbow/.env.local.example) + - path: ../apps/ensrainbow/.env.local + required: false + # Loaded last so docker-compose values override .env.local + - path: ./.env.docker-compose + required: true + + ensadmin: + extends: + file: services/ensadmin.yml + service: ensadmin + env_file: + # NOTE: Optionally define apps/ensadmin/.env.local (see apps/ensadmin/.env.local.example) + - path: ../apps/ensadmin/.env.local + required: false + - path: ./.env.docker-compose + required: true + + postgres: + extends: + file: services/postgres.yml + service: postgres + env_file: + - path: ./.env.docker-compose + required: true + +volumes: + # Docker Compose requires volumes used by services to be declared in each + # compose file that references them — they cannot be inherited via `extends`. + postgres_data: + driver: local + ensrainbow_data: + driver: local diff --git a/docker/services/devnet.yml b/docker/services/devnet.yml new file mode 100644 index 0000000000..ba16e19b42 --- /dev/null +++ b/docker/services/devnet.yml @@ -0,0 +1,17 @@ +services: + devnet: + container_name: devnet + image: ghcr.io/ensdomains/contracts-v2:main-e8696c6 + command: ./script/runDevnet.ts --testNames + pull_policy: always + ports: + - "8545:8545" + environment: + ANVIL_IP_ADDR: "0.0.0.0" + healthcheck: + test: ["CMD", "curl", "--fail", "-s", "http://localhost:8000/health"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + start_interval: 1s diff --git a/docker/services/ensadmin.yml b/docker/services/ensadmin.yml new file mode 100644 index 0000000000..d9e8c4617e --- /dev/null +++ b/docker/services/ensadmin.yml @@ -0,0 +1,17 @@ +services: + ensadmin: + container_name: ensadmin + image: ghcr.io/namehash/ensnode/ensadmin:latest + build: + dockerfile: ./apps/ensadmin/Dockerfile + context: ../.. + ports: + - "4173:4173" + environment: + # NOTE: must be host-accessible (i.e. http://localhost) + ENSADMIN_PUBLIC_URL: http://localhost:4173 + # NOTE: must be host-accessible (i.e. http://localhost) + NEXT_PUBLIC_SERVER_CONNECTION_LIBRARY: http://localhost:4334 + depends_on: + ensapi: + condition: service_started diff --git a/docker/services/ensapi.yml b/docker/services/ensapi.yml new file mode 100644 index 0000000000..3665b0369e --- /dev/null +++ b/docker/services/ensapi.yml @@ -0,0 +1,19 @@ +services: + ensapi: + container_name: ensapi + image: ghcr.io/namehash/ensnode/ensapi:latest + build: + dockerfile: ./apps/ensapi/Dockerfile + context: ../.. + ports: + - "4334:4334" + healthcheck: + test: ["CMD", "curl", "--fail", "-s", "http://localhost:4334/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 1m + start_interval: 1s + depends_on: + postgres: + condition: service_started diff --git a/docker/services/ensindexer.yml b/docker/services/ensindexer.yml new file mode 100644 index 0000000000..9bf539f124 --- /dev/null +++ b/docker/services/ensindexer.yml @@ -0,0 +1,21 @@ +services: + ensindexer: + container_name: ensindexer + image: ghcr.io/namehash/ensnode/ensindexer:latest + build: + dockerfile: ./apps/ensindexer/Dockerfile + context: ../.. + ports: + - "42069:42069" + healthcheck: + test: ["CMD", "curl", "--fail", "-s", "http://localhost:42069/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 5m + start_interval: 1s + depends_on: + ensrainbow: + condition: service_healthy + postgres: + condition: service_started diff --git a/docker/services/ensrainbow.yml b/docker/services/ensrainbow.yml new file mode 100644 index 0000000000..a75d5852cc --- /dev/null +++ b/docker/services/ensrainbow.yml @@ -0,0 +1,19 @@ +services: + ensrainbow: + container_name: ensrainbow + image: ghcr.io/namehash/ensnode/ensrainbow:latest + build: + dockerfile: ./apps/ensrainbow/Dockerfile + context: ../.. + ports: + - "3223:3223" + volumes: + - ensrainbow_data:/app/apps/ensrainbow/data + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://localhost:3223/health"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 20m + start_interval: 1s diff --git a/docker/services/postgres.yml b/docker/services/postgres.yml new file mode 100644 index 0000000000..cff150ded9 --- /dev/null +++ b/docker/services/postgres.yml @@ -0,0 +1,8 @@ +services: + postgres: + container_name: postgres + image: postgres:17 + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data diff --git a/package.json b/package.json index bacf366d6d..67fe706bcd 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "changeset-publish": "changeset publish", "changeset-publish:next": "changeset publish --no-git-tag --snapshot --tag next", "packages:prepublish": "pnpm -r prepublish", - "devnet": "docker compose up devnet", + "devnet": "docker compose -f docker/docker-compose.devnet.yml up devnet", "docker:build:ensnode": "pnpm run -w --parallel \"/^docker:build:.*/\"", "docker:build:ensindexer": "docker build -f apps/ensindexer/Dockerfile -t ghcr.io/namehash/ensnode/ensindexer:latest .", "docker:build:ensadmin": "docker build -f apps/ensadmin/Dockerfile -t ghcr.io/namehash/ensnode/ensadmin:latest .", diff --git a/packages/integration-test-env/src/orchestrator.ts b/packages/integration-test-env/src/orchestrator.ts index 99df9f5f46..a6724db89d 100644 --- a/packages/integration-test-env/src/orchestrator.ts +++ b/packages/integration-test-env/src/orchestrator.ts @@ -42,6 +42,7 @@ import { ENSNamespaceIds } from "@ensnode/datasources"; import { OmnichainIndexingStatusIds } from "@ensnode/ensnode-sdk"; const MONOREPO_ROOT = resolve(import.meta.dirname, "../../.."); +const DOCKER_DIR = resolve(MONOREPO_ROOT, "docker"); const ENSRAINBOW_DIR = resolve(MONOREPO_ROOT, "apps/ensrainbow"); const ENSINDEXER_DIR = resolve(MONOREPO_ROOT, "apps/ensindexer"); const ENSAPI_DIR = resolve(MONOREPO_ROOT, "apps/ensapi"); @@ -238,7 +239,10 @@ async function main() { // Phase 1: Start Postgres + Devnet via docker-compose log("Starting Postgres and devnet..."); - composeEnvironment = await new DockerComposeEnvironment(MONOREPO_ROOT, "docker-compose.yml") + composeEnvironment = await new DockerComposeEnvironment( + DOCKER_DIR, + "docker-compose.orchestrator.yml", + ) .withWaitStrategy("devnet", Wait.forHealthCheck()) .withWaitStrategy("postgres", Wait.forListeningPorts()) .withStartupTimeout(120_000) From f0f4d128769043b3451398268309c0c0895c971a Mon Sep 17 00:00:00 2001 From: sevenzing Date: Tue, 21 Apr 2026 13:27:42 +0400 Subject: [PATCH 02/11] fix PR comments --- apps/ensindexer/.env.local.example | 2 +- docker/README.md | 2 +- docker/docker-compose.devnet.yml | 6 +++- docker/docker-compose.orchestrator.yml | 3 ++ docker/docker-compose.yml | 4 +-- docker/services/ensadmin.yml | 5 --- docker/services/ensapi.yml | 2 +- docker/services/ensindexer.yml | 2 +- docker/services/postgres.yml | 6 ++++ .../content/docs/docs/contributing/index.mdx | 22 ++++++------ .../content/docs/docs/deploying/docker.mdx | 35 ++++++++++++++----- packages/integration-test-env/README.md | 2 +- .../integration-test-env/src/orchestrator.ts | 2 +- 13 files changed, 61 insertions(+), 32 deletions(-) diff --git a/apps/ensindexer/.env.local.example b/apps/ensindexer/.env.local.example index 3a40b68470..412aa88dc3 100644 --- a/apps/ensindexer/.env.local.example +++ b/apps/ensindexer/.env.local.example @@ -243,7 +243,7 @@ ENSRAINBOW_URL=http://localhost:3223 # https://ensnode.io/ensrainbow/usage/available-label-sets # # LABEL_SET_ID: see https://ensnode.io/ensrainbow/concepts/glossary#label-set-id. -# Should match ensrainbow LABEL_SET_ID +# Should match ENSRainbow's LABEL_SET_ID. LABEL_SET_ID=subgraph # LABEL_SET_VERSION: see https://ensnode.io/ensrainbow/concepts/glossary#label-set-version. diff --git a/docker/README.md b/docker/README.md index 6cf5c2211a..d460e3ed74 100644 --- a/docker/README.md +++ b/docker/README.md @@ -58,7 +58,7 @@ docker compose -f docker/docker-compose.devnet.yml up -d devnet postgres ensrain # Start only devnet (quick local EVM node, also shows data information about devnet) docker compose -f docker/docker-compose.devnet.yml up devnet # or -pnmp devnet +pnpm devnet # Stop docker compose -f docker/docker-compose.devnet.yml down diff --git a/docker/docker-compose.devnet.yml b/docker/docker-compose.devnet.yml index 8d2c6bcbd0..75ca2119ee 100644 --- a/docker/docker-compose.devnet.yml +++ b/docker/docker-compose.devnet.yml @@ -19,7 +19,7 @@ services: ensrainbow: condition: service_healthy postgres: - condition: service_started + condition: service_healthy devnet: condition: service_healthy @@ -69,7 +69,11 @@ services: volumes: # Docker Compose requires volumes used by services to be declared in each # compose file that references them — they cannot be inherited via `extends`. + # Explicit `name:` prevents collision with the base stack's volumes when both + # are run from the same directory (same project name). postgres_data: + name: ensnode_devnet_postgres_data driver: local ensrainbow_data: + name: ensnode_devnet_ensrainbow_data driver: local diff --git a/docker/docker-compose.orchestrator.yml b/docker/docker-compose.orchestrator.yml index 40a2551d38..ae67b9f559 100644 --- a/docker/docker-compose.orchestrator.yml +++ b/docker/docker-compose.orchestrator.yml @@ -11,6 +11,9 @@ services: extends: file: services/postgres.yml service: postgres + env_file: + - path: ./.env.docker-compose + required: true volumes: # Docker Compose requires volumes used by services to be declared in each diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 0217f8a95b..08f831d902 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -32,9 +32,9 @@ services: file: services/ensrainbow.yml service: ensrainbow env_file: - # NOTE: Optionally define apps/ensrainbow/.env.local (see apps/ensrainbow/.env.local.example) + # NOTE: must define apps/ensrainbow/.env.local (see apps/ensrainbow/.env.local.example) - path: ../apps/ensrainbow/.env.local - required: false + required: true # Loaded last so docker-compose values override .env.local - path: ./.env.docker-compose required: true diff --git a/docker/services/ensadmin.yml b/docker/services/ensadmin.yml index d9e8c4617e..7e8e95d62d 100644 --- a/docker/services/ensadmin.yml +++ b/docker/services/ensadmin.yml @@ -7,11 +7,6 @@ services: context: ../.. ports: - "4173:4173" - environment: - # NOTE: must be host-accessible (i.e. http://localhost) - ENSADMIN_PUBLIC_URL: http://localhost:4173 - # NOTE: must be host-accessible (i.e. http://localhost) - NEXT_PUBLIC_SERVER_CONNECTION_LIBRARY: http://localhost:4334 depends_on: ensapi: condition: service_started diff --git a/docker/services/ensapi.yml b/docker/services/ensapi.yml index 3665b0369e..8d56753187 100644 --- a/docker/services/ensapi.yml +++ b/docker/services/ensapi.yml @@ -16,4 +16,4 @@ services: start_interval: 1s depends_on: postgres: - condition: service_started + condition: service_healthy diff --git a/docker/services/ensindexer.yml b/docker/services/ensindexer.yml index 9bf539f124..2a65be31e6 100644 --- a/docker/services/ensindexer.yml +++ b/docker/services/ensindexer.yml @@ -18,4 +18,4 @@ services: ensrainbow: condition: service_healthy postgres: - condition: service_started + condition: service_healthy diff --git a/docker/services/postgres.yml b/docker/services/postgres.yml index cff150ded9..85f0f12b23 100644 --- a/docker/services/postgres.yml +++ b/docker/services/postgres.yml @@ -6,3 +6,9 @@ services: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 5s + retries: 5 + start_period: 10s diff --git a/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx b/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx index fce21e8752..c82c0f0e85 100644 --- a/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx @@ -40,12 +40,12 @@ pnpm install ## Running ENSNode :::note -ENSNode is a suite of services, and some depend on others. Refer to the `docker-compose.yml` at the root of the monorepo for a full spec on the relationship between services. +ENSNode is a suite of services, and some depend on others. Refer to the `docker/docker-compose.yml` in the docker directory for a full spec on the relationship between services. ::: @@ -132,32 +132,34 @@ Before you can use Docker Compose, ensure you have the following installed on yo ### Building the Docker Images -Before running `docker compose` the images must be build with the latest changes: see the [Building Docker Images](/ensnode/contributing/building) guide. +Before running `docker compose` the images must be built with the latest changes: see the [Building Docker Images](/ensnode/contributing/building) guide. If you make changes in the application code and wish to run those updates, you must build the relevant Docker container again. ### Running the Applications -Run the built images with: +Run the base stack with: ```bash -docker compose up -d +docker compose -f docker/docker-compose.yml up -d ``` - **ENSIndexer**: Available at [http://localhost:42069](http://localhost:42069) -- **ENSApi**: Available at [http://localhost:42069](http://localhost:4334) +- **ENSApi**: Available at [http://localhost:4334](http://localhost:4334) - **ENSRainbow**: Available at [http://localhost:3223](http://localhost:3223) - **ENSAdmin**: Available at [http://localhost:4173](http://localhost:4173) - **PostgreSQL**: Available on port `5432` +For more compose files (devnet, CI), configuration options, and all available commands, see the [Deploying with Docker](/ensnode/deploying/docker) guide and [`docker/README.md`](https://github.com/namehash/ensnode/blob/main/docker/README.md). + ### Stopping the Applications -To stop the running applications, you can press `Ctrl + C` in the terminal where Docker Compose is running. If you want to remove the containers and networks created by Docker Compose, you can run: +To stop the running applications, you can press `Ctrl + C` in the terminal where Docker Compose is running. To remove the containers and networks: ```bash -docker compose down +docker compose -f docker/docker-compose.yml down ``` -:::note[Postgres Volume in this `docker-compose.yml`] -`docker compoe down` will _not_ delete the Postgres data volume defined here, as it is a **named** volume. To fully delete the Postgres data volume and start from scratch, use `docker compose down -v`. +:::note[Postgres Volume] +`docker compose down` will _not_ delete the Postgres data volume, as it is a **named** volume. To fully delete it and start from scratch, use `docker compose -f docker/docker-compose.yml down -v`. ::: diff --git a/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx b/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx index 88f159aa3a..fe56e94767 100644 --- a/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx +++ b/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx @@ -6,8 +6,6 @@ sidebar: --- import { LinkCard } from '@astrojs/starlight/components'; -import { Code } from '@astrojs/starlight/components'; -import dockercompose from '@workspace/docker-compose.yml?raw'; The Docker images are the easiest way to run or deploy the ENSNode suite of services, both locally and in the cloud. @@ -20,16 +18,37 @@ ENSIndexer runs `CREATE EXTENSION IF NOT EXISTS pg_trgm` at startup to back part href="/ensindexer/usage/configuration" /> -Below is a sample [Docker Compose](https://docs.docker.com/compose/) file linking the various services together. +ENSNode provides several [Docker Compose](https://docs.docker.com/compose/) files for different use cases: - +- **`docker/docker-compose.yml`** — base stack (mainnet by default): ensindexer, ensapi, ensrainbow, ensadmin, postgres +- **`docker/docker-compose.devnet.yml`** — full stack against local devnet (ens-test-env), no `.env.local` files required + +Before running the base stack, configure the required environment files: + +```bash +cp apps/ensindexer/.env.local.example apps/ensindexer/.env.local +cp apps/ensapi/.env.local.example apps/ensapi/.env.local +cp apps/ensrainbow/.env.local.example apps/ensrainbow/.env.local +``` + +Edit each `.env.local` to set your RPC URLs and any other required values, then run: + +```bash +docker compose -f docker/docker-compose.yml up -d +``` + + :::note[Port Mappings] -Note that while this example `docker-compose.yml` exposes each container's port to the host machine, useful for development, you may only wish to expose ENSApi's `4334` and avoid exposing services like ENSRainbow, ENSAdmin, and your Postgres to the wider internet. +Note that while the default `docker-compose.yml` exposes each container's port to the host machine (useful for development), you may only wish to expose ENSApi's `4334` and avoid exposing services like ENSRainbow, ENSAdmin, and Postgres to the wider internet. ::: diff --git a/packages/integration-test-env/README.md b/packages/integration-test-env/README.md index 92de243d9b..464995f628 100644 --- a/packages/integration-test-env/README.md +++ b/packages/integration-test-env/README.md @@ -10,7 +10,7 @@ The current devnet image is pinned to: ghcr.io/ensdomains/contracts-v2:main-e8696c6 ``` -via the `docker-compose.yml` at the monorepo root. +via the `docker/docker-compose.orchestrator.yml` file. ## How It Works diff --git a/packages/integration-test-env/src/orchestrator.ts b/packages/integration-test-env/src/orchestrator.ts index a6724db89d..17e2a72d58 100644 --- a/packages/integration-test-env/src/orchestrator.ts +++ b/packages/integration-test-env/src/orchestrator.ts @@ -12,7 +12,7 @@ * 5. Run `pnpm test:integration` at the monorepo root * * Design decisions: - * - Postgres and devnet are started from the root docker-compose.yml via + * - Postgres and devnet are started from docker/docker-compose.orchestrator.yml via * testcontainers DockerComposeEnvironment, ensuring the orchestrator always * uses the same images and configuration defined there. * - execa for child process management — automatic cleanup on parent exit, From b38f2bd4ab5333e20ea6e8b4ed2a6946ffe47ba2 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Tue, 21 Apr 2026 13:31:50 +0400 Subject: [PATCH 03/11] fix docker integration tests --- packages/integration-test-env/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/integration-test-env/README.md b/packages/integration-test-env/README.md index 464995f628..2d90daf5b2 100644 --- a/packages/integration-test-env/README.md +++ b/packages/integration-test-env/README.md @@ -40,7 +40,7 @@ When developing, it's useful to run each service individually so you can restart #### 1. Start the devnet ```sh -docker compose up devnet +pnpm devnet ``` Runs the ENS contracts-v2 devnet on port 8545. @@ -56,7 +56,7 @@ brew services start postgresql@17 or with the local docker compose: ```sh -docker compose up postgres +docker compose -f docker/docker-compose.yml up postgres ``` #### 3. Start ENSRainbow @@ -64,7 +64,7 @@ docker compose up postgres Run via docker compose: ```sh -docker compose up ensrainbow +docker compose -f docker/docker-compose.yml up ensrainbow ``` Or run it on the host machine from the repo root: From 9acbcf8fea81df0f1f11e1ab95b962370d70d1c1 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Tue, 21 Apr 2026 13:39:01 +0400 Subject: [PATCH 04/11] typos --- docker/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/README.md b/docker/README.md index d460e3ed74..94397e29a6 100644 --- a/docker/README.md +++ b/docker/README.md @@ -10,7 +10,7 @@ All commands are run from the **monorepo root**. | `docker/docker-compose.devnet.yml` | Full stack against local devnet (`ens-test-env`). Includes all base services + devnet. | | `docker/docker-compose.orchestrator.yml` | Minimal infra for CI — devnet + postgres only. Used by `orchestrator.ts`. | | `docker/services/*.yml` | Individual service definitions. Extended by the compose files above. | -| `docker/.env.docker-compose` | Shared env defaults (postgres credentials, internal service URLs). Usually is placed after .env.local so wil override it by design | +| `docker/.env.docker-compose` | Shared env defaults (postgres credentials, internal service URLs). Usually placed after `.env.local`, so it will override it by design. | > To inspect the fully resolved config for any compose file (resolves all `extends`): > ```bash @@ -29,7 +29,7 @@ cp apps/ensapi/.env.local.example apps/ensapi/.env.local cp apps/ensrainbow/.env.local.example apps/ensrainbow/.env.local ``` -Edit both files and set your RPC endpoints (e.g. `RPC_URL_1`, `ALCHEMY_API_KEY`) and any other required values. +Edit those files and set your RPC endpoints (e.g. `RPC_URL_1`, `ALCHEMY_API_KEY`) and any other required values. **2. Start/stop the stack:** From de8b85d6474ba9cc41118c6743fa0989556f1d58 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Tue, 21 Apr 2026 13:40:25 +0400 Subject: [PATCH 05/11] docs(changeset): Moved docker-compose.yml file to separate `docker` directory, updates docs and cicd-tests --- .changeset/hip-poems-shave.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/hip-poems-shave.md diff --git a/.changeset/hip-poems-shave.md b/.changeset/hip-poems-shave.md new file mode 100644 index 0000000000..a22e5f5da1 --- /dev/null +++ b/.changeset/hip-poems-shave.md @@ -0,0 +1,6 @@ +--- +"@ensnode/integration-test-env": patch +"@docs/ensnode": patch +--- + +Moved docker-compose.yml file to separate `docker` directory, updates docs and cicd-tests From f5ff4465ea55605cea60c91e49702758b0670326 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Tue, 21 Apr 2026 20:15:28 +0400 Subject: [PATCH 06/11] add RPC_URL to ensapi --- docker/docker-compose.devnet.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/docker-compose.devnet.yml b/docker/docker-compose.devnet.yml index 75ca2119ee..8f24df384e 100644 --- a/docker/docker-compose.devnet.yml +++ b/docker/docker-compose.devnet.yml @@ -29,6 +29,7 @@ services: service: ensapi environment: ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 + RPC_URL_15658733: http://devnet:8545 env_file: - path: ./.env.docker-compose required: true From ed64029f2b21aba4c86805a5db2cdec6a4dd80f2 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Wed, 22 Apr 2026 15:14:06 +0400 Subject: [PATCH 07/11] change how .env configured --- docker/README.md | 31 +++++++------- docker/docker-compose.devnet.yml | 38 +++++++++++------ docker/docker-compose.orchestrator.yml | 2 +- docker/docker-compose.yml | 28 +++++-------- .../.env.docker.common} | 0 docker/envs/.env.docker.devnet | 6 +++ docker/envs/.env.docker.example | 41 +++++++++++++++++++ .../content/docs/docs/contributing/index.mdx | 16 +++++++- .../content/docs/docs/deploying/docker.mdx | 26 ++++++++---- 9 files changed, 135 insertions(+), 53 deletions(-) rename docker/{.env.docker-compose => envs/.env.docker.common} (100%) create mode 100644 docker/envs/.env.docker.devnet create mode 100644 docker/envs/.env.docker.example diff --git a/docker/README.md b/docker/README.md index 94397e29a6..7b54a32275 100644 --- a/docker/README.md +++ b/docker/README.md @@ -4,13 +4,16 @@ All commands are run from the **monorepo root**. ## Files -| File | Purpose | -|------|---------| -| `docker/docker-compose.yml` | Base stack — ensindexer, ensapi, ensrainbow, ensadmin, postgres. Targets mainnet with default .env.local | -| `docker/docker-compose.devnet.yml` | Full stack against local devnet (`ens-test-env`). Includes all base services + devnet. | -| `docker/docker-compose.orchestrator.yml` | Minimal infra for CI — devnet + postgres only. Used by `orchestrator.ts`. | -| `docker/services/*.yml` | Individual service definitions. Extended by the compose files above. | -| `docker/.env.docker-compose` | Shared env defaults (postgres credentials, internal service URLs). Usually placed after `.env.local`, so it will override it by design. | +| File | Purpose | +| ---------------------------------------- | -------------------------------------------------------------------------------------- | +| `docker/docker-compose.yml` | Base stack — ensindexer, ensapi, ensrainbow, ensadmin, postgres. For mainnet/sepolia. | +| `docker/docker-compose.devnet.yml` | Full stack against local devnet (`ens-test-env`). Includes all base services + devnet. | +| `docker/docker-compose.orchestrator.yml` | Minimal infra for CI — devnet + postgres only. Used by `orchestrator.ts`. | +| `docker/services/*.yml` | Individual service definitions. Extended by the compose files above. | +| `docker/envs/.env.docker.common` | Shared env defaults (postgres credentials, internal service URLs). Committed. | +| `docker/envs/.env.docker.devnet` | Devnet defaults (PLUGINS, etc.). Committed. Works out of the box. | +| `docker/envs/.env.docker.example` | Example for user-specific config. Copy to `.env.docker.local` for mainnet/sepolia. | +| `docker/envs/.env.docker.local` | User config (gitignored). Required for base stack, optional for devnet overrides. | > To inspect the fully resolved config for any compose file (resolves all `extends`): > ```bash @@ -19,17 +22,15 @@ All commands are run from the **monorepo root**. ## Use cases -### Mainnet +### Mainnet / Sepolia -**1. Configure environment files** (one-time setup): +**1. Configure environment** (one-time setup): ```bash -cp apps/ensindexer/.env.local.example apps/ensindexer/.env.local -cp apps/ensapi/.env.local.example apps/ensapi/.env.local -cp apps/ensrainbow/.env.local.example apps/ensrainbow/.env.local +cp docker/envs/.env.docker.example docker/envs/.env.docker.local ``` -Edit those files and set your RPC endpoints (e.g. `RPC_URL_1`, `ALCHEMY_API_KEY`) and any other required values. +Edit `docker/envs/.env.docker.local` and set `NAMESPACE`, `PLUGINS`, and your RPC endpoints (e.g. `ALCHEMY_API_KEY` or `RPC_URL_1`). **2. Start/stop the stack:** @@ -46,7 +47,9 @@ docker compose -f docker/docker-compose.yml down -v ### Local devnet (for developers) -All config is inlined — no `.env.local` files required. +No setup required — devnet defaults are committed in `docker/envs/.env.docker.devnet`. + +To override defaults (e.g. change `PLUGINS`), create `docker/envs/.env.docker.local` with your values. ```bash # Start full stack against devnet diff --git a/docker/docker-compose.devnet.yml b/docker/docker-compose.devnet.yml index 8f24df384e..145f7f85e2 100644 --- a/docker/docker-compose.devnet.yml +++ b/docker/docker-compose.devnet.yml @@ -4,17 +4,19 @@ services: file: services/ensindexer.yml service: ensindexer environment: - # This is strange but RPC_URL_1 and RPC_URL_1337 doesnt work. - # Only this chain id will replace localhost:8545 with correct domain + # TODO: in future we will migrate devnet to chain_id=1 + # need to update this line in that case RPC_URL_15658733: http://devnet:8545 ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 LABEL_SET_ID: ens-test-env - LABEL_SET_VERSION: 0 - PLUGINS: subgraph,ensv2 NAMESPACE: ens-test-env env_file: - - path: ./.env.docker-compose + - path: envs/.env.docker.common required: true + - path: envs/.env.docker.devnet + required: true + - path: envs/.env.docker.local + required: false depends_on: ensrainbow: condition: service_healthy @@ -28,11 +30,17 @@ services: file: services/ensapi.yml service: ensapi environment: - ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 + # TODO: in future we will migrate devnet to chain_id=1 + # need to update this line in that case RPC_URL_15658733: http://devnet:8545 + ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 env_file: - - path: ./.env.docker-compose + - path: envs/.env.docker.common required: true + - path: envs/.env.docker.devnet + required: true + - path: envs/.env.docker.local + required: false ensrainbow: extends: @@ -40,26 +48,32 @@ services: service: ensrainbow environment: LABEL_SET_ID: ens-test-env - LABEL_SET_VERSION: 0 - DB_SCHEMA_VERSION: 3 env_file: - - path: ./.env.docker-compose + - path: envs/.env.docker.common + required: true + - path: envs/.env.docker.devnet required: true + - path: envs/.env.docker.local + required: false ensadmin: extends: file: services/ensadmin.yml service: ensadmin env_file: - - path: ./.env.docker-compose + - path: envs/.env.docker.common + required: true + - path: envs/.env.docker.devnet required: true + - path: envs/.env.docker.local + required: false postgres: extends: file: services/postgres.yml service: postgres env_file: - - path: ./.env.docker-compose + - path: ./envs/.env.docker.common required: true devnet: diff --git a/docker/docker-compose.orchestrator.yml b/docker/docker-compose.orchestrator.yml index ae67b9f559..e813e27f69 100644 --- a/docker/docker-compose.orchestrator.yml +++ b/docker/docker-compose.orchestrator.yml @@ -12,7 +12,7 @@ services: file: services/postgres.yml service: postgres env_file: - - path: ./.env.docker-compose + - path: ./envs/.env.docker.common required: true volumes: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 08f831d902..f049744d72 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -6,11 +6,10 @@ services: environment: ENSINDEXER_SCHEMA_NAME: docker_ensindexer_v1 env_file: - # NOTE: must define apps/ensindexer/.env.local (see apps/ensindexer/.env.local.example) - - path: ../apps/ensindexer/.env.local + - path: envs/.env.docker.common required: true - # Loaded last so docker-compose values (ENSDB_URL, etc.) override .env.local - - path: ./.env.docker-compose + # Copy envs/.env.docker.example to envs/.env.docker.local and configure + - path: envs/.env.docker.local required: true ensapi: @@ -20,11 +19,9 @@ services: environment: ENSINDEXER_SCHEMA_NAME: docker_ensindexer_v1 env_file: - # NOTE: must define apps/ensapi/.env.local (see apps/ensapi/.env.local.example) - - path: ../apps/ensapi/.env.local + - path: envs/.env.docker.common required: true - # Loaded last so docker-compose values (ENSDB_URL, etc.) override .env.local - - path: ./.env.docker-compose + - path: envs/.env.docker.local required: true ensrainbow: @@ -32,11 +29,9 @@ services: file: services/ensrainbow.yml service: ensrainbow env_file: - # NOTE: must define apps/ensrainbow/.env.local (see apps/ensrainbow/.env.local.example) - - path: ../apps/ensrainbow/.env.local + - path: envs/.env.docker.common required: true - # Loaded last so docker-compose values override .env.local - - path: ./.env.docker-compose + - path: envs/.env.docker.local required: true ensadmin: @@ -44,10 +39,9 @@ services: file: services/ensadmin.yml service: ensadmin env_file: - # NOTE: Optionally define apps/ensadmin/.env.local (see apps/ensadmin/.env.local.example) - - path: ../apps/ensadmin/.env.local - required: false - - path: ./.env.docker-compose + - path: envs/.env.docker.common + required: true + - path: envs/.env.docker.local required: true postgres: @@ -55,7 +49,7 @@ services: file: services/postgres.yml service: postgres env_file: - - path: ./.env.docker-compose + - path: envs/.env.docker.common required: true volumes: diff --git a/docker/.env.docker-compose b/docker/envs/.env.docker.common similarity index 100% rename from docker/.env.docker-compose rename to docker/envs/.env.docker.common diff --git a/docker/envs/.env.docker.devnet b/docker/envs/.env.docker.devnet new file mode 100644 index 0000000000..7c63beef83 --- /dev/null +++ b/docker/envs/.env.docker.devnet @@ -0,0 +1,6 @@ +# Default configuration for devnet docker-compose stack. +# These values work out of the box — override by creating .env.docker.local. + +PLUGINS=subgraph,ensv2 +LABEL_SET_VERSION=0 +DB_SCHEMA_VERSION=3 diff --git a/docker/envs/.env.docker.example b/docker/envs/.env.docker.example new file mode 100644 index 0000000000..5cba37d2c8 --- /dev/null +++ b/docker/envs/.env.docker.example @@ -0,0 +1,41 @@ +# Docker environment configuration for ENSNode. +# Copy this file to .env.docker.local and fill in the values. +# +# For devnet: no localization needed — defaults are in .env.docker.devnet. +# Override by creating .env.docker.local with your custom values. +# For mainnet/sepolia: copy this file to .env.docker.local and configure below. + +# ENS Namespace +# Required. Must be: mainnet, sepolia, or ens-test-env. +NAMESPACE=mainnet + +# Plugin Configuration +# Required. Comma-separated list of plugins to activate. +# For subgraph-compatible indexing only: PLUGINS=subgraph +# For full indexing: PLUGINS=subgraph,basenames,lineanames,threedns,protocol-acceleration,registrars,tokenscope +PLUGINS=subgraph + +# ENSRainbow Label Set Configuration +# See https://ensnode.io/ensrainbow/usage/available-label-sets +LABEL_SET_ID=subgraph +LABEL_SET_VERSION=0 +DB_SCHEMA_VERSION=3 + +# RPC Configuration +# Required for mainnet/sepolia. Not needed for devnet. +# You must use private (paid) RPC endpoints — public endpoints are too slow. +# +# Option 1: Auto-generate RPC URLs via provider API keys +# ALCHEMY_API_KEY= +# QUICKNODE_API_KEY= +# QUICKNODE_ENDPOINT_NAME= +# DRPC_API_KEY= +# +# Option 2: Explicit per-chain RPC URLs (takes precedence over auto-generated) +# See apps/ensindexer/.env.local.example for the full list of chain IDs. +# RPC_URL_1=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY +# RPC_URL_10= +# RPC_URL_8453= +# RPC_URL_42161= +# RPC_URL_59144= +# RPC_URL_534352= diff --git a/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx b/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx index c82c0f0e85..36f271bf29 100644 --- a/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/contributing/index.mdx @@ -138,7 +138,19 @@ If you make changes in the application code and wish to run those updates, you m ### Running the Applications -Run the base stack with: +For local development, use the devnet stack — no environment setup required: + +```bash +docker compose -f docker/docker-compose.devnet.yml up -d +``` + +For mainnet/sepolia, first configure your environment: + +```bash +cp docker/envs/.env.docker.example docker/envs/.env.docker.local +``` + +Edit `docker/envs/.env.docker.local` to set `NAMESPACE`, `PLUGINS`, and your RPC endpoints, then run: ```bash docker compose -f docker/docker-compose.yml up -d @@ -150,7 +162,7 @@ docker compose -f docker/docker-compose.yml up -d - **ENSAdmin**: Available at [http://localhost:4173](http://localhost:4173) - **PostgreSQL**: Available on port `5432` -For more compose files (devnet, CI), configuration options, and all available commands, see the [Deploying with Docker](/ensnode/deploying/docker) guide and [`docker/README.md`](https://github.com/namehash/ensnode/blob/main/docker/README.md). +For all available commands and configuration options, see the [Deploying with Docker](/ensnode/deploying/docker) guide and [`docker/README.md`](https://github.com/namehash/ensnode/blob/main/docker/README.md). ### Stopping the Applications diff --git a/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx b/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx index fe56e94767..32b4f53290 100644 --- a/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx +++ b/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx @@ -20,23 +20,35 @@ ENSIndexer runs `CREATE EXTENSION IF NOT EXISTS pg_trgm` at startup to back part ENSNode provides several [Docker Compose](https://docs.docker.com/compose/) files for different use cases: -- **`docker/docker-compose.yml`** — base stack (mainnet by default): ensindexer, ensapi, ensrainbow, ensadmin, postgres -- **`docker/docker-compose.devnet.yml`** — full stack against local devnet (ens-test-env), no `.env.local` files required +- **`docker/docker-compose.yml`** — base stack for mainnet/sepolia: ensindexer, ensapi, ensrainbow, ensadmin, postgres +- **`docker/docker-compose.devnet.yml`** — full stack against local devnet (ens-test-env), works out of the box with no configuration required -Before running the base stack, configure the required environment files: +### Mainnet / Sepolia + +Copy the example env file and configure it: ```bash -cp apps/ensindexer/.env.local.example apps/ensindexer/.env.local -cp apps/ensapi/.env.local.example apps/ensapi/.env.local -cp apps/ensrainbow/.env.local.example apps/ensrainbow/.env.local +cp docker/envs/.env.docker.example docker/envs/.env.docker.local ``` -Edit each `.env.local` to set your RPC URLs and any other required values, then run: +Edit `docker/envs/.env.docker.local` to set your `NAMESPACE`, `PLUGINS`, and RPC endpoints (e.g. `ALCHEMY_API_KEY` or `RPC_URL_1`), then run: ```bash docker compose -f docker/docker-compose.yml up -d ``` + +### Local devnet + +Configuration is optional. To customize defaults (e.g. change `PLUGINS`), copy the example as in previous step and edit it. + +Otherwise, skip setup and run directly: + +```bash +docker compose -f docker/docker-compose.devnet.yml up -d +``` + + Date: Wed, 22 Apr 2026 15:51:53 +0400 Subject: [PATCH 08/11] remove depends_on from /services/ --- docker/docker-compose.devnet.yml | 6 ++++++ docker/docker-compose.yml | 11 +++++++++++ docker/services/ensadmin.yml | 3 --- docker/services/ensapi.yml | 3 --- docker/services/ensindexer.yml | 5 ----- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/docker/docker-compose.devnet.yml b/docker/docker-compose.devnet.yml index 145f7f85e2..76e79373c5 100644 --- a/docker/docker-compose.devnet.yml +++ b/docker/docker-compose.devnet.yml @@ -34,6 +34,9 @@ services: # need to update this line in that case RPC_URL_15658733: http://devnet:8545 ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 + depends_on: + postgres: + condition: service_healthy env_file: - path: envs/.env.docker.common required: true @@ -60,6 +63,9 @@ services: extends: file: services/ensadmin.yml service: ensadmin + depends_on: + ensapi: + condition: service_started env_file: - path: envs/.env.docker.common required: true diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index f049744d72..32bddab5da 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -5,6 +5,11 @@ services: service: ensindexer environment: ENSINDEXER_SCHEMA_NAME: docker_ensindexer_v1 + depends_on: + ensrainbow: + condition: service_healthy + postgres: + condition: service_healthy env_file: - path: envs/.env.docker.common required: true @@ -18,6 +23,9 @@ services: service: ensapi environment: ENSINDEXER_SCHEMA_NAME: docker_ensindexer_v1 + depends_on: + postgres: + condition: service_healthy env_file: - path: envs/.env.docker.common required: true @@ -38,6 +46,9 @@ services: extends: file: services/ensadmin.yml service: ensadmin + depends_on: + ensapi: + condition: service_started env_file: - path: envs/.env.docker.common required: true diff --git a/docker/services/ensadmin.yml b/docker/services/ensadmin.yml index 7e8e95d62d..fbc0fd542f 100644 --- a/docker/services/ensadmin.yml +++ b/docker/services/ensadmin.yml @@ -7,6 +7,3 @@ services: context: ../.. ports: - "4173:4173" - depends_on: - ensapi: - condition: service_started diff --git a/docker/services/ensapi.yml b/docker/services/ensapi.yml index 8d56753187..71ce5c7d34 100644 --- a/docker/services/ensapi.yml +++ b/docker/services/ensapi.yml @@ -14,6 +14,3 @@ services: retries: 3 start_period: 1m start_interval: 1s - depends_on: - postgres: - condition: service_healthy diff --git a/docker/services/ensindexer.yml b/docker/services/ensindexer.yml index 2a65be31e6..ac472ddafc 100644 --- a/docker/services/ensindexer.yml +++ b/docker/services/ensindexer.yml @@ -14,8 +14,3 @@ services: retries: 3 start_period: 5m start_interval: 1s - depends_on: - ensrainbow: - condition: service_healthy - postgres: - condition: service_healthy From 3a939255a721e1dc35bd8b1324f653fd7f0a7707 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Wed, 22 Apr 2026 16:16:10 +0400 Subject: [PATCH 09/11] 1.10.0 --- docs/ensnode.io/ensapi-openapi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ensnode.io/ensapi-openapi.json b/docs/ensnode.io/ensapi-openapi.json index e4496ea1a6..2e27b8e27a 100644 --- a/docs/ensnode.io/ensapi-openapi.json +++ b/docs/ensnode.io/ensapi-openapi.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "ENSApi APIs", - "version": "1.9.0", + "version": "1.10.0", "description": "APIs for ENS resolution, navigating the ENS nameforest, and metadata about an ENSNode" }, "servers": [ From c74d431c8b1a9ca2e3b087f67a5e5e47152330b2 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Wed, 22 Apr 2026 16:33:09 +0400 Subject: [PATCH 10/11] fix typos found by AI agents --- docker/README.md | 3 ++- docker/envs/.env.docker.example | 2 +- docker/services/ensrainbow.yml | 2 +- docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docker/README.md b/docker/README.md index 7b54a32275..ac8e8f6ba4 100644 --- a/docker/README.md +++ b/docker/README.md @@ -16,7 +16,8 @@ All commands are run from the **monorepo root**. | `docker/envs/.env.docker.local` | User config (gitignored). Required for base stack, optional for devnet overrides. | > To inspect the fully resolved config for any compose file (resolves all `extends`): -> ```bash +> +> ``` > docker compose -f docker/docker-compose.yml config > ``` diff --git a/docker/envs/.env.docker.example b/docker/envs/.env.docker.example index 5cba37d2c8..fb1b604166 100644 --- a/docker/envs/.env.docker.example +++ b/docker/envs/.env.docker.example @@ -1,7 +1,7 @@ # Docker environment configuration for ENSNode. # Copy this file to .env.docker.local and fill in the values. # -# For devnet: no localization needed — defaults are in .env.docker.devnet. +# For devnet: env.docker.local is not required — defaults are in .env.docker.devnet. # Override by creating .env.docker.local with your custom values. # For mainnet/sepolia: copy this file to .env.docker.local and configure below. diff --git a/docker/services/ensrainbow.yml b/docker/services/ensrainbow.yml index a75d5852cc..5e1c3c726d 100644 --- a/docker/services/ensrainbow.yml +++ b/docker/services/ensrainbow.yml @@ -15,5 +15,5 @@ services: interval: 30s timeout: 3s retries: 3 - start_period: 20m + start_period: 35m start_interval: 1s diff --git a/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx b/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx index 32b4f53290..46196b1e20 100644 --- a/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx +++ b/docs/ensnode.io/src/content/docs/docs/deploying/docker.mdx @@ -62,5 +62,5 @@ docker compose -f docker/docker-compose.devnet.yml up -d /> :::note[Port Mappings] -Note that while the default `docker-compose.yml` exposes each container's port to the host machine (useful for development), you may only wish to expose ENSApi's `4334` and avoid exposing services like ENSRainbow, ENSAdmin, and Postgres to the wider internet. +Note that while the default `docker/docker-compose.yml` exposes each container's port to the host machine (useful for development), you may only wish to expose ENSApi's `4334` and avoid exposing services like ENSRainbow, ENSAdmin, and Postgres to the wider internet. ::: From d8deeb564db8e2a7ebb6eb019dd505eaf18bf7e2 Mon Sep 17 00:00:00 2001 From: sevenzing Date: Fri, 24 Apr 2026 22:46:55 +0400 Subject: [PATCH 11/11] fix PR comments --- docker/docker-compose.devnet.yml | 6 ++-- docker/envs/.env.docker.example | 36 ++++++------------- .../docs/ensrainbow/deploying/docker.mdx | 2 ++ 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/docker/docker-compose.devnet.yml b/docker/docker-compose.devnet.yml index 76e79373c5..03bfb243c8 100644 --- a/docker/docker-compose.devnet.yml +++ b/docker/docker-compose.devnet.yml @@ -5,8 +5,9 @@ services: service: ensindexer environment: # TODO: in future we will migrate devnet to chain_id=1 - # need to update this line in that case + # need to remove `RPC_URL_15658733` in that case RPC_URL_15658733: http://devnet:8545 + RPC_URL_1: http://devnet:8545 ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 LABEL_SET_ID: ens-test-env NAMESPACE: ens-test-env @@ -31,8 +32,9 @@ services: service: ensapi environment: # TODO: in future we will migrate devnet to chain_id=1 - # need to update this line in that case + # need to remove `RPC_URL_15658733` in that case RPC_URL_15658733: http://devnet:8545 + RPC_URL_1: http://devnet:8545 ENSINDEXER_SCHEMA_NAME: docker_devnet_v1 depends_on: postgres: diff --git a/docker/envs/.env.docker.example b/docker/envs/.env.docker.example index fb1b604166..4ee7174e47 100644 --- a/docker/envs/.env.docker.example +++ b/docker/envs/.env.docker.example @@ -1,39 +1,25 @@ # Docker environment configuration for ENSNode. -# Copy this file to .env.docker.local and fill in the values. +# Copy this file to `.env.docker.local` and fill in the values: +# ```bash +# cp docker/envs/.env.docker.example docker/envs/.env.docker.local +# ``` # -# For devnet: env.docker.local is not required — defaults are in .env.docker.devnet. -# Override by creating .env.docker.local with your custom values. -# For mainnet/sepolia: copy this file to .env.docker.local and configure below. +# For full documentation of each variable, see the service-specific example files: +# apps/ensindexer/.env.local.example +# apps/ensapi/.env.local.example +# apps/ensrainbow/.env.local.example +# apps/ensadmin/.env.local.example -# ENS Namespace -# Required. Must be: mainnet, sepolia, or ens-test-env. NAMESPACE=mainnet - -# Plugin Configuration -# Required. Comma-separated list of plugins to activate. -# For subgraph-compatible indexing only: PLUGINS=subgraph -# For full indexing: PLUGINS=subgraph,basenames,lineanames,threedns,protocol-acceleration,registrars,tokenscope -PLUGINS=subgraph - -# ENSRainbow Label Set Configuration -# See https://ensnode.io/ensrainbow/usage/available-label-sets +PLUGINS=subgraph,basenames,lineanames,threedns,protocol-acceleration,registrars,tokenscope LABEL_SET_ID=subgraph LABEL_SET_VERSION=0 DB_SCHEMA_VERSION=3 - -# RPC Configuration -# Required for mainnet/sepolia. Not needed for devnet. -# You must use private (paid) RPC endpoints — public endpoints are too slow. -# -# Option 1: Auto-generate RPC URLs via provider API keys # ALCHEMY_API_KEY= # QUICKNODE_API_KEY= # QUICKNODE_ENDPOINT_NAME= # DRPC_API_KEY= -# -# Option 2: Explicit per-chain RPC URLs (takes precedence over auto-generated) -# See apps/ensindexer/.env.local.example for the full list of chain IDs. -# RPC_URL_1=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY +# RPC_URL_1= # RPC_URL_10= # RPC_URL_8453= # RPC_URL_42161= diff --git a/docs/ensnode.io/src/content/docs/ensrainbow/deploying/docker.mdx b/docs/ensnode.io/src/content/docs/ensrainbow/deploying/docker.mdx index 2ab8172b5f..c08b653fbe 100644 --- a/docs/ensnode.io/src/content/docs/ensrainbow/deploying/docker.mdx +++ b/docs/ensnode.io/src/content/docs/ensrainbow/deploying/docker.mdx @@ -31,6 +31,8 @@ The service will be available at `http://localhost:3223`. :::note[Storage Requirements] The ENSRainbow storage needed for a set of rainbow tables for healing unknown labels ranges from 1 MB to dozens of GB depending on the label set ID and label set version. See [System Requirements](/ensrainbow/contributing/system-requirements/) for details. +::: + ## Production Setup For full ENS Subgraph backward compatibility use the `subgraph` label set ID and 0 as the label set version (for maximized label healing use the `searchlight` label set ID and the latest label set version):