CrewCmd is designed to be self-hosted. The current supported contract is a source checkout with embedded PGlite for contributor evaluation and controlled OSS preview use. This is not yet a hardened production support guarantee.
Docker Compose, external Postgres, and platform deployments remain preview paths pending the manual evidence in #668. There is currently no supported npm CLI, desktop installer, prebuilt server archive, or published container image.
git clone https://github.com/rogerchappel/crewcmd.git
cd crewcmd
pnpm install --frozen-lockfile
pnpm devOpen http://localhost:3000. Use pnpm dev:https only for HTTPS-only browser
features or local-network testing. PGlite data is stored in .data/pglite.
cp .env.example .env
# Set AUTH_SECRET and set NEXT_PUBLIC_APP_URL to the exact public origin.
# Compose derives AUTH_URL from NEXT_PUBLIC_APP_URL.
docker compose up --build -d
curl --fail http://localhost:3000/api/healthThis includes Postgres and CrewCmd. Validate restart persistence, backup, restore, TLS, and teardown on the target host before relying on it.
- Clone the repo on your server
- Set up Postgres (or use embedded PGlite for single-user)
- Set
AUTH_SECRET,NEXT_PUBLIC_APP_URL, and the same canonicalAUTH_URL - Build, then run with
pnpm startor use PM2/systemd
CrewCmd is a Next.js app. Deploy to:
- Vercel — Needs external Postgres (Neon, Supabase)
- Railway — Includes Postgres
- Fly.io — Includes Postgres
- Coolify — Self-hosted PaaS
HTTPS is required for:
- Voice features (microphone access)
- Secure cookie handling
For local development, pnpm dev:https generates a self-signed certificate.
For production, use a reverse proxy (Nginx, Caddy) with Let's Encrypt, or deploy behind a platform that handles TLS.
Production source/Node deployments must pin Auth.js to the public origin:
export NEXT_PUBLIC_APP_URL=https://crewcmd.example.com
export AUTH_URL=https://crewcmd.example.com
pnpm build
pnpm startBoth values must be the same origin, including any non-default port. Do not
include a path, credentials, query, or fragment. Docker Compose derives
AUTH_URL from NEXT_PUBLIC_APP_URL; generated CLI configurations write both.
Do not use AUTH_TRUST_HOST=true instead of AUTH_URL.
server {
listen 443 ssl;
server_name crewcmd.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/crewcmd.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/crewcmd.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}The reverse proxy must overwrite, rather than append to, Host,
X-Forwarded-Host, and X-Forwarded-Proto. Keep the proxy hostname and scheme
identical to AUTH_URL.
Data is stored in .data/pglite/. Stop CrewCmd completely, then create a
PGlite archive:
pnpm db:pglite:backup -- \
"./backups/crewcmd-pglite-$(date +%Y%m%d-%H%M%S).tar.gz"The backup command refuses to run while the embedded database appears active and refuses to overwrite an existing archive. Archives contain account data, password hashes, runtime configuration, and any secrets stored in the database. They are created with owner-only permissions, but should still be encrypted and access-controlled wherever they are retained.
Raw copies of .data/pglite are not a supported recovery format. Restore an
archive into a new, empty data directory with the same reviewed CrewCmd/PGlite
version that created it:
export CREWCMD_PGLITE_DATA_DIR=.data/pglite-restored
pnpm db:pglite:restore -- ./backups/crewcmd-pglite-YYYYMMDD-HHMMSS.tar.gz
pnpm devThe restore command never deletes or overwrites a non-empty target directory.
Confirm /api/health, sign in, and exercise one read/write workflow before
making the restored directory your normal CREWCMD_PGLITE_DATA_DIR.
Use standard pg_dump:
pg_dump $DATABASE_URL > crewcmd-backup-$(date +%Y%m%d).sqlFor Docker Compose:
docker compose exec -T db pg_dump -U crewcmd crewcmd > crewcmd-backup-$(date +%Y%m%d).sqlTest restoring backups in a disposable environment before depending on them.
There are no published stable release artifacts yet. Pin deployments to a reviewed commit SHA, record the current SHA, and take a matching data backup before updating.
git rev-parse HEAD
# Stop CrewCmd, then archive the current embedded database if applicable.
pnpm db:pglite:backup -- ./backups/crewcmd-pglite-before-update.tar.gz
git fetch origin
git checkout REVIEWED_COMMIT_OR_TAG
pnpm install --frozen-lockfile
pnpm build
# Restart the serverEmbedded PGlite applies its tracked schema at startup. External Postgres users
must back up the database and run pnpm db:migrate before restarting.
There is no automated downgrade workflow. To roll back safely:
- Stop CrewCmd.
- Check out the previously recorded commit SHA.
- Restore the data backup taken for that exact code revision if the update applied schema changes.
- Run
pnpm install --frozen-lockfile, rebuild, and restart. - Confirm
/api/health, sign-in, and one read/write workflow before reopening access.
Do not run older code against a newer migrated database without a tested compatibility or restore plan.
For migration diagnostics and baselining an older database, see Database Migrations.