BasekickLabs
Getting Started

Installation

Install Arc Launchpad with Docker Compose alongside Arc, standalone Docker, the Helm chart, or from source, setting LAUNCHPAD_JWT_SECRET and LAUNCHPAD_BASE_URL.

Launchpad ships as a container image, a Helm chart, and source. Pick the path that fits your environment. The only strictly required configuration is LAUNCHPAD_JWT_SECRET, without which the app refuses to start in production.

Docker Compose (with Arc)

The fastest way to try Launchpad is to bring up both Arc and Launchpad together. Create a docker-compose.yml:

services:
  arc:
    image: ghcr.io/basekick-labs/arc:latest
    container_name: arc
    restart: unless-stopped
    ports:
      - "8000:8000"
    environment:
      - STORAGE_BACKEND=local
    volumes:
      - arc-data:/app/data
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

  launchpad:
    image: ghcr.io/basekick-labs/launchpad:latest
    container_name: launchpad
    restart: unless-stopped
    depends_on:
      - arc
    ports:
      - "3000:3000"
    environment:
      # REQUIRED: signs session tokens. Generate with: openssl rand -hex 32
      - LAUNCHPAD_JWT_SECRET=${LAUNCHPAD_JWT_SECRET:?set LAUNCHPAD_JWT_SECRET}
      # Public URL of this deployment (email links + passkey origin).
      - LAUNCHPAD_BASE_URL=${LAUNCHPAD_BASE_URL:-http://localhost:3000}
      - LAUNCHPAD_DB_PATH=/app/data/launchpad.db
      # Arc is on the same Docker network (a private address), so allow it.
      - LAUNCHPAD_ALLOW_PRIVATE_ENDPOINTS=true
    volumes:
      - launchpad-data:/app/data
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:3000/',r=>process.exit(r.statusCode<500?0:1)).on('error',()=>process.exit(1))"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

volumes:
  arc-data:
  launchpad-data:

Bring it up:

LAUNCHPAD_JWT_SECRET=$(openssl rand -hex 32) docker compose up -d

Then open http://localhost:3000 and continue with First-run setup.

Private endpoints

By default Launchpad rejects Arc endpoints that resolve to a private, loopback, or link-local address. This is an SSRF safeguard, since its proxy forwards requests to whatever endpoint you register. Because Arc here lives on the same Docker network, the compose sets LAUNCHPAD_ALLOW_PRIVATE_ENDPOINTS=true. See Configuration.

Standalone Docker

Point Launchpad at an Arc you already run elsewhere:

docker run -p 3000:3000 \
  -e LAUNCHPAD_JWT_SECRET=$(openssl rand -hex 32) \
  -e LAUNCHPAD_BASE_URL=http://localhost:3000 \
  -v launchpad-data:/app/data \
  ghcr.io/basekick-labs/launchpad:latest

The SQLite database is written to /app/data/launchpad.db; mount a volume there to persist it.

Set LAUNCHPAD_BASE_URL correctly

Set LAUNCHPAD_BASE_URL to the public URL you actually serve on. It also drives the ORIGIN used for CSRF and the secure flag on session cookies, so a mismatch can cause login or form actions to fail. See Configuration.

Helm (Kubernetes)

helm install launchpad oci://ghcr.io/basekick-labs/charts/launchpad \
  --set jwtSecret=$(openssl rand -hex 32) \
  --set baseUrl=https://launchpad.example.com

Common values:

ValueDefaultPurpose
jwtSecret""Required unless existingSecret is set. Signs session tokens.
existingSecret""Name of a pre-created Secret holding LAUNCHPAD_JWT_SECRET instead.
baseUrlhttp://localhost:3000Public URL (email links + passkey origin).
persistence.size1GiPVC size for the SQLite database.
ingress.enabledfalseEnable to expose via an Ingress.

See helm/launchpad/values.yaml in the repo for the full list.

From source

Requires Node.js 20+.

git clone https://github.com/Basekick-Labs/launchpad
cd launchpad
npm install
cp .env.example .env        # then edit .env: set LAUNCHPAD_JWT_SECRET at minimum
npm run dev                 # http://localhost:5173

For a production build:

npm run build
LAUNCHPAD_JWT_SECRET=$(openssl rand -hex 32) node build

The server listens on $PORT (default 3000).

Next steps

On this page