# Fluxer Chat Server Deployment

## Overview
Fluxer is an open-source, independent instant messaging and VoIP platform deployed on st.vish.gg, replacing the previous Stoat Chat installation.

## Deployment Details

### Domain Configuration
- **Primary Domain**: st.vish.gg
- **DNS Provider**: Cloudflare (DNS-only, A record to Seattle VM YOUR_WAN_IP)
- **SSL/TLS**: Wildcard Let's Encrypt certificate (`*.st.vish.gg` + `st.vish.gg`)
- **Reverse Proxy**: nginx on the host, proxying to Docker containers

### Architecture
Fluxer uses a unified server architecture (`fluxer-server`) that bundles all backend services into a single deployable container.

#### Core Services (bundled in fluxer_server)
- **app**: Frontend web application
- **api**: REST API backend
- **gateway**: WebSocket gateway for real-time communication
- **admin**: Administrative panel
- **media_proxy**: Media processing and proxying
- **s3**: Built-in S3-compatible object storage

#### Supporting Services
- **valkey**: Cache and session storage (Redis-compatible)
- **meilisearch**: Full-text search engine (optional, `search` profile)
- **elasticsearch**: Alternative search backend (optional, `search` profile)
- **livekit**: Voice and video calling infrastructure (optional, `voice` profile)
- **nats-core**: Message broker
- **nats-jetstream**: Persistent message streaming

### Docker Compose Configuration
The deployment uses two compose files:
- **`/root/fluxer/compose.yaml`**: Base service definitions
- **`/root/fluxer/compose.override.yaml`**: Local overrides (build from source, port binding to 127.0.0.1:8088)

### Nginx Configuration
The nginx reverse proxy is configured at `/etc/nginx/sites-available/fluxer` (symlinked to sites-enabled) and routes:

| Domain | Upstream |
|--------|----------|
| `st.vish.gg` | `http://127.0.0.1:8088` (main app + all routes) |
| `api.st.vish.gg` | `http://127.0.0.1:8088/api/` |
| `events.st.vish.gg` | `http://127.0.0.1:8088/gateway/` (WebSocket) |
| `files.st.vish.gg` | `http://127.0.0.1:8088/media/` |
| `proxy.st.vish.gg` | `http://127.0.0.1:8088/s3/` |
| `voice.st.vish.gg` | `http://127.0.0.1:8088/livekit/` |

SSL certificates are at `/etc/nginx/ssl/st.vish.gg.{crt,key}`.

### Current Status

**DEPLOYED AND RUNNING** on st.vish.gg (Seattle VM)

#### Service Health (as of April 2026)
```
CONTAINER         STATUS            PORT
fluxer_server     Up (healthy)      127.0.0.1:8088->8080/tcp
valkey            Up (healthy)      6379/tcp (internal)
livekit           Up (healthy)      7880-7881/tcp, 50000-50100/udp
nats-core         Up                4222/tcp (internal)
nats-jetstream    Up                4223/tcp (internal)
meilisearch       Up (healthy)      7700/tcp
elasticsearch     Up (healthy)      9200/tcp
```

#### Health Check
```bash
# Internal health check
curl -fsS http://127.0.0.1:8088/_health

# Returns JSON with status of: kv, s3, jetstream, mediaProxy, admin, api, app
```

## Maintenance

### Container Management
```bash
cd /root/fluxer

# View logs
MEILI_MASTER_KEY=<key> docker compose logs -f fluxer_server

# Restart services
MEILI_MASTER_KEY=<key> docker compose restart fluxer_server

# Rebuild from source and redeploy
MEILI_MASTER_KEY=<key> docker compose build --no-cache fluxer_server
MEILI_MASTER_KEY=<key> docker compose up -d fluxer_server
```

Note: `MEILI_MASTER_KEY` must be set (or use a `.env` file) because `compose.yaml` requires it, even if the meilisearch service is not started.

### Updating
```bash
cd /root/fluxer
git fetch --all
git pull origin refactor   # Currently tracking the 'refactor' branch

# Rebuild and redeploy
MEILI_MASTER_KEY=<key> docker compose build --no-cache fluxer_server
MEILI_MASTER_KEY=<key> docker compose up -d fluxer_server
```

### Nginx Management
```bash
# Test configuration
nginx -t

# Reload after config changes
systemctl reload nginx

# View active sites
ls -la /etc/nginx/sites-enabled/
```

### SSL Certificate Renewal
The wildcard cert covers all `*.st.vish.gg` subdomains. Renew with:
```bash
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d st.vish.gg \
  -d "*.st.vish.gg"
```

Current certificate expires: May 16, 2026.

## Configuration

### Fluxer Config
- **Application config**: `/root/fluxer/config/config.json`
- **Environment overrides**: `/root/fluxer/dev/.env`
- **Base domain**: `st.vish.gg`
- **Database**: SQLite at `/usr/src/app/data/db/fluxer.db` (inside container volume `fluxer_data`)
- **Cache**: Valkey (Redis-compatible) at `redis://valkey:6379/0`

### Repository
- **Source**: https://github.com/fluxerapp/fluxer
- **Branch**: `refactor` (85 commits ahead of `main` as of April 2026)
- **Local clone**: `/root/fluxer`

## Security Notes
- All services run in isolated Docker containers
- nginx handles SSL termination on the host
- fluxer_server binds only to `127.0.0.1:8088` (not exposed publicly)
- Internal services (valkey, nats) are not exposed to the host network

## Changelog

- **April 7, 2026**: Removed stale nextcloud nginx config that was interfering with routing. Rebuilt fluxer_server from latest source on `refactor` branch.
- **March 21, 2026**: Migrated from dev multi-container architecture to unified `fluxer-server:stable` image with compose.override.yaml for local builds.
- **February 15, 2026**: Initial deployment, replacing Stoat Chat.

---

**Last Updated**: April 7, 2026
**Status**: Production Running
