How to self-host Proset Community Edition
Proset Community Edition (CE) is the open-source version of Proset. It runs on your own server: your Firebase project, your AI provider key, and your recordings. Hosted Proset.ai is the managed alternative if you prefer no setup.
This guide takes you from an empty Linux server to a running CE instance behind automatic HTTPS, with backups and a repeatable update path. It assumes you are comfortable with a terminal and basic server administration.
The CE is bring-your-own-everything: your Firebase project, your AI provider key, and your email provider. The CE has no telemetry and no phone-home code — your data stays on your server.
Before you begin
- A Linux server (VPS) where you have root or sudo access. About 1 GB of RAM and a few GB of free disk are enough to start.
- A domain name whose DNS A record points to your server's public IP address.
- Docker with the Compose plugin installed (Docker Engine 24+ and Compose v2).
- Git installed.
- A Firebase project on the free (Spark) plan.
- One AI provider API key: OpenAI, Groq, DeepSeek, Mistral, or Fireworks.
Create a Firebase project
- Open the Firebase console, create a project, and give it a name you recognize, such as
proset-ce. - In Build → Authentication → Sign-in method, enable Email/Password.
- In Build → Firestore Database, create the database and choose production mode.
- Download the service account: open Project settings → Service accounts, select Generate new private key, and save the JSON file as
firebase-service-account.jsoninside the CE directory you will clone in the next section. - Register a web app: open Project settings → Your apps → Add app → Web, and copy the six client values it shows (API key, auth domain, project ID, storage bucket, messaging sender ID, and app ID).
- Deploy the Firestore rules that ship with the CE repo. These rules deny all direct client access — in Proset CE, only the server talks to Firestore through the Admin SDK, which bypasses the rules:
npm install -g firebase-tools
firebase login
# run from the CE directory (cloned in the next section)
firebase deploy --only firestore:rules --project <your-project-id>
Configure the environment file
Clone the CE repository and create your .env file:
git clone https://github.com/Schoedel-Design-AI/proset-community.git
cd proset-community
cp .env.example .env
openssl rand -hex 32
The last command generates a random secret. Edit .env and fill in:
BETTER_AUTH_SECRET— paste the random value fromopenssl rand -hex 32(it must be at least 32 characters and must not be a placeholder).PUBLIC_APP_URL— your public URL, for examplehttps://voice.example.com.- At least one AI provider key:
OPENAI_API_KEY,GROQ_API_KEY,DEEPSEEK_API_KEY,MISTRAL_API_KEY, orAI_FIREWORKS_API_KEY. The app routes transcription to whichever provider has credentials. - Firebase —
FIREBASE_PROJECT_ID,GOOGLE_APPLICATION_CREDENTIALS=./firebase-service-account.json, and the sixAIFORMS_PUBLIC_FIREBASE_*client values from the previous section. ADMIN_EMAILS— optional, comma-separated email addresses that become admins on sign-in. Leave it empty for a single-user instance.SENDGRID_API_KEY— optional, enables email verification and password reset. Email features are disabled without it.
Check your configuration before starting:
./scripts/validate-env.sh
Never commit .env or firebase-service-account.json to version control — the repo's .gitignore already excludes them.
Start with Docker
From the CE directory:
docker compose up -d --build
docker compose ps
When the container shows as running, open http://localhost:5000 on the server, or http://<your-server-ip>:5000 from your own computer, and create your account with your email and a password. If you set ADMIN_EMAILS, that account is promoted to admin automatically.
Add HTTPS with Caddy
Caddy obtains and renews TLS certificates automatically, so you do not manage certificates yourself.
- Create a
Caddyfilewith your domain:
voice.example.com {
reverse_proxy localhost:5000
}
- Run Caddy in Docker, opening ports 80 and 443:
docker run -d --name caddy \
-p 80:80 -p 443:443 \
-v "$PWD/Caddyfile:/etc/caddy/Caddyfile:ro" \
-v caddy_data:/data -v caddy_config:/config \
caddy:2
- In
.env, setPUBLIC_APP_URL=https://voice.example.comandAIFORMS_PUBLIC_DOMAIN=voice.example.com, then rebuild:
docker compose up -d --build
Open https://voice.example.com and confirm the site loads over HTTPS. Point additional domains or a subdomain for the API at the same localhost:5000 upstream if you need them.
Back up your instance
Back up three things: the database, the recordings, and the secrets. Do all three on the same schedule.
Database (Firestore). Export the Firestore database to a Cloud Storage bucket you own:
gcloud firestore export gs://<your-bucket>/proset-backups/$(date +%F)
If you prefer the console, Firebase Firestore → Backups provides managed backups where your plan supports them.
Recordings and uploads. Recordings are stored on the Docker volume proset-data (mounted at /app/.local/object-storage). Archive it to a file you can move off the server:
docker run --rm -v proset-data:/data -v "$PWD":/backup alpine \
tar czf /backup/proset-data-$(date +%F).tar.gz -C /data .
Secrets. Keep a copy of .env and firebase-service-account.json somewhere encrypted, such as a password manager or a separate secrets vault. Without them you cannot restore the instance.
Back up at least weekly, and daily if you record frequently. Periodically restore a copy on a test machine so you know the backup actually works. The .env file and the service account are required to restore; the Firestore export and the recordings archive contain the data.
Update the Community Edition
Check the repository's changelog for breaking changes, then:
git pull
docker compose up -d --build
Run a backup first, then verify the version you expected and that sign-in and transcription still work after the update.
Troubleshoot
- Port 5000 is already in use. Set a different port in
.env(PORT=5001) and rundocker compose up -dagain, or find the conflicting process withss -ltnp | grep 5000and stop it. - Firestore permission errors. The CE ships deny-all Firestore rules; only the server should access Firestore. If clients report permission errors, deploy the repo's
firestore.ruleswithfirebase deploy --only firestore:rules --project <your-project-id>. - The server prints "Firebase credentials are not set. Running in DEVELOPMENT mode". Check that
NODE_ENV=productionis set in.env, thatFIREBASE_PROJECT_IDmatches your project, and thatGOOGLE_APPLICATION_CREDENTIALSpoints to an existing service-account JSON file. In production the server refuses to start without Firebase configured. - The container fails to start or restart. Inspect the logs:
docker compose logs proset. The two most common causes are a missing or placeholderBETTER_AUTH_SECRET(regenerate it withopenssl rand -hex 32) and a malformed.envvalue. - Transcription never completes. Run
./scripts/validate-env.shand confirm at least one AI provider key is set and valid.
Migrate to hosted Proset.ai
Hosted Proset.ai and the CE are separate accounts — moving over is a manual export/import, not a sync.
- In the CE, export the recordings and artifacts you want to keep. Use the app's Export an artifact feature (PDF, DOCX, CSV, or Markdown) or copy the transcripts you need.
- Create an account at proset.ai and re-import or re-create the content you exported.
- Keep your CE backups until you have verified everything you need exists in your Proset.ai account.
- When you are satisfied, stop the CE container with
docker compose down(your data stays on the server) or delete the server once the backups are stored somewhere safe.
Verify your installation
Your installation is complete when all of the following are true:
https://voice.example.comloads over HTTPS with no certificate warning.- You can sign in with the account you created.
- A test recording produces a transcript, and you can convert it to an email, task, or summary.
- You have run a full backup (Firestore export, recordings archive, and secrets) and restored it on a test machine at least once.
- You know how to update the CE (
git pullanddocker compose up -d --build) and have done it at least once.