Server Prerequisites. New Deployment
Audience: DevOps / Platform Engineer
Last updated: 2026-03-13
Relates to:deploy/bootstrap.sh,deploy/infrastructure.md
Overview
Section titled “Overview”This document lists everything you need before running bootstrap.sh on a new server.
The bootstrap script handles all software installation and configuration automatically. but it needs the right hardware, OS, network, accounts, and secrets in place first.
1. Server Requirements
Section titled “1. Server Requirements”Minimum Specs
Section titled “Minimum Specs”| Resource | Minimum | Recommended | Current production |
|---|---|---|---|
| CPU | 4 cores | 8+ cores | 28 cores |
| RAM | 4 GB | 8 GB | 128 GB |
| Disk | 40 GB | 100 GB | 916 GB |
| Architecture | x86_64 (amd64) | x86_64 | x86_64 |
| OS | Ubuntu 24.04 LTS | Ubuntu 24.04 LTS | Ubuntu 24.04.2 LTS |
Resource Breakdown (what actually uses what)
Section titled “Resource Breakdown (what actually uses what)”| Component | CPU | RAM | Disk |
|---|---|---|---|
| TapPass app | Low | ~80 MB | ~1 GB (Docker image) |
| PostgreSQL | Low | ~20 MB (grows with data) | ~100 MB (grows) |
| Redis | Low | ~4 MB | Negligible |
| OPA | Negligible | ~10 MB | ~50 MB |
| SPIRE (server + agent) | Low | ~50 MB | ~100 MB |
| Assess service | Low | ~95 MB | ~500 MB (Docker image) |
| License server | Low | ~40 MB | ~200 MB |
| Nginx | Negligible | ~5 MB | Negligible |
| cloudflared (x3 tunnels) | Low | ~15 MB each | ~50 MB |
| MkDocs venv | : | : | ~150 MB |
| Docs + Trust builds | : | : | ~10 MB |
| Docker images (total) | : | : | ~10 GB |
| Total | ~2 cores | ~500 MB | ~15 GB |
The current production server (128 GB RAM, 28 cores) is massively overprovisioned. A 4-core / 8 GB / 50 GB VPS would run everything comfortably.
Network
Section titled “Network”| Requirement | Details |
|---|---|
| Outbound HTTPS | Required: Cloudflare tunnels connect outbound on port 443 |
| Inbound ports | None required: all access goes through Cloudflare tunnels |
| SSH | Port 2222 (only needed for initial setup before tunnel is up) |
| Static IP | Not required (tunnels work behind NAT/CGNAT) |
| Bandwidth | Low: docs/trust are static sites, SSH is lightweight |
The server does NOT need any inbound ports open to the internet. All traffic flows through Cloudflare Tunnels (outbound connections).
2. Accounts & Services
Section titled “2. Accounts & Services”You need active accounts on these external services before running bootstrap.
Required
Section titled “Required”| Service | What for | Sign up | Cost |
|---|---|---|---|
| Cloudflare | Tunnels, DNS, Zero Trust, DDoS protection | dash.cloudflare.com | Free plan works |
| GitHub | Source code hosting | github.com | Free for private repos |
Required (configured in .env.prod)
Section titled “Required (configured in .env.prod)”| Service | What for | Get credentials from | Env var |
|---|---|---|---|
| Google OAuth | SSO login for users | console.cloud.google.com > APIs & Services > Credentials | GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET |
| Resend | Transactional email + alert notifications | resend.com | RESEND_API_KEY |
| OpenAI | LLM provider for AI agents | platform.openai.com | OPENAI_API_KEY |
Cloudflare specifics
Section titled “Cloudflare specifics”| What | Details |
|---|---|
| Domain | tappass.ai must be managed by Cloudflare (nameservers pointed to Cloudflare) |
| Account email | jens.bontinck@cogniqor.ai |
| Plan | Free plan is sufficient |
| Zero Trust | Free plan (up to 50 users) |
3. Secrets & Credentials
Section titled “3. Secrets & Credentials”Files you need to bring to the new server
Section titled “Files you need to bring to the new server”| File | What | How to get it |
|---|---|---|
| deploy/.env.prod | All app secrets (22 variables) | Copy from current server or secrets manager |
| ~/.ssh/id_github_server | GitHub deploy key | Generate new or copy existing |
| ~/.ssh/id_github_server.pub | Public key (registered on GitHub) | Paired with above |
.env.prod variables
Section titled “.env.prod variables”All of these must be set. The bootstrap script does NOT generate them.
App Config:
TAPPASS_PRODUCTION=1TAPPASS_HOST=0.0.0.0TAPPASS_PORT=9620TAPPASS_CORS_ORIGINS=https://app.tappass.aiTAPPASS_FINGERPRINT=prod-tappass-cogniqor-01 # unique per serverCryptographic Secrets (generate new per server):
TAPPASS_JWT_SECRET= # 48+ charsTAPPASS_VAULT_KEY= # 32 bytes base64TAPPASS_ADMIN_API_KEY= # 32+ charsPOSTGRES_PASSWORD= # 32+ charsSPIRE_JOIN_TOKEN= # UUIDSSO / OAuth:
TAPPASS_SSO_PROVIDER=googleTAPPASS_SSO_CLIENT_ID= # from Google Cloud ConsoleTAPPASS_SSO_CLIENT_SECRET= # from Google Cloud ConsoleTAPPASS_SSO_REDIRECT_URI=https://app.tappass.ai/sso/callbackTAPPASS_SSO_ALLOWED_DOMAINS=cogniqor.aiTAPPASS_SAML_ACS_URL=https://app.tappass.ai/saml/acsGOOGLE_OAUTH_CLIENT_ID= # same as SSO_CLIENT_IDGOOGLE_OAUTH_CLIENT_SECRET= # same as SSO_CLIENT_SECRETExternal APIs:
OPENAI_API_KEY= # from platform.openai.comRESEND_API_KEY= # from resend.comLicense:
TAPPASS_LICENSE= # issued by CogniqorGenerated by bootstrap (don’t set manually):
TUNNEL_TOKEN= # generated when creating the app tunnelTAPPASS_TOKEN_KEY_FILE=/app/keys/tappass-token.pemGenerating new secrets for a fresh server
Section titled “Generating new secrets for a fresh server”openssl rand -base64 48 # TAPPASS_JWT_SECRETopenssl rand -base64 32 # TAPPASS_VAULT_KEYecho "tp_admin_$(openssl rand -base64 32 | tr -d '=/+')" # TAPPASS_ADMIN_API_KEYopenssl rand -hex 24 # POSTGRES_PASSWORDuuidgen # SPIRE_JOIN_TOKENGitHub deploy key
Section titled “GitHub deploy key”On the new server (as the deploy user):
ssh-keygen -t ed25519 -f ~/.ssh/id_github_server -N "" -C "tappass-deploy@$(hostname)"Add the public key to GitHub:
cat ~/.ssh/id_github_server.pubGo to github.com/tappass/tappass > Settings > Deploy keys > Add (read-only is sufficient).
SSH config:
cat >> ~/.ssh/config << 'EOF'Host github.com IdentityFile ~/.ssh/id_github_server StrictHostKeyChecking noEOF4. DNS (pre-existing)
Section titled “4. DNS (pre-existing)”These DNS records already exist on Cloudflare. The bootstrap script will create new tunnels and attempt to update them. If the records already exist, you need to update them manually in the Cloudflare dashboard to point to the new tunnel IDs.
| Record | Type | Points to |
|---|---|---|
| app.tappass.ai | CNAME | [app-tunnel-id].cfargotunnel.com |
| assess.tappass.ai | CNAME | [assess-tunnel-id].cfargotunnel.com |
| licenses.tappass.ai | CNAME | [license-tunnel-id].cfargotunnel.com |
| ssh.tappass.ai | CNAME | [ssh-tunnel-id].cfargotunnel.com |
| docs.tappass.ai | CNAME | [docs-tunnel-id].cfargotunnel.com |
| trust.tappass.ai | CNAME | [trust-tunnel-id].cfargotunnel.com |
| tappass.ai | CNAME | tappass-ai.pages.dev |
| www.tappass.ai | CNAME | tappass-ai.pages.dev |
When migrating to a new server, you create new tunnels (new IDs). Update these CNAME records to point to the new tunnel IDs. The old tunnel on the old server should be stopped/deleted.
5. Repos to clone
Section titled “5. Repos to clone”The bootstrap script clones the main repo. These two are separate and need manual setup:
| Repo | Local path | Purpose |
|---|---|---|
| tappass/tappass | ~/projects/tappass | Main app + docs + trust + deploy |
| tappass/tappass-assess | ~/tappass-assess | Assess service |
| tappass/tappass-license-server | ~/tappass_license_server | License server |
After bootstrap, clone the other two:
git clone git@github.com:tappass/tappass-assess.git ~/tappass-assessgit clone git@github.com:tappass/tappass-license-server.git ~/tappass_license_server6. Full Deployment Checklist
Section titled “6. Full Deployment Checklist”Use this checklist when deploying to a new server.
Pre-deploy
Section titled “Pre-deploy”- Server provisioned (Ubuntu 24.04, 4+ cores, 8+ GB RAM, 50+ GB disk)
- SSH access works (port 22 initially)
- Cloudflare account ready with tappass.ai domain
- GitHub deploy key generated and added to all 3 repos
- .env.prod prepared with all secrets
- Google OAuth redirect URIs updated (if domain changed)
Bootstrap
Section titled “Bootstrap”- Copied deploy key to server
- Ran: sudo ./bootstrap.sh
- Authenticated with Cloudflare (browser step)
- Verified: docs.tappass.ai loads
- Verified: trust.tappass.ai loads
- Verified: ssh ssh.tappass.ai works
App deployment
Section titled “App deployment”- Copied .env.prod to ~/tappass/deploy/
- Ran: docker compose —env-file .env.prod -f docker-compose.prod.yml up -d
- Registered SPIRE workload entries
- Verified: app.tappass.ai loads
Additional services
Section titled “Additional services”- Cloned and started tappass-assess
- Cloned and started tappass_license_server
- Set up license server backup cron
Security
Section titled “Security”- Zero Trust policy set for ssh.tappass.ai (only your email)
- Old server tunnels deleted in Cloudflare dashboard
- DNS CNAME records updated to new tunnel IDs
- Verified healthcheck: ~/bin/healthcheck.sh
- Changed default password
Post-deploy verification
Section titled “Post-deploy verification”- Tested SSO login on app.tappass.ai
- Tested docs auto-deploy (push a change, wait 5 min)
- Verified backups run: ~/bin/backup-postgres.sh
- Verified alerts work: stop a service, check email
7. Quick Start (TL;DR)
Section titled “7. Quick Start (TL;DR)”On a fresh Ubuntu 24.04 server:
# 1. Copy deploy keyscp ~/.ssh/id_github_server user@new-server:~/.ssh/
# 2. Clone and bootstrapssh user@new-servergit clone git@github.com:tappass/tappass.git ~/projects/tappasssudo ~/projects/tappass/deploy/bootstrap.sh
# 3. Copy secrets and start appscp .env.prod user@new-server:~/tappass/deploy/cd ~/tappass/deploydocker compose --env-file .env.prod -f docker-compose.prod.yml up -d
# 4. Clone and start other servicesgit clone git@github.com:tappass/tappass-assess.git ~/tappass-assesscd ~/tappass-assess && docker compose up -d
git clone git@github.com:tappass/tappass-license-server.git ~/tappass_license_servercd ~/tappass_license_server && docker compose up -d
# 5. Verify~/bin/healthcheck.shTotal time: ~15 minutes (mostly waiting for Docker builds).