Installation
AI Admin Panel installs on a fresh Linux server and sets up everything: Docker, PostgreSQL, Valkey, Traefik (auto-SSL), Keycloak (OIDC auth), and the panel itself.
Prerequisites
Server Requirements
| Requirement | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4+ cores |
| RAM | 4 GB | 8+ GB |
| Disk | 20 GB SSD | 50+ GB SSD |
| OS | Ubuntu 22.04, Ubuntu 24.04, Debian 12 | Ubuntu 24.04 |
| Architecture | x86_64 (amd64), aarch64 (arm64) | x86_64 |
DNS Requirements
Before installing, point your domain to the server:
- A record —
panel.example.com→ your server IP - Wildcard A record —
*.panel.example.com→ same server IP
The wildcard record is essential — every deployed service gets a subdomain like myapp.panel.example.com.
Disable the orange proxy cloud during installation so Let's Encrypt can issue certificates via HTTP challenge. Re-enable it after setup if desired.
Network Requirements
| Port | Direction | Purpose |
|---|---|---|
| 80 | Inbound | HTTP → auto-redirects to HTTPS |
| 443 | Inbound | HTTPS (Traefik terminates SSL) |
| 22 | Inbound | SSH access |
No other services should be running on ports 80/443.
Automated Install
curl -fsSL https://get.aiadminpanel.com | bash
The installer prompts for your domain. To skip prompts, set environment variables:
export PANEL_DOMAIN="panel.example.com"
export ACME_EMAIL="admin@example.com"
curl -fsSL https://get.aiadminpanel.com | bash
Installer Options
| Flag | Description |
|---|---|
--dry-run | Preview all actions without executing |
--verbose | Enable debug output |
--unattended | Non-interactive mode (requires PANEL_DOMAIN env var) |
Environment Variables
| Variable | Required | Description |
|---|---|---|
PANEL_DOMAIN | Yes | Base domain (e.g., panel.example.com) |
ACME_EMAIL | No | Email for Let's Encrypt (default: admin@example.com) |
CF_DNS_API_TOKEN | No | Cloudflare API token for wildcard certs and auto-DNS |
PANEL_VERSION | No | Version to install (default: latest) |
GOMEMLIMIT | No | Go memory limit (default: 0 = unlimited) |
Manual Install
If you prefer full control, follow these steps:
1. Install Docker
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
Verify Docker 24+:
docker --version
docker compose version
2. Create Directories and Secrets
# Create directories
mkdir -p /opt/aiadminpanel /etc/aiadminpanel /var/log/aiadminpanel /run/secrets
# Generate secrets
dd if=/dev/urandom bs=32 count=1 2>/dev/null | xxd -p -c 64 > /run/secrets/master_key
dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 -w0 | tr '+/' '-_' > /run/secrets/db_password
dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 -w0 | tr '+/' '-_' > /run/secrets/keycloak_admin_password
chmod 600 /run/secrets/*
3. Download and Configure
Clone the repository or download the release files:
cd /opt/aiadminpanel
# Download docker-compose.yml and realm export
curl -fsSL https://raw.githubusercontent.com/iskraecommerce/ai-admin-panel/main/docker-compose.yml -o docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/iskraecommerce/ai-admin-panel/main/keycloak-realm-export.json -o keycloak-realm-export.json
Create the .env file:
cat > /opt/aiadminpanel/.env <<EOF
PANEL_DOMAIN=panel.example.com
ACME_EMAIL=admin@example.com
PANEL_VERSION=latest
GOMEMLIMIT=0
# Keycloak OIDC
OIDC_DISCOVERY_URL=http://keycloak:8180/realms/aiadminpanel/.well-known/openid-configuration
OIDC_CLIENT_ID=panel-backend
KEYCLOAK_URL=http://keycloak:8180
KEYCLOAK_REALM=aiadminpanel
KEYCLOAK_ADMIN_USER=admin
KEYCLOAK_HOSTNAME=auth.panel.example.com
OIDC_REDIRECT_URI=https://panel.example.com/auth/callback
PANEL_INTERNAL_URL=http://panel:8080
# Optional: Cloudflare DNS
# CF_DNS_API_TOKEN=your-token-here
EOF
chmod 600 /opt/aiadminpanel/.env
4. Start the Stack
cd /opt/aiadminpanel
docker compose up -d
This starts all services: PostgreSQL, Valkey, Traefik, Keycloak, Ollama, LiteLLM, and the panel.
5. Create the Keycloak Database
Keycloak needs its own database:
docker exec aiadminpanel_postgresql psql -U aiadminpanel -c "CREATE DATABASE keycloak;" 2>/dev/null || true
6. Wait for Services
# Wait for Keycloak (up to 2 minutes)
echo "Waiting for Keycloak..."
for i in $(seq 1 120); do
health=$(docker inspect --format='{{.State.Health.Status}}' aiadminpanel_keycloak 2>/dev/null || echo "unknown")
[ "$health" = "healthy" ] && echo "Keycloak is ready" && break
sleep 1
done
# Wait for panel
echo "Waiting for panel..."
for i in $(seq 1 60); do
curl -sf http://localhost:8080/healthz > /dev/null 2>&1 && echo "Panel is ready" && break
sleep 1
done
7. Verify
# Health check
curl -s https://panel.example.com/healthz | jq .
# Expected: { "status": "ok" }
# Check all containers
docker compose ps
Open https://panel.example.com in your browser. You'll be redirected to the Keycloak login page.
What the Installer Creates
/opt/aiadminpanel/
├── .env # Environment configuration
├── docker-compose.yml # Production compose file
├── keycloak-realm-export.json # Keycloak realm with panel clients
├── litellm-config.yaml # LiteLLM AI gateway config
└── letsencrypt/
├── acme.json # Let's Encrypt certificates
└── acme-dns.json # Wildcard certificates (if Cloudflare)
/etc/aiadminpanel/
└── config.yaml # Panel configuration
/run/secrets/
├── master_key # Panel encryption key
├── db_password # PostgreSQL password
└── keycloak_admin_password # Keycloak admin password
/var/log/aiadminpanel/
└── install.log # Installation log
What Gets Deployed
The install creates these Docker containers:
| Container | Image | Purpose |
|---|---|---|
aiadminpanel_traefik | traefik:v3 | Reverse proxy, auto-SSL |
aiadminpanel_postgresql | postgres:16-alpine | Primary database |
aiadminpanel_valkey | valkey/valkey:8-alpine | Cache and pub/sub |
aiadminpanel_keycloak | keycloak:26.0 | OIDC identity provider |
aiadminpanel_panel | ghcr.io/aiadminpanel/panel | The panel itself |
aiadminpanel_ollama | ollama/ollama | Local LLM inference |
aiadminpanel_litellm | ghcr.io/berriai/litellm | AI gateway |
Post-Install Verification
# Check panel health
curl -s https://panel.example.com/healthz | jq .
# Check Keycloak is accessible
curl -s -o /dev/null -w "%{http_code}" https://auth.panel.example.com
# Check template catalog loaded
curl -s https://panel.example.com/api/v1/templates/catalog | jq '.templates | length'
# Expected: 45
# Check all containers running
docker compose -f /opt/aiadminpanel/docker-compose.yml ps
Then open https://panel.example.com and log in. The first time, create an admin user through Keycloak at https://auth.panel.example.com/admin/.
Default Credentials
| Service | URL | Username | Password |
|---|---|---|---|
| Keycloak Admin | https://auth.{domain}/admin/ | admin | Contents of /run/secrets/keycloak_admin_password |
| Panel | https://{domain} | Created via Keycloak | — |
Troubleshooting
Port 80/443 already in use
Stop any existing web server:
systemctl stop nginx apache2 2>/dev/null
systemctl disable nginx apache2 2>/dev/null
DNS not resolving
dig +short panel.example.com
dig +short test.panel.example.com
Both should return your server IP. If not, wait for DNS propagation (up to 48 hours for some providers).
Let's Encrypt rate limits
For testing, use the staging CA:
# In docker-compose.yml, change the ACME server to:
# --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
Production rate limit: 50 certificates per registered domain per week.
Keycloak not starting
Keycloak needs its own database. If it fails to start:
# Check logs
docker logs aiadminpanel_keycloak
# Common fix: create the database
docker exec aiadminpanel_postgresql psql -U aiadminpanel -c "CREATE DATABASE keycloak;"
docker compose restart keycloak
Checking logs
docker logs --tail 100 aiadminpanel_panel # Panel
docker logs --tail 100 aiadminpanel_traefik # Traefik
docker logs --tail 100 aiadminpanel_keycloak # Keycloak
docker logs --tail 100 aiadminpanel_postgresql # PostgreSQL
Dry run
Test the installer without making changes:
bash install.sh --dry-run --verbose