← All articles
red and white 8 logo

Lemmy: Run Your Own Federated Reddit-Like Forum

Social 2026-03-04 · 3 min read lemmy fediverse activitypub self-hosted reddit alternative community forum
By Selfhosted Guides Editorial TeamSelf-hosting practitioners covering open source software, home lab infrastructure, and data sovereignty.

Reddit's API changes in 2023 drove millions of users to look for alternatives. Lemmy is the main self-hosted option: a link aggregator and discussion platform that looks and works like Reddit but runs on the open ActivityPub protocol, which means instances can federate with each other (and with Mastodon, Pleroma, and other Fediverse services).

Photo by Brett Jordan on Unsplash

You can run a private Lemmy instance for your team or community, or join the federated network and participate in communities across thousands of other instances.

How Lemmy's Federation Works

Each Lemmy instance is independent but can talk to other instances:

This means you don't need to run a large instance to have access to content. A small single-user or community instance can still subscribe to communities from major instances like lemmy.world, programming.dev, or beehaw.org.

Installation with Docker Compose

Lemmy requires a few moving parts: the main application, a WebSocket server, a Postgres database, and Pict-RS for image handling.

services:
  lemmy:
    image: dessalines/lemmy:0.19.5
    hostname: lemmy
    restart: always
    environment:
      - RUST_LOG="warn,lemmy_server=info,lemmy_api=info,lemmy_db_schema=info"
    volumes:
      - ./lemmy.hjson:/config/config.hjson:ro
    depends_on:
      - postgres
      - pictrs

  lemmy-ui:
    image: dessalines/lemmy-ui:0.19.5
    hostname: lemmy-ui
    restart: always
    environment:
      - LEMMY_UI_LEMMY_INTERNAL_HOST=lemmy:8536
      - LEMMY_UI_LEMMY_EXTERNAL_HOST=lemmy.yourdomain.com
      - LEMMY_UI_HTTPS=true
    depends_on:
      - lemmy

  postgres:
    image: postgres:16-alpine
    hostname: postgres
    restart: always
    environment:
      - POSTGRES_USER=lemmy
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=lemmy
    volumes:
      - ./volumes/postgres:/var/lib/postgresql/data

  pictrs:
    image: asonix/pictrs:0.5.16
    hostname: pictrs
    restart: always
    environment:
      - PICTRS_OPENTELEMETRY_URL=http://otel:4137
      - PICTRS__SERVER__API_KEY=a-secret-key
    volumes:
      - ./volumes/pictrs:/mnt

lemmy.hjson (main config):

{
  hostname: "lemmy.yourdomain.com"
  database: {
    uri: "postgresql://lemmy:password@postgres/lemmy"
  }
  pictrs: {
    url: "http://pictrs:8080/"
    api_key: "a-secret-key"
  }
  email: {
    smtp_server: "mail.yourdomain.com:587"
    smtp_login: "[email protected]"
    smtp_password: "yourpassword"
    smtp_from_address: "[email protected]"
    tls_type: "starttls"
  }
  setup: {
    admin_username: "admin"
    admin_password: "a-strong-password"
    admin_email: "[email protected]"
    site_name: "My Lemmy Instance"
  }
}

Reverse Proxy

Lemmy needs specific proxy configuration because it serves both a browser app (the UI) and an API/federation endpoint, distinguishing them by Accept header.

Nginx:

upstream lemmy {
    server localhost:8536;
}
upstream lemmy-ui {
    server localhost:1234;
}

server {
    listen 443 ssl;
    server_name lemmy.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/lemmy.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lemmy.yourdomain.com/privkey.pem;

    set $proxpass "http://lemmy-ui";
    if ($http_accept = "application/activity+json") {
        set $proxpass "http://lemmy";
    }
    if ($http_accept = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") {
        set $proxpass "http://lemmy";
    }
    if ($request_method = POST) {
        set $proxpass "http://lemmy";
    }

    location / {
        proxy_pass $proxpass;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /api {
        proxy_pass http://lemmy;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Caddy (simpler approach):

lemmy.yourdomain.com {
    @lemmy_api path /api/* /pictrs/* /feeds/* /.well-known/*
    @lemmy_api method POST
    @lemmy_api header Accept application/activity+json

    handle @lemmy_api {
        reverse_proxy lemmy:8536
    }

    handle {
        reverse_proxy lemmy-ui:1234
    }
}

First-Time Setup

On first launch, Lemmy creates the admin account using the credentials in lemmy.hjson. Log in at your domain to complete setup.

Key admin settings to configure:

To enable federation, you must set it in lemmy.hjson:

federation: {
    enabled: true
    allowed_instances: []  # empty = allow all
    blocked_instances: ["blockedinstance.com"]
}

Creating Your First Community

After logging in as admin, create a community (c/your-community). Set:

Joining Other Communities

From your instance, search for communities on other instances:

[email protected]     # search for the linux community on lemmy.world
[email protected]
[email protected]

Your instance will subscribe and federate posts from that community.

Use Cases

Private team forum: Close registration, create topic communities (announcements, help, general), replace Slack threads for async discussions with a searchable archive.

Community site: Run a niche community for a specific interest with full control over moderation and federation policies.

Personal instance: A single-user instance lets you participate in the Fediverse with your own domain identity, without depending on any specific provider.

Resources

Get free weekly tips in your inbox. Subscribe to Self-Hosted Weekly