This guide walks you through deploying your own QUIRC instance: the web client + Ergo IRC server.
- Node.js 18+
- Docker (for the IRC server)
- A domain name (optional but recommended)
- A static hosting provider (Netlify, Vercel, Cloudflare Pages, or any web server)
git clone https://github.com/virgilvox/quirc.git
cd quirc
npm installCopy the example environment file:
cp .env.example .envEdit .env with your values:
# Your IRC server's hostname
VITE_DEFAULT_SERVER=irc.yourdomain.com
# Your IRC server's port
VITE_DEFAULT_PORT=6697
# WebSocket URL (what the client connects to)
VITE_GATEWAY_URL=wss://irc.yourdomain.com
# Channels to auto-join on connect
VITE_AUTO_JOIN=#general,#randomcd deploy
docker build -t quirc-ergo .
docker run -d -p 8080:8080 -v quirc-data:/ircd \
-e DO_SPACES_KEY=your-key \
-e DO_SPACES_SECRET=your-secret \
-e DO_SPACES_REGION=sfo3 \
-e DO_SPACES_BUCKET=your-bucket \
--name quirc-ergo quirc-ergoYou'll need a reverse proxy (nginx, Caddy) in front to handle TLS:
nginx example:
server {
listen 443 ssl;
server_name irc.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}Caddy example:
irc.yourdomain.com {
reverse_proxy localhost:8080
}
doctl apps create --spec deploy/app.yamlEdit deploy/app.yaml to update your domain and GitHub repo. See deploy/README.md for details.
Edit deploy/ircd.yaml and add your domain:
server:
websockets:
allowed-origins:
- "https://yourdomain.com"Rebuild and restart the container after changing the config.
- Connect your GitHub repo to Netlify
- Set build command:
npm run build - Set publish directory:
dist - Add environment variables in Netlify dashboard (all the
VITE_*vars)
- Import your GitHub repo
- Framework preset: Vite
- Add environment variables in project settings
npm run buildUpload the dist/ folder to your web server. The app is fully static — no server-side rendering needed.
Point your domains:
| Record | Name | Value |
|---|---|---|
| A or CNAME | yourdomain.com |
Your static host |
| A or CNAME | irc.yourdomain.com |
Your IRC server |
QUIRC supports file uploads via S3-compatible storage (DigitalOcean Spaces, AWS S3, MinIO, etc.).
- Create a Spaces bucket (or S3 bucket)
- Enable CDN on the bucket
- Set the server-side environment variables:
DO_SPACES_KEY=your-access-key
DO_SPACES_SECRET=your-secret-key
DO_SPACES_REGION=sfo3
DO_SPACES_BUCKET=your-bucket
DO_SPACES_CDN_DOMAIN=your-bucket.sfo3.cdn.digitaloceanspaces.com
CORS_ORIGIN=https://yourdomain.com- Set the client-side variable:
VITE_UPLOAD_API=/api/upload-urlThe CDN domain is configured server-side via DO_SPACES_CDN_DOMAIN — the Netlify Function returns the full CDN URL to the client after upload.
The upload API runs as a Netlify Function. If you're not using Netlify, you'll need to implement a presigned URL endpoint yourself.
QUIRC's visual style is controlled by CSS custom properties in src/styles/variables.css. You can override:
- Colors:
--q-accent-teal,--q-accent-orange, etc. - Backgrounds:
--q-bg-primary,--q-bg-secondary - Font:
--q-font-mono
The splash screen logo is in src/components/logo/.
After deploying:
- Open your web client URL
- You should see the connection modal with your server pre-filled
- Connect as a guest — verify you join the auto-join channels
- Register a nickname — verify the success flow completes
- Disconnect and reconnect — verify SASL auto-login works
- Send a DM — verify it appears in the DM section of the sidebar
- Upload a file (if configured) — verify the CDN URL is posted