Deployment Guide

Phixr runs as a set of containers: the Phixr bot, an OpenCode server, Redis for session state, and optionally PostgreSQL.

Architecture Overview

                          +-----------------+
GitLab Webhooks --------> |   Phixr Bot     | ------> GitLab API
                          |   (FastAPI)     |
                          +-------+---------+
                                  |
                    +-------------+-------------+
                    |             |             |
              +-----+----+ +-----+----+ +------+-----+
              | OpenCode  | |  Redis   | | PostgreSQL |
              |  Server   | | (state)  | | (optional) |
              +-----------+ +----------+ +------------+

Prerequisites

Start All Services

podman compose --profile full-stack up -d

This starts:

Check Status

podman ps --format "table {{.Names}}\t{{.Status}}"

All services should show “Up” with opencode-server and redis showing “(healthy)”.

View Logs

# All services
podman compose --profile full-stack logs -f

# Specific service
podman logs -f phixr_phixr_1

Stop

podman compose --profile full-stack down

Rebuild After Code Changes

podman compose --profile full-stack build
podman compose --profile full-stack up -d

Custom Domain Setup

Phixr generates links to the OpenCode web UI in GitLab comments. By default, these point to localhost:4096. For production, configure a public URL.

Configure the Public OpenCode URL

In .env.local:

# Internal URL (Docker service name, used for API calls between containers)
PHIXR_SANDBOX_OPENCODE_SERVER_URL=http://opencode-server:4096

# Public URL (what users click in GitLab comments)
PHIXR_SANDBOX_OPENCODE_PUBLIC_URL=https://opencode.example.com

For the Phixr bot itself:

PHIXR_API_URL=https://phixr.example.com

Reverse Proxy (nginx example)

Put both Phixr and OpenCode behind a reverse proxy:

# Phixr API + webhooks
server {
    listen 443 ssl;
    server_name phixr.example.com;

    location / {
        proxy_pass http://localhost: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;
    }

    # WebSocket support for vibe rooms
    location /ws {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

# OpenCode web UI
server {
    listen 443 ssl;
    server_name opencode.example.com;

    location / {
        proxy_pass http://localhost:4096;
        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;

        # SSE support
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 86400s;
    }
}

GitLab Webhook URL

Update the webhook in GitLab to point to your public Phixr URL:

https://phixr.example.com/webhooks/gitlab

Podman Rootless Notes

Phixr is designed for Podman rootless. A few things to be aware of:

If you see permission errors on Fedora/RHEL, ensure the :Z labels are present on volume mounts in docker-compose.yml.

Production Checklist

Health Checks

# Phixr health
curl https://phixr.example.com/health

# Sandbox health (includes OpenCode + Redis status)
curl https://phixr.example.com/api/v1/sandbox/health

# Session list
curl https://phixr.example.com/api/v1/sessions