Railway detects the Dockerfile automatically and provides managed PostgreSQL and Redis.
# Install Railway CLI
npm install -g @railway/cli
railway login
# Create project and services
railway init # creates a new Railway project
railway add postgres # managed PostgreSQL (Railway provides DATABASE_URL)
railway add redis # managed Redis (Railway provides REDIS_URL)Set these in Railway → Project → Variables:
NODE_ENV=production
PORT=3000
# PostgreSQL — Railway injects DATABASE_URL automatically
# Or set individually:
DB_HOST=${{Postgres.PGHOST}}
DB_PORT=${{Postgres.PGPORT}}
DB_USERNAME=${{Postgres.PGUSER}}
DB_PASSWORD=${{Postgres.PGPASSWORD}}
DB_DATABASE=${{Postgres.PGDATABASE}}
DB_SSL=true
# Redis — Railway injects REDIS_URL
REDIS_HOST=${{Redis.REDISHOST}}
REDIS_PORT=${{Redis.REDISPORT}}
REDIS_PASSWORD=${{Redis.REDISPASSWORD}}
# JWT RS256 keys (single-line with \n escapes)
# Generate with: bash scripts/rotate-jwt-keys.sh
PRIVATE_KEY=<single-line RSA private key with \n>
PUBLIC_KEY=<single-line RSA public key with \n>
# CORS — your frontend domain
ALLOWED_ORIGINS=https://your-frontend.railway.app
# Optional: strict permission guard
PERMISSION_GUARD_STRICT=trueTip: Use
scripts/rotate-jwt-keys.shto generate keys in single-line format ready for environment variables.
bash scripts/rotate-jwt-keys.sh
# Outputs PRIVATE_KEY and PUBLIC_KEY as single-line env vars
# Copy the output directly into Railway Variablesrailway up
# Railway builds the Dockerfile, runs migrations via docker-entrypoint.sh, starts the apprailway run npm run seed:rbaccurl https://your-app.railway.app/health/liveness
# → { "status": "ok" }
curl https://your-app.railway.app/health/readiness
# → { "status": "ok", "info": { "database": {...}, "redis": {...} } }- Go to render.com → New → Web Service
- Connect GitHub repo
RamosJSouza/secure-nestjs-drizzle-template - Environment: Docker
- Dockerfile path:
./Dockerfile - Health check path:
/health/readiness
- Dashboard → New → PostgreSQL (Render provides
DATABASE_URL) - Dashboard → New → Redis (Render provides
REDIS_URL)
Same as Railway above. Render auto-injects DATABASE_URL and REDIS_URL when services are linked.
# Clone the repo
git clone https://github.com/RamosJSouza/secure-nestjs-drizzle-template.git
cd secure-nestjs-drizzle-template
# Configure environment
cp .env.example .env
# Edit .env with your values
# Generate RSA keys
bash scripts/rotate-jwt-keys.sh >> .env
# Start all services
docker compose up -d
# Run migrations and seed
docker compose exec app npm run db:migrate
docker compose exec app npm run seed:rbacThis package is published as secure-nestjs-drizzle-template on the npm registry.
# 1. Build the project
npm run build
# 2. Login to npm
npm login
# 3. Publish (public access, configured in publishConfig)
npm publishThe CD workflow (.github/workflows/cd.yml) publishes automatically on v*.*.* tags:
# Create and push a release tag
git tag v1.0.1
git push origin v1.0.1
# → triggers cd.yml: builds multi-arch Docker image + npm publishPrerequisite: Add
NPM_TOKENsecret to GitHub repository settings (Settings → Secrets → Actions).
After deployment, run the seed to create the default admin role and permissions:
npm run seed:rbacThis creates:
adminrole with all permissions- Default permissions for
user:*,role:*,feature:*,permission:*
To create the first admin user, use the /auth/register endpoint (or add a seed entry for the first user in src/migrations/seeds/run-seed.ts).