Get Started

From download to a running community — whether you're joining someone else's server or setting up your own.

1. The Client 2. Your Own Server 3. Building a Community Troubleshooting Updating

Part 1: The Client (for users)

Windows

Installer (recommended)

Installs the app, adds a desktop shortcut, and handles file associations. To update, just run the new installer.

Portable (.exe, no install)

Run from anywhere — USB drives, restricted environments. Create a folder named data next to the .exe and GoodComms keeps all settings, logs, and cache there instead of AppData.

Linux

The Linux client is a portable binary — no installation required:

chmod +x gc-client
./gc-client

Screen sharing requires PipeWire and xdg-desktop-portal — already present on most modern desktop distros.

Joining a Server

  1. Launch the app and click the + (Plus) icon in the sidebar.
  2. Enter the address your server owner gave you — a domain or an IP address.
  3. Register a new account or log in. Accounts are local to each server — there is no global GoodComms account.
  4. Enable Save Password for a one-click quick-join button on your next launch.

Part 2: Setting Up a Server (for owners)

The server authenticates sessions, stores messages in SQLite, and relays media packets — it never processes or decodes your data. CPU and RAM needs are minimal; bandwidth and storage are the real scaling factors. This walkthrough covers the recommended production setup: Docker + a domain + Caddy. For self-signed/LAN, manual TLS, or bare-binary setups, see Deploy a Server.

Step 1: Compose file

Caddy on the host (most common for a simple VPS): expose TCP 4076 on loopback only, point Caddy at localhost:4076. Prefer a fully commented config? Use the .env template with env_file: .env.

# docker-compose.yml
services:
  goodcomms-server:
    image: goodcomms/gc-server:latest
    container_name: gc-server
    restart: unless-stopped
    ports:
      - "127.0.0.1:4076:4076"  # TCP - loopback only, your host proxy connects here
      - "4077:4077/udp"         # Voice (Opus) - must be open in your firewall
      - "4078:4078/udp"         # Video (H.264) - must be open in your firewall
    environment:
      - IP_ADDR=0.0.0.0
      - PORT=4076
      - NO_TLS=true             # The proxy handles TLS - do not remove this
      - TRUST_PROXY=true        # Rate limiting keys on X-Forwarded-For - required behind a proxy
      - DATABASE_PATH=/app/data/goodcomms.db
      - STORAGE_DIR=/app/uploads
      - DRIVE_DIR=/app/drive
      - RETENTION_DAYS=0        # 0 = media kept forever
      - LOG_DIR=/app/logs
      # First run only - remove after logging in:
      # - ADMIN_USER=your_username
      # - ADMIN_PASS=your_secure_password
    volumes:
      - ./data:/app/data         # Database and certs
      - ./uploads:/app/uploads   # Chat file uploads
      - ./drive:/app/drive       # Server Drive files
      - ./logs:/app/logs         # Server logs
# Caddyfile
chat.yourdomain.com {
    reverse_proxy localhost:4076
}

Caddy running in Docker instead? Drop the loopback port mapping, put both containers on a shared network, and proxy to gc-server:4076 — the full variant is on the deploy page. Nginx and Traefik work the same way: TLS terminates at the proxy, GoodComms receives plain HTTP on 4076.

Step 2: Open firewall ports

Your proxy handles TCP 443. Voice and video are direct UDP — they cannot be proxied and must be open at every layer (server firewall, cloud security group, router): UDP 4077 (voice) and UDP 4078 (video).

Voice/video silently failing is almost always these two ports being blocked.

Step 3: Bootstrap your owner account

Uncomment ADMIN_USER / ADMIN_PASS in the compose file, then:

docker compose up -d

Connect with the client and log in — that claims the Owner role. Then immediately docker compose down, remove the two credential lines, and docker compose up -d again. Your account lives in the database now; credentials don't belong in config files.

Part 3: Building Your Community

Channels

In Admin → Channels, click New Channel. A channel can be Text, Voice, or both. Private channels are hidden from everyone except roles you grant.

Note: a channel's privacy (public vs. private) can't be changed after creation — everything else (name, description, type, position) can.

Roles

Roles use a hierarchy — higher numbers have authority over lower ones:

RoleHierarchyDescription
Owner101Full control, bypasses all permission checks
Administrator100Broad administrative access
Default10Base role assigned to all new members

Example moderator: create a role named Moderator at hierarchy 50, grant manage_messages + manage_users, assign it under Admin → Users. They can moderate anyone ranked below them but can't touch channels or roles.

Server Drive

The Drive tab is private file storage for your community — folders, uploads, sharing — stored on your own hardware with no third-party cloud.

Troubleshooting

Can't connect to the server

Verify the domain resolves to your server's IP, the proxy is running and forwarding to 4076, and check logs: docker compose logs -f goodcomms-server

Voice or video not working

Almost always a firewall issue — verify UDP 4077 and 4078 are open at every layer. These ports cannot be proxied; they must be directly reachable.

Self-signed certificate warning

Expected when connecting via IP address instead of a domain — click Connect anyway. Normal for LAN setups; see Mode B.

Linux screen sharing issues

Ensure PipeWire and xdg-desktop-portal are installed and running. System-audio loopback isn't supported on Linux. If the picker doesn't appear on a second stream, restart the app.

GIF search not working

GIF search is optional and configured by the server owner via GIPHY_API_KEY / KLIPY_API_KEY.

Updating the Server

docker compose pull          # Pull the new image
docker compose up -d         # Restart with it - zero config changes needed

Your database, uploads, and drive files live in the mounted volumes and are untouched by updates. Pin image: to a version tag if you'd rather not track latest.

All deployment modes, ports, and environment variables: Deploy a Server. Found a bug? Open an issue on GitHub.