Self-Hosting Setup Guide¶
Steps to deploy the GhostBrain voice-interviewer bot on your own Google Cloud Platform (GCP) environment with Twilio. The deployment is fully automated via GitHub Actions and Terraform.
1. Prerequisites¶
- GCP project with billing enabled.
- gcloud CLI installed and logged in:
gcloud auth loginandgcloud config set project YOUR_PROJECT_ID. - GitHub repo with the Ghost Brain code (for CI/CD).
- Accounts and keys:
- Groq — API key for
llama-3.3-70b-versatile. - Deepgram — API key for STT (nova-2).
- OpenAI — API key for TTS (tts-1, alloy).
- Twilio — Account SID and Auth Token (and a Voice-capable phone number).
2. Create Artifact Registry repository (for Docker images)¶
The GitHub Actions deploy workflow pushes the Docker image to Google Artifact Registry. Create the repo before your first deploy:
# Set your project and region (e.g. us-central1)
export PROJECT_ID="your-gcp-project-id"
export REGION="us-central1"
# Enable required APIs
gcloud services enable artifactregistry.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com \
run.googleapis.com \
secretmanager.googleapis.com \
--project="$PROJECT_ID"
# Create the repository (Docker format)
gcloud artifacts repositories create ghost-brain \
--repository-format=docker \
--location="$REGION" \
--project="$PROJECT_ID" \
--description="Ghost Brain bot images"
3. (Optional) Remote Terraform state¶
By default, the pipeline runs without a remote backend, which is generally not recommended for production. To keep state in GCS so you can reliably run Terraform from CI:
-
Create a state bucket and enable versioning:
-
Edit
terraform/backend.tf(uncomment or create it): -
If you previously ran Terraform locally, migrate the state:
terraform init -migrate-state. - In
.github/workflows/deploy.yml, remove-backend=falsefrom theterraform initsteps if you added the remote backend.
4. Configure GitHub repository secrets¶
The entire deployment—including securely saving your API keys to GCP Secret Manager—is handled by the GitHub Actions workflow.
- In your GitHub repository, go to Settings → Secrets and variables → Actions.
- Add the following repository secrets:
| Secret name | Description |
|---|---|
GCP_PROJECT_ID |
Your GCP project ID (e.g. my-project-123). |
GCP_SA_KEY |
JSON key of a GCP service account for GitHub Actions (see below). |
GCP_REGISTRY_REGION |
(Optional) Region for Artifact Registry; default is us-central1. |
GROQ_API_KEY |
Your Groq API key. |
DEEPGRAM_API_KEY |
Your Deepgram API key. |
OPENAI_API_KEY |
Your OpenAI API key. |
TWILIO_ACCOUNT_SID |
Your Twilio Account SID. |
TWILIO_AUTH_TOKEN |
Your Twilio Auth Token. |
ALLOWED_CALLER_ID |
(Optional) Phone number to whitelist. |
SYSTEM_INSTRUCTIONS |
(Optional) Custom system prompt for the AI. |
Creating a service account for GitHub Actions:
- Create a GCP service account (e.g.
github-actions-deploy). - Grant it the following roles:
- Artifact Registry Writer
- Cloud Run Admin
- Service Account User (to attach the runtime SA to Cloud Run)
- Secret Manager Admin (to create secrets)
- Storage Admin (to create the transcript bucket and read/write the Terraform state bucket)
- Service Account Admin & Project IAM Admin (to create the runtime SA and bind roles)
- Create a JSON key for this account and paste the contents into the
GCP_SA_KEYGitHub secret.
5. Deploy via CI/CD¶
Push your code (and backend.tf changes if any) to the main branch.
The .github/workflows/deploy.yml workflow will automatically:
1. Lint and test the code.
2. Build the Docker image and push it to Artifact Registry.
3. Run terraform apply to provision:
- GCS bucket for transcripts.
- Secret Manager secrets (securely populated from your GitHub Secrets).
- Cloud Run service pointing to the new Docker image.
6. Connect Twilio: phone number and WebSocket URL¶
Once the deployment completes successfully, you need to point your Twilio phone number to the newly created Cloud Run service.
-
Get your Cloud Run URL: Check the Terraform outputs in the GitHub Actions logs, or find it in the GCP Console under Cloud Run. It will look like
https://ghost-brain-bot-xxxxx-uc.a.run.app. -
Create a TwiML Bin (Twilio Console → Explore → TwiML Bins):
- Name: e.g.
Ghost Brain WebSocket. - Body (replace the URL with your Cloud Run URL, changing
https://towss://):
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Connect>
<Stream url="wss://YOUR_CLOUD_RUN_URL/ws" />
</Connect>
</Response>
- Assign the TwiML Bin to a phone number:
- Go to Phone Numbers → Manage → Active Numbers.
- Select your number.
- Under "Voice configuration", set "A call comes in" to TwiML Bin and choose the bin you just created. Save.
7. Verification¶
- Health Check: Open
https://YOUR_CLOUD_RUN_URL/healthin a browser. You should see{"status":"ok"}. - Call: Dial your Twilio number. The bot should answer and speak.
- Transcripts: Hang up the call, and check your generated GCS bucket (
ghost_brain-memory-...); the transcript should appear undertranscripts/<call_sid>.md. - Logs: View the Cloud Run logs in the GCP Console to monitor interactions and errors.