Self-Hosted ZNC IRC Bouncer with Docker & Reverse Proxy
ZNC is an advanced IRC network bouncer that stays connected to IRC servers even when you are offline. It allows you to replay the chat logs you missed and keeps your nick online 24/7.
While ZNC is easy to install via package managers, running it in Docker keeps the host system clean. However, setting it up with a Reverse Proxy (like Nginx or YunoHost) and handling permissions correctly requires a few specific steps.
This guide covers installing the linuxserver/znc image, generating the initial configuration securely, and integrating it with a web proxy.
Prerequisites
- A VPS or Linux server with Docker and Docker Compose installed.
- A Reverse Proxy (Nginx, Traefik, or YunoHost).
- Your user PUID and PGID (run
idin your terminal to find these).
Step 1: Directory & Permissions
First, create a dedicated directory for ZNC. Using the LinuxServer.io image allows us to map the container's internal user to our host user, preventing permission issues.
# Create the directory structure
mkdir -p ~/docker/znc/config
Step 2: The Docker Compose File
Create a docker-compose.yml file inside your ZNC directory.
We are mapping two ports:
- 6501: The Web UI port. We map this to
127.0.0.1(localhost) only, because we will expose it via a secure Reverse Proxy later. - 6697: The IRC port. We map this globally so IRC clients can connect directly via SSL.
services:
znc:
image: linuxserver/znc:latest
container_name: znc
environment:
- PUID=23691 # Replace with your User ID (run `id` to check)
- PGID=23691 # Replace with your Group ID
- TZ=Asia/Kuala_Lumpur
volumes:
- ./config:/config
ports:
- "127.0.0.1:6501:6501" # Internal Web UI (for Reverse Proxy)
- "6697:6697" # External IRC Port (SSL)
restart: unless-stopped
Step 3: Generating the Configuration (The Tricky Part)
ZNC requires an initial configuration file with a hashed password to start. You cannot simply create a text file. Furthermore, the LinuxServer image does not allow running the generator as root.
To solve this, we use s6-setuidgid to run the configuration wizard as the correct internal user (abc).
Run this command to start the wizard:
docker compose run --rm znc s6-setuidgid abc znc --makeconf
Answer the prompts as follows:
- Listen on port:
6501 - Listen using SSL:
No(Crucial: The reverse proxy handles SSL for the website; ZNC handles it internally for the IRC port). - Listen using IPv6:
Yes - Username/Password: Set your desired admin credentials.
- Launch ZNC now?
No
Note: If you encounter errors about "Old Config" or permissions, delete the contents of the
./configfolder and try the command again.
Step 4: Start the Service
Once the configuration file is generated, start the container in the background:
docker compose up -d
Step 5: Reverse Proxy Setup (YunoHost Example)
To access the ZNC web interface securely (e.g., at znc.obulou.org), you need to point your proxy to the local port we defined.
If you are using YunoHost:
- Go to Web Admin > Applications > Install.
- Select "Redirect" (or "Custom Webapp").
- Label: ZNC
- Domain/Path: e.g.,
znc.obulou.orgorobulou.org/znc - Destination URL:
http://127.0.0.1:6501
Step 6: Connecting Your Client
You can now connect any IRC client (HexChat, The Lounge, mIRC) to your bouncer.
- Server:
obulou.org(Your domain) - Port:
6697 - SSL/TLS: Enabled (Accept invalid certificate if self-signed)
- Password:
username/network:password
A Note on SSL Certificates
By default, ZNC generates a self-signed certificate for the IRC port (6697). Your IRC client may warn you about this. You can accept the warning, or for a "cleaner" setup, you can mount your Let's Encrypt certificates (from /etc/letsencrypt or YunoHost certs) into the ZNC container volume, though that requires additional file permission management.
No comments to display
No comments to display