Skip to content

Conversation

@jakejarvis
Copy link
Owner

@jakejarvis jakejarvis commented Oct 22, 2025

Summary by CodeRabbit

  • Chores

    • Added automated local development infrastructure and a script to start it via Docker.
    • Added a convenience npm script to launch the Docker-based dev environment.
  • Documentation

    • Expanded setup and getting-started instructions with environment examples, service list and ports.
    • Added detailed local dev workflow and useful development commands.

@vercel
Copy link

vercel bot commented Oct 22, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
domainstack Ready Ready Preview Comment Oct 23, 2025 3:50pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 22, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds Docker-based local development services (Postgres, Neon WS proxy, Redis, Serverless Redis HTTP, Inngest), loads env vars with dotenv, adjusts Drizzle configuration and Neon client for WebSocket proxying, introduces a startup script to orchestrate and wait for services, and updates docs and package scripts/dependencies.

Changes

Cohort / File(s) Summary
Docker Compose Setup
docker-compose.yml
Adds compose file defining services: postgres:17 with healthcheck and pg_data volume, pg_proxy (Neon WS proxy) on host port 5433, redis:7-alpine, srh (serverless-redis-http), and inngest dev server; sets ports, env, and service dependencies.
Package metadata & scripts
package.json
Adds runtime deps dotenv, postgres, ws; dev dep @types/ws; adds script dev:start-docker.
Drizzle config
drizzle.config.ts
Replaces plain export with defineConfig(...), loads .env.local and .env via dotenv, validates DATABASE_URL at runtime, and updates schema path to ./lib/db/schema.ts.
Neon client wiring
lib/db/client.ts
Imports ws and @neondatabase/serverless config, sets webSocketConstructor = ws, and when not in production configures wsProxy, disables secure WebSocket and pipeline TLS/connect for local Neon proxy routing to localhost:5433.
Seed script env loading
scripts/seed/providers.ts
Adds dotenv loading (.env.local then .env) before other imports to ensure env vars are available during seeding.
Dev infra orchestration
scripts/start-dev-infra.sh
New bash script that checks Docker/Compose, pulls images, launches docker-compose in detached mode, polls service ports with timeout, prints connection strings, and tails compose logs.
Documentation
README.md
Reworks Getting Started into numbered headings, adds .env.local example and local dev workflow (Docker instructions and ports), expands Drizzle and dev commands, and documents host.docker.internal note.

Sequence Diagram

sequenceDiagram
    participant App as Next.js App
    participant Drizzle as Drizzle Config
    participant Pool as Postgres Pool (client)
    participant WSProxy as pg_proxy (localhost:5433)
    participant PG as PostgreSQL (localhost:5432)

    Note over Drizzle,App: Startup (dotenv loads .env.local then .env)
    App->>Drizzle: read config (DATABASE_URL validated)
    App->>Pool: instantiate Pool (uses neonConfig)
    Note over Pool,WSProxy: neonConfig uses ws and wsProxy in dev
    Pool->>WSProxy: WebSocket connection / v1
    WSProxy->>PG: forward to Postgres TCP
    PG-->>WSProxy: SQL response
    WSProxy-->>Pool: WebSocket response
    Pool-->>App: connection ready
Loading

Poem

🐰 I hopped in with a tiny cheer,
Docker pots and sockets near,
Postgres, Redis, proxy bright,
Inngest humming through the night,
Seeds and schemas snug and keen—dev burrow fresh and green. 🌱

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "Add Docker Compose configuration for local development with Postgres, Redis, and Inngest" directly describes the central change in this PR. The docker-compose.yml file is the primary artifact being added, which defines all the local services mentioned in the title. While the PR also includes supporting infrastructure changes (a startup automation script, configuration updates, package dependencies, and documentation), these are secondary to and enable the Docker Compose setup. The title is specific about which services are being added (Postgres, Redis, Inngest) and clearly conveys the purpose (local development environment setup). A teammate reviewing the commit history would understand that this adds a Docker-based local development setup.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2bc9f6f and 6d3b075.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • README.md (2 hunks)
  • docker-compose.yml (1 hunks)
  • drizzle.config.ts (1 hunks)
  • lib/db/client.ts (2 hunks)
  • package.json (5 hunks)
  • scripts/seed/providers.ts (1 hunks)
  • scripts/start-dev-infra.sh (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 48b1792 and c2f2e2c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • docker-compose.yml (1 hunks)
  • package.json (2 hunks)
  • server/db/client.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
server/**

📄 CodeRabbit inference engine (AGENTS.md)

server/ hosts backend integrations and tRPC routers; isolate DNS, RDAP/WHOIS, TLS, and header probing services here

Files:

  • server/db/client.ts
server/db/**

📄 CodeRabbit inference engine (AGENTS.md)

Place Drizzle ORM schema, migrations, and repository layer for Postgres in server/db/

Files:

  • server/db/client.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: TypeScript only; keep modules small, pure, and roughly ≤300 LOC
Consolidate imports using @/... path aliases

Files:

  • server/db/client.ts
**/*.{ts,tsx,css,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use 2-space indentation across the codebase

Files:

  • server/db/client.ts
  • package.json
package.json

📄 CodeRabbit inference engine (AGENTS.md)

Require Node.js >= 22 via package.json engines

Files:

  • package.json
🪛 Checkov (3.2.334)
docker-compose.yml

[medium] 26-27: Basic Auth Credentials

(CKV_SECRET_4)

🔇 Additional comments (4)
docker-compose.yml (2)

4-18: LGTM! Postgres service is well-configured.

The service uses a pinned image version, includes proper health checks, and persists data via named volume. Hardcoded credentials are appropriate for local development.


33-42: LGTM! Redis service is properly configured.

The service uses a pinned image version, enables AOF persistence, and includes appropriate health checks.

server/db/client.ts (1)

1-3: Verify the ws import syntax works correctly.

The neonConfig import is correct. However, the ws package is a CommonJS module. With esModuleInterop enabled in TypeScript, the default import should work, but please confirm this doesn't cause issues.

If you encounter import errors, you may need to use:

import * as ws from "ws";

Or verify your tsconfig.json has:

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}
package.json (1)

81-81: LGTM! Versions are confirmed as latest.

Both ws and @types/ws are at their latest stable versions (8.18.3 and 8.18.1 respectively). The WebSocket dependencies for the Neon proxy functionality are properly aligned.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2f2e2c and 4bf4d54.

📒 Files selected for processing (1)
  • server/db/client.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
server/**

📄 CodeRabbit inference engine (AGENTS.md)

server/ hosts backend integrations and tRPC routers; isolate DNS, RDAP/WHOIS, TLS, and header probing services here

Files:

  • server/db/client.ts
server/db/**

📄 CodeRabbit inference engine (AGENTS.md)

Place Drizzle ORM schema, migrations, and repository layer for Postgres in server/db/

Files:

  • server/db/client.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: TypeScript only; keep modules small, pure, and roughly ≤300 LOC
Consolidate imports using @/... path aliases

Files:

  • server/db/client.ts
**/*.{ts,tsx,css,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use 2-space indentation across the codebase

Files:

  • server/db/client.ts
🔇 Additional comments (3)
server/db/client.ts (3)

1-3: LGTM! Imports are correct.

The imports properly support the local development proxy configuration, with neonConfig for configuration and ws for WebSocket connectivity.


7-7: LGTM! Concise error handling.

The single-line throw statement is clear and appropriate for this validation check.


21-22: LGTM! Database client export is correct.

The pool creation and drizzle export follow standard patterns and provide a clean API for the rest of the codebase to consume.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

54-84: Remove the unused postgres package from dependencies.

The postgres package (line 68) is not imported or used anywhere in the codebase. The only reference to "postgres" found is a string literal (cache_source: "postgres") in a configuration object, not the npm module itself. Since the codebase uses @neondatabase/serverless as the database client, the postgres package is redundant and should be removed.

The other runtime dependencies (dotenv and ws) are correctly added for environment variable loading and WebSocket support.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4bf4d54 and 2bc9f6f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • README.md (2 hunks)
  • docker-compose.yml (1 hunks)
  • drizzle.config.ts (1 hunks)
  • lib/db/client.ts (2 hunks)
  • package.json (5 hunks)
  • scripts/seed/providers.ts (1 hunks)
  • scripts/start-dev-infra.sh (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: TypeScript only; keep modules small, pure, and roughly ≤300 LOC
Consolidate imports using @/... path aliases

Files:

  • drizzle.config.ts
  • scripts/seed/providers.ts
  • lib/db/client.ts
**/*.{ts,tsx,css,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use 2-space indentation across the codebase

Files:

  • drizzle.config.ts
  • scripts/seed/providers.ts
  • package.json
  • lib/db/client.ts
package.json

📄 CodeRabbit inference engine (AGENTS.md)

Require Node.js >= 22 via package.json engines

Files:

  • package.json
lib/**

📄 CodeRabbit inference engine (AGENTS.md)

lib/ holds domain utilities and caching (lib/cache); import these via @/... aliases

Files:

  • lib/db/client.ts
🪛 LanguageTool
README.md

[uncategorized] ~3-~3: The official name of this software platform is spelled with a capital “H”.
Context: ... domain names. Search any domain (e.g., [github.com](https://domainstack.io/github.com...

(GITHUB)

🪛 markdownlint-cli2 (0.18.1)
README.md

84-84: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🔇 Additional comments (20)
scripts/seed/providers.ts (1)

1-5: LGTM! Environment variable loading pattern is correct.

The dotenv configuration correctly loads .env.local first (for local overrides) followed by .env (defaults), ensuring environment variables are available before subsequent imports that depend on them.

package.json (2)

16-16: LGTM! Script addition enhances developer experience.

The dev:start-docker script provides convenient automation for starting local infrastructure via the shell script.


98-98: LGTM! Type definitions correctly added.

The @types/ws devDependency provides TypeScript support for the ws package.

lib/db/client.ts (2)

1-3: LGTM! Imports are correct.

The additions of neonConfig and ws support the WebSocket configuration for local development with the Neon proxy.


12-23: Verify DATABASE_URL format assumption in wsProxy configuration.

The WebSocket configuration correctly sets up routing through the local Neon proxy. However, the wsProxy function (line 19) assumes the DATABASE_URL host will be localhost to construct "localhost:5433/v1". If DATABASE_URL contains a different host in development (e.g., 127.0.0.1 or a hostname), the proxy URL may not work as expected.

Consider adding a validation check or documenting the expected DATABASE_URL format:

 if (process.env.NODE_ENV !== "production") {
+  // Ensure DATABASE_URL uses localhost as the host for local development
+  if (!connectionString.includes("localhost")) {
+    console.warn("Warning: DATABASE_URL should use 'localhost' as host for local development with wsproxy");
+  }
   // Tell the driver how to build the wsproxy URL from the DB host

Alternatively, verify the expected format is documented in .env.local examples. Based on coding guidelines.

drizzle.config.ts (3)

1-5: LGTM! Consistent environment loading pattern.

The dotenv configuration matches the pattern used in other files, ensuring .env.local overrides take precedence.


9-13: LGTM! Runtime validation improves error handling.

The DATABASE_URL validation ensures configuration errors are caught early with a clear error message.


15-22: Schema path is correct and verified.

The updated schema path "./lib/db/schema.ts" is correctly configured and the file exists at that location. The use of defineConfig() and the validated url variable are both appropriate improvements that enhance type safety and maintainability.

scripts/start-dev-infra.sh (4)

1-21: LGTM! Robust setup and validation.

The script follows bash best practices with strict error handling (set -euo pipefail), proper root directory detection, and clear validation checks for Docker and Docker Compose v2.


23-27: LGTM! Docker Compose startup is appropriate.

The script pulls images with --ignore-pull-failures and falls back gracefully with || true, then starts services in detached mode, which is correct for local development.


52-62: LGTM! Service health checks are comprehensive.

The script waits for all five services with appropriate timeouts and clear identification, matching the ports exposed in docker-compose.yml.


64-74: LGTM! Excellent developer experience with connection strings and logs.

The success message provides all necessary connection strings in the correct format, and log tailing with exec ensures developers can monitor service output immediately.

docker-compose.yml (5)

1-17: LGTM! Postgres service is well-configured.

The Postgres service uses a specific version tag (postgres:17), includes appropriate healthchecks, and persists data with a named volume. The configuration is suitable for local development.


19-32: LGTM! Neon wsproxy configuration is correct.

The pg_proxy service correctly routes WebSocket traffic to the Postgres container with appropriate environment variables and port mapping (5433) that matches the configuration in lib/db/client.ts.

Note: A past review comment suggested pinning the image version instead of using :latest. While this is a best practice for reproducibility, it's acceptable for local development environments.


34-38: LGTM! Redis service is appropriately configured.

The Redis service uses a specific version (redis:7-alpine) and exposes the standard port. The ephemeral data storage (no volume) is acceptable for local development where Redis is used for caching and locks.


40-51: LGTM! SRH service provides Upstash-compatible local testing.

The Serverless Redis HTTP service is correctly configured to proxy requests to the Redis container, with environment variables matching the README documentation (token: dev-token, port: 8079).

Note: A past review comment suggested pinning the image version instead of using :latest. This is a best practice but not critical for local development.


53-60: LGTM! Inngest service configuration is correct with documented Linux caveat.

The Inngest dev server is properly configured to call back to the Next.js app via host.docker.internal:3000. The README already documents that Linux users need to add extra_hosts: ["host.docker.internal:host-gateway"] to this service, which is an appropriate approach.

Note: A past review comment suggested pinning the image version. Consider matching the version to the inngest package version in package.json (3.44.3) for consistency.

README.md (3)

38-65: LGTM! Excellent environment configuration guidance.

The step-by-step setup instructions are clear, and the .env.local example comprehensively documents all required environment variables with helpful comments. The values correctly match the Docker Compose service configurations.


88-106: LGTM! Database and dev server instructions are clear.

The migration steps are in the correct order, and the dev server instructions include helpful links to both the Next.js app and Inngest UI.


110-124: Verify the environment file reference in the dev command comment.

The Useful Commands section is well-organized. However, line 113 mentions .env.development.local, but the setup instructions earlier reference .env.local. Verify which file is actually used by Next.js in development mode.

Next.js loads .env.local by default in all environments, and .env.development.local specifically in development mode (with higher precedence). If only .env.local is used in this project, update the comment:

-pnpm dev                  # start dev server (uses .env.development.local)
+pnpm dev                  # start dev server (uses .env.local)

Otherwise, clarify in the setup instructions that .env.development.local is preferred over .env.local.

Comment on lines 67 to 87
### 3. Start local dev services (Docker)

We provide a single [`docker-compose.yml`](docker-compose.yml) and a helper script ([`start-dev-infra.sh`](scripts/start-dev-infra.sh)) that boots all services and waits for them to be ready:

- **Postgres** on `localhost:5432`
- **Neon wsproxy** on `localhost:5433` (WebSocket proxy used by the Neon serverless driver)
- **Redis** on `localhost:6379`
- **Serverless Redis HTTP (SRH)** on `http://localhost:8079` (Upstash-compatible REST proxy)
- **Inngest Dev Server** on `http://localhost:8288`

Run:

3. Run database migrations:
```bash
pnpm db:migrate
# Seed known providers in `lib/providers/rules/`
pnmm db:seed:providers
pnpm dev:start-docker
```

4. Run dev server:
> On Linux, if `host.docker.internal` isn’t available, add `extra_hosts` to the Inngest service in `docker-compose.yml`:
> ```yaml
> extra_hosts: ["host.docker.internal:host-gateway"]
> ```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Fix markdown formatting around the YAML code block.

The Docker setup documentation is comprehensive and accurate. However, the YAML code block (line 84-86) should be surrounded by blank lines per markdown linting rules.

Apply this diff to fix the formatting:

 > On Linux, if `host.docker.internal` isn't available, add `extra_hosts` to the Inngest service in `docker-compose.yml`:
+>
 > ```yaml
 > extra_hosts: ["host.docker.internal:host-gateway"]
 > ```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

84-84: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
In README.md around lines 67 to 86, the inline YAML code block for extra_hosts
needs proper Markdown fencing and surrounding blank lines; add an empty line
before the ```yaml fence and an empty line after the closing ``` so the YAML
block is separated from the quoted paragraph, ensure the fence uses ```yaml and
the indented line contains only extra_hosts:
["host.docker.internal:host-gateway"] without leading '>' quotation markers.

@jakejarvis jakejarvis merged commit b9bfa65 into main Oct 23, 2025
1 check passed
@jakejarvis jakejarvis deleted the feat/local-dev branch October 23, 2025 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants