- Express + TypeScript backend with IRC connection manager - React + Vite frontend with mIRC-inspired theme - Drizzle ORM + PostgreSQL schema (users, connections, channels, messages) - Redis pub/sub for real-time WebSocket delivery across replicas - IRC color code parser (16 + 99 extended palette) - Kubernetes manifests for homecloud deployment - Multi-stage Dockerfile with non-root user - docker-compose for local development
158 lines
6.8 KiB
Markdown
158 lines
6.8 KiB
Markdown
# mIRCcloud.com
|
|
|
|
A modern web-based IRC client inspired by the classic mIRC desktop application. Connect to IRC networks from your browser with a nostalgic Win32 aesthetic, persistent message history, and real-time WebSocket communication.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Internet │
|
|
│ mirccloud.com (DNS → 24.144.124.133) │
|
|
└─────────────────┬───────────────────────────────────────┘
|
|
│
|
|
┌─────────────────▼───────────────────────────────────────┐
|
|
│ DigitalOcean Edge Node │
|
|
│ nginx-public ingress controller │
|
|
└─────────────────┬───────────────────────────────────────┘
|
|
│ WireGuard tunnel
|
|
┌─────────────────▼───────────────────────────────────────┐
|
|
│ k3s Homecloud Cluster │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────┐ │
|
|
│ │ mirccloud namespace │ │
|
|
│ │ │ │
|
|
│ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ │
|
|
│ │ │ App │ │ Postgres │ │ Redis │ │ │
|
|
│ │ │ (x2) │──│ (16) │ │ (7-alp) │ │ │
|
|
│ │ │ :3000 │ │ :5432 │ │ :6379 │ │ │
|
|
│ │ └─────────┘ └──────────┘ └──────────┘ │ │
|
|
│ │ │ │ │
|
|
│ │ ┌────▼────┐ │ │
|
|
│ │ │ NFS PVC │ (uploads, postgres, redis) │ │
|
|
│ │ │Synology │ │ │
|
|
│ │ └─────────┘ │ │
|
|
│ └──────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**Components:**
|
|
- **Client** — React + Vite SPA with mIRC-inspired dark theme
|
|
- **Server** — Express + WebSocket server handling IRC connections
|
|
- **PostgreSQL** — Message persistence, user accounts, connection configs
|
|
- **Redis** — Pub/sub for real-time event distribution across app replicas
|
|
- **NFS (Synology)** — Persistent storage for all stateful data
|
|
|
|
## Local Development
|
|
|
|
### Prerequisites
|
|
|
|
- Node.js 20+
|
|
- Docker & Docker Compose
|
|
|
|
### Quick Start
|
|
|
|
```bash
|
|
# Start infrastructure (postgres + redis)
|
|
docker compose up postgres redis -d
|
|
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Run database migrations
|
|
cd server && npx drizzle-kit push
|
|
|
|
# Start the server (watches for changes)
|
|
npm run dev --workspace=server
|
|
|
|
# In another terminal, start the client
|
|
npm run dev --workspace=client
|
|
```
|
|
|
|
### Using Docker Compose (full stack)
|
|
|
|
```bash
|
|
docker compose up
|
|
```
|
|
|
|
The app will be available at http://localhost:3000 (API) and http://localhost:5173 (client dev server).
|
|
|
|
## Deployment
|
|
|
|
### Build & Push Container Image
|
|
|
|
```bash
|
|
# Login to Gitea registry
|
|
docker login git.lab.fairings.org
|
|
|
|
# Build and push
|
|
docker build -t git.lab.fairings.org/jpreston/mirccloud/app:latest .
|
|
docker push git.lab.fairings.org/jpreston/mirccloud/app:latest
|
|
```
|
|
|
|
### Deploy to Kubernetes
|
|
|
|
```bash
|
|
# Create namespace
|
|
kubectl apply -f kubernetes/namespace.yaml
|
|
|
|
# Create secrets (copy from example first)
|
|
cp kubernetes/secrets.yaml.example kubernetes/secrets.yaml
|
|
# Edit kubernetes/secrets.yaml with real base64-encoded values
|
|
kubectl apply -f kubernetes/secrets.yaml
|
|
|
|
# Deploy everything
|
|
kubectl apply -f kubernetes/configmap.yaml
|
|
kubectl apply -f kubernetes/pvc.yaml
|
|
kubectl apply -f kubernetes/postgres.yaml
|
|
kubectl apply -f kubernetes/redis.yaml
|
|
kubectl apply -f kubernetes/deployment.yaml
|
|
kubectl apply -f kubernetes/service.yaml
|
|
kubectl apply -f kubernetes/ingress.yaml
|
|
kubectl apply -f kubernetes/networkpolicy.yaml
|
|
```
|
|
|
|
### DNS Setup
|
|
|
|
Point these records to the edge node:
|
|
- `mirccloud.com` → A record → `24.144.124.133`
|
|
- `www.mirccloud.com` → A record → `24.144.124.133`
|
|
|
|
TLS certificates are automatically provisioned by cert-manager using the `letsencrypt-prod` ClusterIssuer.
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Description | Default |
|
|
|----------|-------------|---------|
|
|
| `PORT` | Server listen port | `3000` |
|
|
| `DATABASE_URL` | PostgreSQL connection string | — |
|
|
| `REDIS_URL` | Redis connection string | — |
|
|
| `JWT_SECRET` | Secret for signing JWT tokens | — |
|
|
| `CORS_ORIGIN` | Allowed CORS origin | `http://localhost:5173` |
|
|
| `NODE_ENV` | Environment (development/production) | `development` |
|
|
| `POSTGRES_PASSWORD` | PostgreSQL password (used in k8s) | — |
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
mirccloud.com/
|
|
├── client/ # React frontend (Vite)
|
|
│ ├── src/
|
|
│ │ ├── components/ # UI components (TreeBar, MessagePanel, etc.)
|
|
│ │ ├── pages/ # Login, Register pages
|
|
│ │ ├── stores/ # Zustand state (auth, irc, websocket)
|
|
│ │ ├── styles/ # mIRC theme CSS
|
|
│ │ └── utils/ # IRC color parser, helpers
|
|
│ └── index.html
|
|
├── server/ # Express + WebSocket backend
|
|
│ └── src/
|
|
│ ├── auth/ # JWT + bcrypt authentication
|
|
│ ├── db/ # Drizzle ORM schema + connection
|
|
│ ├── irc/ # IRC connection manager + event handlers
|
|
│ ├── routes/ # REST API routes
|
|
│ └── websocket/ # WebSocket server
|
|
├── kubernetes/ # Production deployment manifests
|
|
├── Dockerfile # Multi-stage production build
|
|
├── docker-compose.yml # Local development stack
|
|
└── package.json # Workspace root
|
|
```
|