Deployment Guide
Architecture
HASSAR.AI consists of two independently deployed components that connect at runtime:
| Component | Technology | Target | Domain |
|---|---|---|---|
| Frontend | Next.js 16 (App Router) via OpenNext | Cloudflare Workers | hassar.ai |
| Backend | FastAPI + PostgreSQL | Client's dedicated server | api.hassar.ai |
https://api.hassar.ai.https://hassar.ai. Part 1 below is kept for reference — you don't need to repeat these steps unless redeploying from scratch.Before You Begin
- Cloudflare account with
hassar.aidomain already added, and Administrator access (required to connect a GitHub repo for Workers Builds) - Access to GitHub repository:
VlassStudio/HassarAI(private — you'll need to be added as a collaborator, and authenticate with a token or SSH key to clone)
- Ubuntu 22.04 LTS or Debian 12
- Python 3.11+
- PostgreSQL 15+
- Nginx
- DNS:
api.hassar.aipointed to the server's public IP - Firewall: port 443 and 80 open inbound; port 8000 not exposed publicly
Create a Workers Project
Next.js's App Router (SSR, dynamic routes) needs a real request-handling runtime, not just static file hosting. Cloudflare Pages' native Next.js preset only serves the .next build output as static assets and does not run Next.js's Functions runtime — that build 404s on every route. The frontend is deployed as a Cloudflare Worker via the OpenNext adapter instead, which correctly bundles the app to run server-side on Cloudflare.
- Log in to Cloudflare Dashboard → Compute (Workers) → Workers & Pages
- Click Create application
- Click the small "Get started" link under "Looking to deploy Pages?" — this wording is misleading, but it's the entry point for a Git-connected build. Do not use the plain "Ship something new" wizard, which defaults to a bare
wrangler deployWorker scaffold - Continue with GitHub → authorise → select repository VlassStudio/HassarAI
Build Settings
| Field | Value |
|---|---|
| Framework preset | Next.js |
| Build command | npx opennextjs-cloudflare build |
| Deploy command | npx wrangler deploy |
| Path (Advanced settings) | /frontend |
Environment Variable
Add a build variable:
| Variable | Value |
|---|---|
NEXT_PUBLIC_API_URL | https://api.hassar.ai |
Click Deploy. The first build takes 1–2 minutes. Cloudflare assigns a *.workers.dev URL — verify the app loads there before attaching the custom domain.
Custom Domain
- In the Worker's Domains tab → Add Domain → enter
hassar.ai. If Cloudflare shows "No zones match" even though the zone exists, click Onboard domain anyway and continue through the flow — this warning is cosmetic in most cases - For
www.hassar.ai: attaching it directly as a Custom Domain on the Worker can silently fail (the same "no zones match" step not completing). The reliable path is a Redirect Rule instead — under thehassar.aizone → Rules → Redirect Rules → Create rule, use the built-in "Redirect from WWW to root" template as-is, then Deploy. This 301-redirectswww.hassar.ai→hassar.ai - SSL is provisioned automatically once the domain is active
git push to main triggers an automatic rebuild and redeploy via Workers Builds. No manual action needed for future updates.Clone & Install
The repository is private. You've been added as a collaborator on VlassStudio/HassarAI, so a plain HTTPS clone will prompt for GitHub authentication — use a Personal Access Token as the password when prompted, or clone over SSH if you have a key set up on GitHub.
git clone https://github.com/VlassStudio/HassarAI.git
cd HassarAI/backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Using the GitHub CLI instead (handles auth automatically once logged in via gh auth login):
gh repo clone VlassStudio/HassarAI
cd HassarAI/backend
PostgreSQL Setup
sudo -u postgres psql
CREATE DATABASE hassarai;
CREATE USER hassarai_user WITH PASSWORD 'your-strong-password';
GRANT ALL PRIVILEGES ON DATABASE hassarai TO hassarai_user;
\q
Environment File
Create /home/<user>/HassarAI/backend/.env:
DATABASE_URL=postgresql://hassarai_user:your-strong-password@localhost:5432/hassarai
JWT_SECRET_KEY=<random-string-minimum-64-characters>
APP_ENV=production
python3 -c "import secrets; print(secrets.token_hex(32))".env file to git. It is already listed in .gitignore.Systemd Service
Create /etc/systemd/system/hassarai.service (replace <user> with your system username):
[Unit]
Description=HASSAR.AI Backend
After=network.target postgresql.service
[Service]
Type=simple
User=www-data
WorkingDirectory=/home/<user>/HassarAI/backend
EnvironmentFile=/home/<user>/HassarAI/backend/.env
ExecStart=/home/<user>/HassarAI/backend/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 2
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable hassarai
sudo systemctl start hassarai
sudo systemctl status hassarai
Nginx Reverse Proxy
sudo apt install nginx -y
Create /etc/nginx/sites-available/hassarai-api:
server {
listen 80;
server_name api.hassar.ai;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;
proxy_read_timeout 120s;
}
}
sudo ln -s /etc/nginx/sites-available/hassarai-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
SSL Certificate
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d api.hassar.ai
Follow the prompts. Certbot auto-renews every 90 days.
Verify Backend
curl https://api.hassar.ai/
# Expected: {"ok": true}
Create Admin Account
- Open
https://hassar.ai/signupand register the first user - Promote to admin directly in the database:
sudo -u postgres psql hassarai
UPDATE users SET role = 'admin' WHERE email = 'your@email.com';
\q
Connect AGIM
- Log in to
https://hassar.aiwith your admin account - Go to System Admin → AI Config
- Enter the AGIM URL — the AGIM chat endpoint (e.g.
https://api.hassar.ai/chat); confirm the exact path with whoever manages the AGIM server, as it depends on how it's exposed - Enter the AGIM API Key only if AGIM requires one — leave blank if not
- Click Save
- Open Talk to Jim and send a test message — confirm AGIM responds
message, blueprint (if a blueprint is loaded), plus message_id, timestamp, chat_history, and user_context for forward compatibility with a richer AGIM contract. It reads response (or content) back from AGIM's reply.Updating the Application
Push to main branch — Cloudflare Workers Builds rebuilds and redeploys automatically.
cd HassarAI
git pull origin main
cd backend
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart hassarai
Environment Variables Reference
| Variable | Required | Value |
|---|---|---|
NEXT_PUBLIC_API_URL | Yes | https://api.hassar.ai |
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | PostgreSQL connection string |
JWT_SECRET_KEY | Yes | Random string, minimum 64 characters |
APP_ENV | Yes | Set to production on live server |