A Neatnik Guide Published February 8, 2026
Beneath the well-polished exterior of modern web services—propped up by things requiring obscene amounts of JS and CSS, relying on security-bereft dependencies, and designed with dark patterns eliciting engagement and monetization—the protocols of yesterday can still be found, chugging steadily along, barely sipping bandwidth, quietly used by those who either never quit or who have decided to return to simpler, less manipulative ways.
One of those old protocols is IRC, or Internet Relay Chat. IRC has been around since the late 80s, saw its heyday throughout the 90s and early 2000s, and is still in widespread use today. These days it’s been largely supplanted by Discord, though, which has turned simple text chat into an engagement factory, fueled by Nitro and Boosts and Orbs and whatever else they need to prop up their IPO. All while happily turning over your information to law enforcement because there is no real privacy there at all.
You don’t need Discord for plain text chat. IRC gets the job done just fine, costs less than a “server boost” to run, and puts you firmly in the driver’s seat (especially where privacy is concerned). And you also get to run a real server, not whatever it is that Discord considers a “server”, which is definitely not a server.
There are countless reasons to run an IRC server today, ranging from having a space for casual fun chat with friends to organizing communities or collaborating on massive projects. IRC is simple, lightweight, easy to use, and completely free and open technology.
Ready to take the leap? Let’s go!
About this guide
This guide assumes that you know how to use a terminal and enter commands. It doesn’t assume that you’re a sysadmin or genius, though!
Throughout the guide you’ll see various terminal commands, and I’ve marked which ones you can copy and paste directly and which ones you’ll need to edit first. I’ve tried to make everything as simple as possible, and I’ve even done some backflips to ensure that you don’t have to touch an editor to get up and running.
Server Setup
In this guide, you’ll set up a small (but mighty!) Ergo IRC server hosted with Hetzner. Hetzner is a European data center operator (based in Germany), and I’ve used them for years. Their service is extremely reliable and inexpensive. If you use this link, they’ll give you a €20 credit (and I’ll get €10 if you stick around with them, which is a really nice way to support me and this guide).
Once you have an account with Hetzner, go ahead and log in. You may be asked to create a “project”, which is a simple way to organize your servers. Once you see the red Create Resource button, go ahead and click on that, and then click on Servers.

Your IRC server will run happily (with plenty of resources to spare) on the least expensive cost-optimized server plan that Hetzner offers. Incidentally, those servers (the Arm64 Ampere models) happen to offer amazing performance at the price point. The monthly cost is less than a Discord “server boost”, meaning if you were already paying to boost a Discord server, you’ll already be coming out ahead with this setup. And you can run all kinds of other stuff on it, too, beyond just IRC.
Type
Go ahead and choose the Arm64 (Ampere®) option. The default server configuration name, CAX11, should be selected automatically. That’s the model that we’re going to use, and it’s more than enough power for your IRC server.

Location
Ampere servers are only available in Hetzner’s European datacenters, but I consider that to be more of an advantage than a problem. In case you haven’t been paying attention lately, you really don’t want to host anything in the USA at this point in time.
You can choose any of the locations shown. If you’re not sure what to choose, go with Falkenstein. (That’s what I usually do when I set up a new server.)

Image
The image is the operating system that you’ll install on your server. For this guide, we’re using Debian 13 (since that’s what I run for everything, including omg.lol).
You can choose a different image if you’d like, but there’s a good chance that this guide won’t work if you do. If you’re looking to follow along with a simple and guaranteed-to-work setup, stick with Debian 13.

Networking
By default, both Public IPv4 and Public IPv6 options will be selected. I’d suggest leaving that exactly as is. You can save a few cents by going IPv6 only, but you’ll likely severely limit the number of people who can connect to your IRC server, which kind of defeats the purpose.

SSH Keys
This guide assumes that you’ll use an SSH key for server authentication, because that’s really the only secure way to run a server. Using an SSH key is the only way to safeguard against password-based attacks and make yourself largely unphishable (because you’d never share your private key with anyone).
If you already have an SSH key, go ahead and add the public key to Hetzner by clicking the Add SSH key button. If you don’t have a key yet, you can follow this guide to set one up.
If you use 1Password, you can easily add a new SSH key to your vault, and obtain the public key from there. 1Password also has a really nice SSH agent feature that will handle authentication automatically within your OS. (This is what I use.)

Volumes
You won’t need a volume for your server, so you can leave this section alone.
Firewalls
You can also leave this section alone. You can choose to set up a firewall if you want to, but Debian’s built-in setup is sufficient for an IRC server, so feel free to skip this.
Backups
Server backups are always important, and Hetzner can take automatic nightly snapshot backups of your server if you enable backups here. They cost €0.66/month, which is a good deal for automated peace of mind. But it’s also possible for you to set up your own backup strategy (using rsync or similar tools) and skip this if you’d like. If you’re not sure what to do, I’d suggest enabling Hetzner’s backups.
Placement groups
There’s no need to worry about this setting, unless you have a bunch of servers that you want to distribute in a particular way. You can just skip this.
Labels
This is another section you can skip.
Cloud config
And you can skip this one too.
Name
The server name doesn’t really impact anything, but it’s nice to have a descriptive name. By default you’ll get something like debian-4gb-fsn1-1, which isn’t overly pretty. I usually use the full domain of whatever I’m hosting on the server, so I might use something like irc.example.net. Fill in the server name and click the red Create & Buy now button when you’re ready.
Connect to your new server
Once you’ve created the server, Hetzner will take you to your server list, with your brand new server right at the top. Within a moment or two you’ll see the Public IP address appear, and you’ll need that to connect to the server and to set up DNS.

Setting up DNS
This is a good time to pause and set up DNS for your server. While it’s possible to connect to an IRC server with an IP address alone, it’s not recommended because you’ll be limited to insecure traffic. Setting up a hostname will allow you to use a TLS certificate and will secure your traffic. (And this guide assumes that you’ll do that.)
For your DNS, you’ll need an A record pointing to the server’s public IP, and, optionally (but highly recommended), an AAAA record pointing to the server’s public IPv6 address. To get your IPv6 address, click on the server in the list, click on Networking, and then look for the IPv6 entry under the Public Network heading at the top. It should be the second row, beneath the IPv4 one, and it will end in ::/64. Click on that IPv6 address to copy it. Note that what you’re copying is actually the range of IPv6 addresses available to your server; when you set up DNS, you’ll want to replace the /64 with a number. I usually use the number 1. So, for example, 2a01:4f8:c010:6700::/64 becomes 2a01:4f8:c010:6700::1.

SSH into your new server
With the server provisioned and DNS set up, you’re now ready to connect to the server for the first time. You’ll do with this SSH, which allows us to securely connect and begin to configure the server in your terminal.
Pull up a terminal and type this:
ssh root@your-server-address
Be sure to change your-server-address to either the IP address of your server, or the hostname that you chose when setting up DNS. You may need to start with the IP address if the hostname hasn’t yet propagated across global DNS servers.
You’ll most likely encounter a message like this:
The authenticity of host '49.13.84.148 (49.13.84.148)' can't be established.
ED25519 key fingerprint is SHA256:3cvfw3S+0EOwl/kZlCqartcxhNcZJQEjynNKpUvaXsw.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
This is totally normal and you can type yes and press enter to continue. You’ll then see a warning about permanently adding the IP address the list of known hosts, which is fine and normal.
If everything is set up correctly with your SSH key, you should connect to the server right away (or if you’re using 1Password, you may be prompted to enter your vault password to continue with the key negotiation through its SSH agent). If you run into a problem here, you may need to review your SSH key configuration and make corrections before proceeding.
You’ll know that you’re logged into the server successfully when you see something like this:
Linux irc 6.12.57+deb13-arm64 #1 SMP Debian 6.12.57-1 (2025-11-05) aarch64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Feb 7 22:29:05 2026 from 10.0.0.42
root@irc:~#
Configuring your server
Now that you’re in, it’s time to start configuring the server. Before we get to the fun IRC stuff, you’ll first need to get some basic configuration in place to make the server run properly.
Update the OS
To ensure you’re running the latest OS, and to enable unattended upgrades, run these commands (you can copy and paste them all at once to run them sequentially, vs. one at a time):
OK to copy/paste!
apt -y update
apt -y upgrade
apt -y full-upgrade
DEBIAN_FRONTEND=noninteractive apt-get --yes --force-yes upgrade
DEBIAN_FRONTEND=noninteractive apt-get --yes --force-yes dist-upgrade
apt -y install unattended-upgrades
systemctl enable unattended-upgrades
systemctl start unattended-upgrades
You’ll see a bunch of stuff fly by in your terminal window. You shouldn’t need to worry about any of it, though. After several moments, you’ll return to a blank prompt and can continue.
Create your own user account
Using the root account is isn’t best practice, so next you’ll create a local user account on the server for yourself. This is the main account you’ll use with the server.
The command below will define your local account username. Be sure to change yourname to your desired username. For example, if you wanted to use the name pikachu, then you would run USERNAME=pikachu.
Change this first!
USERNAME=yourname
You won’t see any visible feedback after running this, but you can make sure that it worked by running this:
OK to copy/paste!
echo $USERNAME
If you see your desired username, then you’re good to proceed.
These next commands will add your local user account, give it sudo access (so that you can run commands as root), and makes it so that when you run sudo you’re not required to provide a password each time.
OK to copy/paste!
adduser --disabled-password --gecos "" $USERNAME
usermod -aG sudo $USERNAME
cat >> /etc/sudoers
Copy your SSH key to your new user account
Right now, the SSH public key is in the root user’s home directory. To use SSH key authentication with your new local user account, you’ll need to copy that over to your new home directory:
OK to copy/paste!
mkdir /home/$USERNAME/.ssh
cp /root/.ssh/* /home/$USERNAME/.ssh
chmod 700 /home/$USERNAME/.ssh
chmod 600 /home/$USERNAME/.ssh/*
chmod 640 /home/$USERNAME/.ssh/authorized_keys
chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh
Enhance server security
These next commands will disable password authentication on the server, limiting authentication to SSH keys only. This will make your server impervious to brute-force login attacks, since the only way to connect will be with the correct private SSH key. We’re also disabling the ability for the root account to log in externally (though you can still access that account from within the server itself, or Hetzner’s recovery console if needed).
OK to copy/paste!
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
cat >> /etc/ssh/sshd_config
Reboot and verify login
At this point, you can run this command to reboot the server:
OK to copy/paste!
reboot now
Your SSH connection will be dropped as the server begins to reboot. Rebooting should take less than two minutes (and often less than one). When you re-connect, use your new user account instead of root:
ssh yourname@your-server-address
If you land on a Linux prompt that starts with your new username, then you’re good to go.
Install “the stuff”
Now it’s time to install stuff! To make this IRC server do its job, we’re going to need two things:
- Caddy, a web server, which we’ll use to manage our certificates and handle
webirctraffic. - Ergo, an IRC server, which will do all of the IRC stuff.
Caddy
To install Caddy, run this command:
OK to copy/paste!
sudo apt install -y caddy
Now, we’ll configure Caddy so that it’s ready to use with IRC. First, let’s define the hostname for the IRC server. This would be whatever you set up with DNS above, e.g. irc.example.com.
Change this first!
HOSTNAME=irc.example.com
Change the hostname above to match your own hostname, and then enter the command in your terminal.
Then run these commands to complete the setup. They’ll ensure that Caddy is using your correct hostname, will only respond to HTTPS requests, and will proxy Web IRC traffic to Ergo’s websocket listener:
OK to copy/paste!
sudo sed -i "s/:80/$HOSTNAME/g" /etc/caddy/Caddyfile
sudo sed -i $'/^[[:space:]]*file_server[[:space:]]*$/a\\\n\\\n\thandle_path /webirc {\\\n\t\treverse_proxy 127.0.0.1:8067\\\n\t}' /etc/caddy/Caddyfile
sudo systemctl restart caddy
At this point, Caddy should be able to serve its default web page, which you’ll see if you visit the server’s hostname in your browser (same one you set up in DNS earlier). The first visit will take an extra second or two while Caddy automatically obtains a certificate for your site. If everything is working correctly, you’ll see Caddy’s default page.
Ergo
With Caddy installed and configured, we can move on to Ergo.
First, we’ll download Ergo:
OK to copy/paste!
wget https://github.com/ergochat/ergo/releases/download/v2.17.0/ergo-2.17.0-linux-arm64.tar.gz
tar -xzvf ergo-2.17.0-linux-arm64.tar.gz
rm ergo-2.17.0-linux-arm64.tar.gz
mv ergo-2.17.0-linux-arm64 ergo
Next, we’ll grab the yq utility, which will make it easy to update the Ergo configuration:
OK to copy/paste!
sudo apt install -y yq
You’ll need to choose a “network name” for your IRC server. If you plan to connect this server to other IRC servers on the same network, you’ll want to use that established network name. Otherwise, this can be whatever you’d like. Change the your-network-name value below to a valid hostname and run the command:
Change this first!
NETWORKNAME=your-network-name
Now we’re going to set the IRC Operator password. This password will let you authenticate as an IRC Operator on the server, giving you full permissions to manage it when connected.
When you run the command below, you’ll be prompted to enter a password, and then to confirm it. You’ll then see the hashed password that was generated, but you don’t need to do anything with that as we’ll add it to the Ergo configuration momentarily.
OK to copy/paste!
PASSWORD="$(ergo/ergo genpasswd | tee /dev/tty | tail -n 1)"
Next, we’ll configure Ergo with some solid defaults (and the password that you just set above):
OK to copy/paste!
cp ergo/default.yaml ergo/ircd.yaml
yq -Y --indentless --in-place '.["network"]["name"] = "'"$NETWORKNAME"'"' ergo/ircd.yaml
yq -Y --indentless --in-place '.["server"]["name"] = "'"$HOSTNAME"'"' ergo/ircd.yaml
yq -Y --indentless --in-place '.["server"]["listeners"][":6697"]["tls"]["cert"] = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/'"$HOSTNAME"'/'"$HOSTNAME"'.crt"' ergo/ircd.yaml
yq -Y --indentless --in-place '.["server"]["listeners"][":6697"]["tls"]["key"] = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/'"$HOSTNAME"'/'"$HOSTNAME"'.key"' ergo/ircd.yaml
yq -Y --indentless --in-place '.["server"]["listeners"][":8067"]["websocket"] = true' ergo/ircd.yaml
yq -Y --indentless --in-place '.["languages"]["path"] = "/home/'"$USER"'/ergo/languages"' ergo/ircd.yaml
yq -Y --indentless --in-place '.["opers"]["admin"]["password"] = "'"$PASSWORD"'"' ergo/ircd.yaml
Note that the yq utility removes comments from the configuration file
The yq utility that we used above is super convenient, but it has the drawback of stripping comments from the configuration file. But! You can still see all of the original comments in the default.yaml file in the ergo directory. (It’s one of the most thoroughly-commented configuration files I’ve ever seen.)
Creating an Ergo service
At this point, Ergo is configured and ready to run. But to keep things sane, you’ll want to turn it into a systemd service so you can manage it more easily and keep it running more reliably.
OK to copy/paste!
sudo sh -c "cat > /etc/systemd/system/ergo.service
At this point, Ergo is up and running, and you can connect to your server now using the client of your choice. If you ever want to see what’s going on with the Ergo process, you can take a look at its journal entries by running this:
OK to copy/paste!
sudo journalctl -u ergo -f
Installing Gamja, a simple web client
If you’d like to get a simple web client installed on your server, Gamja is a great choice.
sudo apt install -y git npm
git clone https://codeberg.org/emersion/gamja.git
cd gamja && npm install --omit=dev
echo "{ \"server\": { \"url\": \"wss://$HOSTNAME/webirc\", \"autojoin\": \"#chat\" } }" > config.json
sudo cp -r * /usr/share/caddy/
cd ~ && rm -rf gamja
Now if you visit your server’s hostname in your browser, instead of that default Caddy landing page, you’ll see Gamja’s simple connection screen, and you can use that as an IRC client.
You did it!
You now have live IRC server, that you fully control, running in a German datacenter. This is about as good as it gets these days!
This is the end of this guide, but there’s still plenty more to learn about IRC itself (which I could share in another guide if there’s enough interest). For now, though, I strongly suggest that you familiarize yourself with both the Ergo admin manual and user guide. There are many different ways to configure Ergo to achieve different kinds of setups, and you can spend time tuning things to make them work best for your own needs (or your the needs of your community/project).
I’ll leave you with these final tips:
Authenticate as an IRC Operator
Once you’ve connected to your IRC server, the first thing you should do is run this command:
Put your password here!
/oper admin your-password-here
You’ll want to swap your-password-here with the password that you set when configuring Ergo above. This will grant you full access to all IRC commands, which is important for being able to run the server effectively.
After entering the command, you should see a confirmation that you are now an IRC Operator.
Rehash the configuration
If you ever make changes to the Ergo configuration (located in ergo/ircd.yaml in your home directory), you’ll need to rehash the server to apply new configuration while the server is running. To do this, just run:
/rehash
You should see a confirmation message that the rehash is complete. You’ll want to do this any time you make updates to your ircd.yaml file.
Set the MOTD
The Message of the Day, or MOTD, is what people see when they connect to your IRC server. You can edit yours in the ergo/ergo.motd file in your home directory. You’ll need to rehash the server after making changes to the file.
Join a channel
To join a channel, type:
/join #chat
Now, have a friend connect to the server and join the same channel.
And have fun chatting with each other!
The end
If you enjoyed this guide, please consider supporting me with a fivedollars.lol tip, or by joining the omg.lol community (where we have our own awesome IRC server!).