IRC with The Lounge, Soju, Caddy, and Podman

I recently started using IRC again and decided to document my setup. The setup configuration should not be copied verbatim, since it makes some unconventional decisions (like not using top-level named volumes for podman-compose).

Variables

In the following sections, replace each variable with their actual value.

Name Example Description
IRC_CLIENT irc.example.com URL to access The Lounge
IRC_HOST irc.libera.chat URL of an IRC server The Lounge should connect to
IRC_PORT[1] 6667 External port that The Lounge connects to
CADDY_PORT[1] 6667 Internal port that Caddy listens on to forward to soju
SOJU_PORT[1] 6667 Internal port that soju listens on for connections
SOJU_USER bingus Username for soju (this will be an admin account)
SOJU_PASS hunter2 Password for $SOJU_USER
  1. All three ports can be the same number, I list them here to better illustrate where each port number sits in the configurations.

Soju

Directory Structure

.
├── compose.yaml
└── soju
    ├── config
    │   └── config.txt
    └── data

Files

    compose.yaml
services:
  soju:
    image: codeberg.org/emersion/soju
    restart: unless-stopped
    volumes:
      - ./soju/config/config.txt:/soju-config:ro
      - ./soju/data:/var/lib/soju:rw
    soju/config/config.txt
hostname      $IRC_URL

db            sqlite3 /var/lib/soju/main.db
message-store fs      /var/lib/soju/logs/

listen        unix+admin://
listen        irc+insecure://0.0.0.0:$SOJU_PORT
http-origin   $IRC_CLIENT

Setup


The Lounge

Directory Structure

.
├── compose.yaml
└── thelounge/

Files

    compose.yaml
services:
  thelounge:
    image: ghcr.io/thelounge/thelounge
    restart: unless-stopped
    volumes:
      - ./thelounge:/var/opt/thelounge:rw

Setup

  • Network Settings:

    Server Password
    $IRC_CLIENT : $IRC_PORT $SOJU_PASS
  • User Preferences:

    Username
    $SOJU_USER/$IRC_SERVER

Caddy

Directory Structure

.
├── compose.yaml
└── caddy
    ├── Caddyfile
    ├── Dockerfile
    ├── config/
    └── data/

Files

    compose.yaml
services:
  caddy:
    build: ./caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
      - "$IRC_PORT:$CADDY_PORT"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy/data:/data:rw
      - ./caddy/config:/config:rw
    caddy/Dockerfile
FROM docker.io/caddy:2.8-builder AS builder

RUN xcaddy build \
    --with github.com/mholt/caddy-l4

FROM docker.io/caddy:2.8

COPY --from=builder /usr/bin/caddy /usr/bin/caddy
    caddy/Caddyfile
{
    layer4 {
        :$CADDY_PORT {
            route {
                tls {
                    connection_policy {
                        alpn http/1.1 http/1.0
                        default_sni $IRC_CLIENT
                    }
                }
                proxy soju:$SOJU_PORT
            }
        }
    }
}

$IRC_CLIENT {
    reverse_proxy thelounge:9000
}

Conclusion

If you made it to the end, hope you get IRC configured just the way you want it! Feel free to hit me up if you have any questions!