J'ai passé des années à compiler des serveurs IRC à la main. Télécharger les sources, résoudre les dépendances, ajuster le ./configure, croiser les doigts pendant le make. Quand Docker est arrivé, j'ai d'abord résisté — un conteneur pour un daemon réseau, ça semblait excessif. Puis j'ai eu besoin de déployer trois instances d'InspIRCd sur le même serveur pour un client, et j'ai compris l'intérêt. Depuis, tous mes déploiements IRC passent par des conteneurs. Voici comment faire proprement.
Pourquoi conteneuriser un serveur IRC
Un serveur IRC est un programme réseau qui écoute sur des ports, maintient des connexions persistantes, et stocke son état en mémoire. En soi, il n'a pas besoin de Docker pour fonctionner. Mais Docker résout plusieurs problèmes récurrents dans l'administration d'un ircd.
Le premier, c'est l'isolation. Si vous hébergez un serveur IRC sur une machine qui fait aussi serveur web, DNS, et mail, un crash de l'ircd ou une faille de sécurité reste confinée dans le conteneur. Le second, c'est la reproductibilité : votre Dockerfile est la documentation de votre déploiement. Le troisième, c'est la portabilité — vous pouvez déplacer votre serveur IRC d'un hébergeur à un autre en copiant quelques fichiers.
Pour les entreprises qui gèrent leur infrastructure IRC en interne, et je pense notamment aux équipes techniques qui utilisent encore IRC pour le ChatOps, la conteneurisation simplifie aussi le processus de mise à jour. Si vous faites appel à un prestataire comme PowerITi pour gérer votre infrastructure, le déploiement conteneurisé facilite la maintenance et le monitoring.
Construire une image de base
Prenons InspIRCd comme exemple. C'est un serveur IRC modulaire, bien documenté, et qui se compile facilement. Voici un Dockerfile fonctionnel :
FROM debian:bookworm-slim AS builder
RUN apt-get update && apt-get install -y \
build-essential \
git \
pkg-config \
libssl-dev \
libgnutls28-dev \
libmysqlclient-dev \
perl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /src
RUN git clone --depth 1 --branch v3.17.0 \
https://github.com/inspircd/inspircd.git .
RUN ./configure --prefix=/opt/inspircd \
--enable-extras=m_ssl_openssl \
&& make -j$(nproc) \
&& make install
# Image finale légère
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y \
libssl3 \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN useradd -r -s /usr/sbin/nologin ircd
COPY --from=builder /opt/inspircd /opt/inspircd
RUN chown -R ircd:ircd /opt/inspircd
USER ircd
WORKDIR /opt/inspircd
EXPOSE 6667 6697
CMD ["/opt/inspircd/bin/inspircd", "--nofork"]
Quelques points à noter. Le multi-stage build sépare la compilation de l'exécution : l'image finale ne contient ni compilateur ni headers, ce qui réduit sa taille et sa surface d'attaque. Le --nofork est indispensable — Docker attend que le processus principal reste au premier plan. Un daemon qui fork en arrière-plan fera croire à Docker que le conteneur s'est arrêté.
ghcr.io/ergochat/ergo est prête à l'emploi et maintenue par les développeurs. Sauf besoin spécifique de compilation, utilisez-la directement plutôt que de construire votre propre image.docker-compose : l'assemblage complet
Un docker-compose.yml permet de décrire l'ensemble de votre stack IRC dans un seul fichier. Serveur, TLS, volumes, réseau — tout est déclaratif.
version: "3.8"
services:
ircd:
build:
context: .
dockerfile: Dockerfile
container_name: inspircd
restart: unless-stopped
ports:
- "6667:6667" # Plaintext (désactivez en production)
- "6697:6697" # TLS
volumes:
- ./conf:/opt/inspircd/conf:ro
- ./data:/opt/inspircd/data
- ./logs:/opt/inspircd/logs
- ./certs:/opt/inspircd/certs:ro
networks:
- ircnet
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
healthcheck:
test: ["CMD-SHELL", "echo PING | nc -w 3 localhost 6667 || exit 1"]
interval: 30s
timeout: 10s
retries: 3
networks:
ircnet:
driver: bridge
La configuration du serveur IRC est montée en lecture seule (:ro) pour éviter qu'un bug ou une faille ne modifie la config à chaud. Les logs et les données (base de channels, etc.) sont dans des volumes séparés pour la persistance. Le healthcheck vérifie que le serveur répond aux connexions TCP.
Le restart: unless-stopped assure que le conteneur redémarre automatiquement après un crash ou un reboot du serveur, sauf si vous l'avez arrêté manuellement. En production, c'est le comportement souhaité.
TLS et certificats
Un serveur IRC en 2025 sans TLS, c'est comme un site web sans HTTPS — techniquement possible, mais irresponsable. Voici comment intégrer Let's Encrypt avec votre conteneur IRC.
# Obtenir le certificat (sur l'hôte, pas dans le conteneur)
sudo certbot certonly --standalone -d irc.votredomaine.com
# Copier les certificats dans le dossier monté
sudo cp /etc/letsencrypt/live/irc.votredomaine.com/fullchain.pem ./certs/
sudo cp /etc/letsencrypt/live/irc.votredomaine.com/privkey.pem ./certs/
sudo chown 1000:1000 ./certs/*.pem
sudo chmod 600 ./certs/privkey.pem
Dans la configuration InspIRCd :
<openssl certfile="/opt/inspircd/certs/fullchain.pem"
keyfile="/opt/inspircd/certs/privkey.pem"
dhbits="2048">
<bind address="" port="6697" type="clients" ssl="openssl">
certbot renew puis docker restart inspircd est le minimum viable. Sans cela, vos utilisateurs verront des erreurs TLS tous les trois mois.Pour le renouvellement automatisé :
#!/bin/bash
# /usr/local/bin/renew-irc-cert.sh
certbot renew --quiet
DOMAIN="irc.votredomaine.com"
CERT_DIR="/etc/letsencrypt/live/$DOMAIN"
IRC_CERTS="/opt/irc-docker/certs"
cp "$CERT_DIR/fullchain.pem" "$IRC_CERTS/"
cp "$CERT_DIR/privkey.pem" "$IRC_CERTS/"
chown 1000:1000 "$IRC_CERTS"/*.pem
chmod 600 "$IRC_CERTS/privkey.pem"
docker restart inspircd
Volumes et persistance
Un serveur IRC stocke plusieurs types de données qu'il faut persister entre les redémarrages du conteneur :
# Structure des volumes recommandée
./irc-server/
├── conf/ # Configuration (montée en :ro)
│ ├── inspircd.conf
│ ├── modules.conf
│ └── opers.conf
├── certs/ # Certificats TLS (montés en :ro)
│ ├── fullchain.pem
│ └── privkey.pem
├── data/ # Données persistantes
│ ├── xline.db # Bans réseau (K-lines, G-lines)
│ └── permchannels.conf # Channels permanents
├── logs/ # Logs
│ └── startup.log
└── docker-compose.yml
La séparation entre configuration (lecture seule) et données (lecture-écriture) est volontaire. Si vous versionnez votre déploiement avec Git — et vous devriez — seuls conf/ et docker-compose.yml vont dans le dépôt. Les données et les certificats restent hors du contrôle de version.
Pour les backups, un simple tar du dossier data/ suffit. Les serveurs IRC ne génèrent pas de volumes de données importants — même un serveur actif ne produit que quelques Ko de données persistantes.
Alternative : Podman sans daemon
Si vous n'aimez pas l'idée d'un daemon Docker tournant en root sur votre serveur, Podman est une alternative directe. Compatible avec les mêmes Dockerfile et docker-compose.yml (via podman-compose), Podman tourne en rootless par défaut.
# Installation sur Debian/Ubuntu
sudo apt install podman podman-compose
# Build et lancement (même syntaxe que Docker)
podman build -t inspircd .
podman-compose up -d
# Vérification
podman ps
podman logs inspircd
# Génération d'un fichier systemd pour la persistance
podman generate systemd --name inspircd --files
mv container-inspircd.service ~/.config/systemd/user/
systemctl --user enable container-inspircd.service
systemctl --user start container-inspircd.service
loginctl enable-linger $USER
Le loginctl enable-linger est la ligne que tout le monde oublie. Sans elle, vos conteneurs Podman s'arrêtent quand vous vous déconnectez de la session SSH. Avec le linger activé, les services utilisateur persistent même sans session active.
Podman offre un avantage de sécurité réel : pas de daemon root, pas de socket Docker exposé. Pour un serveur IRC qui accepte des connexions du monde entier, cette surface d'attaque réduite n'est pas négligeable.
Mise en production
Quelques recommandations tirées de mon expérience avec des serveurs IRC en production :
# Monitoring : vérifier que le port répond
# Ajoutez ceci à votre supervision (Nagios, Zabbix, etc.)
check_command = check_tcp -H irc.votredomaine.com -p 6697 --ssl
# Logs : rotation automatique
# Dans docker-compose.yml, ajoutez sous le service :
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# Firewall : n'exposez que les ports nécessaires
sudo ufw allow 6697/tcp comment "IRC TLS"
sudo ufw deny 6667/tcp comment "IRC plaintext bloqué"
En production, désactivez le port 6667 (plaintext). Tout le trafic doit passer par le 6697 (TLS). Si des utilisateurs se plaignent de ne pas pouvoir se connecter sans TLS, expliquez-leur que c'est 2025 et que leur client supporte le TLS depuis au moins dix ans.
La limite mémoire de 512 Mo dans le docker-compose.yml est suffisante pour un serveur de quelques centaines d'utilisateurs. Un serveur IRC consomme environ 1 Mo de RAM par centaine de connexions. Ajustez selon votre usage, mais ne supprimez pas la limite — un serveur IRC sous attaque peut consommer de la mémoire de façon incontrôlée.
Pour les structures qui externalisent la gestion de leurs serveurs, le déploiement conteneurisé est un atout : le prestataire peut reproduire l'environnement exact sur n'importe quelle machine. C'est le type d'infrastructure standardisée que des sociétés comme PowerITi peuvent déployer et superviser sans documentation spécifique à chaque client.
Questions fréquentes
Docker ajoute-t-il de la latence aux connexions IRC ?
La surcharge réseau de Docker est négligeable — de l'ordre de quelques microsecondes par paquet. En mode host network, elle est nulle. Pour IRC, où la latence se mesure en millisecondes, Docker n'a aucun impact perceptible sur l'expérience utilisateur.
Peut-on linker deux serveurs IRC conteneurisés ?
Oui. Créez un réseau Docker dédié entre les conteneurs ou utilisez les ports exposés. La configuration du link IRC se fait dans les fichiers de configuration du serveur, pas dans Docker. Assurez-vous que les deux conteneurs peuvent se résoudre mutuellement par nom d'hôte.
Faut-il utiliser Docker ou Podman pour un serveur IRC ?
Si vous avez déjà Docker en place et que la sécurité du daemon root ne vous préoccupe pas, restez sur Docker. Si vous partez de zéro ou si vous préférez une approche rootless, Podman est un choix solide. Les deux sont fonctionnellement équivalents pour ce cas d'usage.