Skip to content

Feature Request: Support ALLOWED_HOSTS environment variable for containerized deployments + Production Server Architecture Discussion #10

@Popidge

Description

@Popidge

Summary

Currently, the Docker setup runs Vite's dev server in the container, which works but has limitations. This issue proposes:

  1. Adding ALLOWED_HOSTS environment variable support for accessing the dev server from custom hostnames
  2. Discussing a proper production server architecture using TanStack Start's Nitro integration

Use Case

Running Crabwalk in a homelab environment where:

  • The container is accessed via custom hostnames (e.g., jt-homelab.local) rather than localhost
  • Vite's default allowedHosts blocks requests from non-localhost origins
  • Users need to configure allowed hosts without modifying vite.config.ts

Note, this would also apply to clawdbot users running on VPS and using services like Tailscale to access thier gateway UI too - maybe able to workaround right now by running from source (not in docker) and configuring allowedHosts yourself, or an SSH tunnel to port 3000?

Proposed Changes

1. Environment Variable Support for Allowed Hosts

vite.config.ts - Parse ALLOWED_HOSTS env var:

const allowedHosts = process.env.ALLOWED_HOSTS
  ? process.env.ALLOWED_HOSTS.split(',').map(host => host.trim()).filter(Boolean)
  : undefined

export default defineConfig({
  // ... existing plugins
  server: {
    allowedHosts: allowedHosts,
  },
})

Dockerfile - Pass through the environment variable:

ARG ALLOWED_HOSTS
ENV ALLOWED_HOSTS=${ALLOWED_HOSTS}

docker-compose.yml - Add to environment:

environment:
  - CLAWDBOT_API_TOKEN=${CLAWDBOT_API_TOKEN}
  - ALLOWED_HOSTS=${ALLOWED_HOSTS:-}

.env.example - Document the new variable:

# Comma-separated list of allowed hosts for the Vite dev server
# Example: ALLOWED_HOSTS=myhost.local,192.168.1.100,.mydomain.com
ALLOWED_HOSTS=

Current Docker Limitation

The current Dockerfile's runtime stage only copies dist/ and package*.json, but running npm run dev requires:

  • src/ - Source files (TanStack Start needs these to resolve router entries)
  • public/ - Static assets
  • vite.config.ts - Vite configuration
  • tsconfig.json - TypeScript configuration

Workaround for dev server approach:

COPY --from=builder /app/src ./src
COPY --from=builder /app/public ./public
COPY vite.config.ts ./
COPY tsconfig.json ./

Production Server Architecture Discussion

As mentioned in the Dockerfile comments, you're still figuring out a proper prod server approach. I did a little research on this, might help you when working on this:

Research Findings

TanStack Start + Nitro:

  • Nitro provides a universal server engine for production deployments
  • Supports node-server preset for Node.js/Docker environments
  • Build output: .output/server/index.mjs (or configurable)
  • Standard pattern: vite buildnode .output/server/index.mjs

Current App Compatibility:

  • tRPC API routes - Compatible with Nitro's fetch handler
  • Server functions - TanStack Start handles via Nitro
  • Clawdbot WebSocket - Uses ws library, Node.js compatible
  • ⚠️ tRPC WebSocket subscriptions - Need verification in production mode

Proposed Production Setup:

  1. Add Nitro plugin to vite.config.ts:
import { nitro } from 'nitro/vite'

export default defineConfig({
  plugins: [
    tanstackStart(),
    nitro({ preset: 'node-server' }),
    // ... other plugins
  ],
})
  1. Update package.json:
{
  "scripts": {
    "dev": "vite dev --port 3000 --host",
    "build": "vite build",
    "start": "node .output/server/index.mjs"
  }
}
  1. Simplified Dockerfile:
# Build stage
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Runtime stage
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
COPY --from=builder /app/.output ./.output
EXPOSE 3000
CMD ["node", ".output/server/index.mjs"]

Considerations for Production Server

  1. allowedHosts in production - Vite's allowedHosts is a dev server feature. In production, host validation would need to be handled at:

    • Reverse proxy level (nginx, traefik)
    • Custom server entry with host checking
    • Application-level middleware
  2. WebSocket subscriptions - The tRPC WebSocket subscriptions need testing in production mode to ensure they stream correctly through Nitro's server.

  3. Clawdbot connection - The server-side WebSocket connection to clawdbot (ws://host:18789) should work unchanged in production Node.js environment.

Questions for Maintainers

  1. Is there interest in supporting the ALLOWED_HOSTS environment variable for the dev server?
  2. What's the timeline/plan for moving from dev server to production server in Docker?
  3. Are there known issues with tRPC WebSocket subscriptions in TanStack Start production mode?
  4. Would a PR for either the ALLOWED_HOSTS feature or the production server setup be welcome?

References

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions