User Tools

This is an old revision of the document!


Lemmy

Lemmy Lemmy is the Fediverse response to the reddit like social media, but of course, federated. What't not to like? And isn't it the best opportunity to self-host for your personal use and have your own Lemmy instance?

Luckly, it's pretty easy to self-host and it seems not to require many resources, so far.

Note: Lemmy requires a dedicated subdomain that cannot be changed afterward, because that is the unique identifier of your instance.

Installation

I suggest you follow this guide, which was my base, taking into consideration my following notes and detailed steps.

First of all, create the usual dedicated user. You alsoi need to create the data folder where all data needs to be located. As usual in my setup, the daemon folder will be /data/daemons/lemmy and the data folder will be /data/lemmy:

useradd -d /data/daemons/lemmy -m lemmy
mkdir /data/lemmy
mkdir /data/lemmy/pictr
chown lemmy:lemmy /data/lemmy -R
chmod o+w /data/lemmy/pictr  

The /data/lemmy/pictr folder needs to exist but needs also be writable by others at this time because it will be populated by a subuid linked to the lemmy user, you can then change it's ownership and permissions after the first usccessfull start with the following commands as root:

cd /data/lemmy
ls -l pictrs
# Now grab the UID and GID of the files inside the pictrs folder and use them for the following command:
chown UID:GIR -R pictrs
chmod o-w pictrs -R

There are five files that you need to edit, download the raw ones:

su - lemmy
wget https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/examples/config.hjson -O /data/lemmy/lemmy.hjson
wget https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/templates/nginx_internal.conf -O /data/lemmy/nginx_internal.conf
wget https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/files/proxy_params -O /data/lemmy/proxy_params
wget https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/examples/customPostgresql.conf -O /data/lemmy/customPostgresql.conf
wget https://raw.githubusercontent.com/LemmyNet/lemmy-docs/main/assets/docker-compose.yml

Please pay attention that you moved the files to /data/lemmy and not in the same folder of the docker-compose.yml file (this is different from the above linked guide).

Here are some notes on editing them, start with the guide linked above, then follow my notes.

lemmy.hjson

This contains critical setup for your Lemmy instance:

lemmy.hjson
{
  database: {
    host: postgres
    password: "<< here your custom database password >>"
  }
  hostname: "lemmy.mydomain.com" # DO NOT put "https://" here!
  pictrs: {
    url: "http://pictrs:8080/"
    api_key: "<< here your custom database password >>"
  }
  email: {
    smtp_server: "postfix:25"
    smtp_from_address: "noreply@lemmy.mydomain.eu" 
    tls_type: "none"
  }
}

You could edit the email section and enable your own email server, if you have one, to get a better chance of your lemmy emails to reach users.

nginx_internal.conf

This is the Lemmy internal NGINX web server setup. You need this even if you will be slapping an additional NGINX reverse proxy in front of it.

There is only one line to edit here, which is the internal resolver address:

    resolver  10.89.0.1 valid=5s;

This is important, because this internal NGINX will need to resolve the other containers by name, and this can be achieved by enabling Podman internal name resolutions for the lemmy-net. Podman internal name resolution is disabled by default and need to be enabled in the docker-compose.yml like this:

networks:
  lemmy-net:
    dns_enabled: true 

Differently from docker, in podman the internal resolver address is 10.89.0.1.

proxy_params

This file doesn't need to be modified.

customPostgresql.conf

This file contains specific PostgreSQL setup to fine-tune the database to your hardware capabilties. Go to this page to generate it's content based on your server specs. I suggest you downplay a bit your specs when you input them in the page. This will create a more conservative configuration, to play better with other shared services on your server.

Yes, in other words, you can discard the content of the original downloaded file and replace it with the one generated by the page linked in this paragraph.

docker-compose.yml

This is the most critical file. The following is derived from the one linked above, but i have done a few podman specific editings, noted below:

docker-compose.yml
x-logging: &default-logging
  driver: "json-file"
  options:
    max-size: "50m"
    max-file: "4"

services:
  proxy:
    image: nginx:1-alpine
    ports:
      - "10633:8536"  # Choose an available port on your server!
    volumes:
      - /data/lemmy/nginx_internal.conf:/etc/nginx/nginx.conf:ro,Z
      - /data/lemmy/proxy_params:/etc/nginx/proxy_params:ro,Z
    restart: always
    logging: *default-logging
    networks:
      - lemmy-net
    
  lemmy:
    image: dessalines/lemmy:0.19.8
    hostname: lemmy
    restart: always
    logging: *default-logging
    environment:
      - RUST_LOG="warn"
    volumes:
      - /data/lemmy/lemmy.hjson:/config/config.hjson:Z
    depends_on:
      - postgres
    networks:
      - lemmy-net
    
  lemmy-ui:
    image: dessalines/lemmy-ui:0.19.8
    environment:
      - LEMMY_UI_LEMMY_INTERNAL_HOST=lemmy:8536
      - LEMMY_UI_LEMMY_EXTERNAL_HOST=lemmy.ml
      - LEMMY_UI_HTTPS=true
    volumes:
      - /data/lemmy/lemmy-ui/extra_themes:/app/extra_themes
    restart: always
    logging: *default-logging
    networks:
      - lemmy-net

  pictrs:
    image: asonix/pictrs:0.5.16
    hostname: pictrs
    environment:
      - PICTRS_OPENTELEMETRY_URL=http://otel:4137
      - PICTRS__SERVER__API_KEY=<< here your lemmy postgres password >>
      - RUST_BACKTRACE=full
      - PICTRS__MEDIA__VIDEO__VIDEO_CODEC=vp9
      - PICTRS__MEDIA__ANIMATION__MAX_WIDTH=256
      - PICTRS__MEDIA__ANIMATION__MAX_HEIGHT=256
      - PICTRS__MEDIA__ANIMATION__MAX_FRAME_COUNT=400
    user: 991:991 # This 991 will be used to define the UID:GID you need to set ownership of the folder to, as stated above...
    volumes:
      - /data/lemmy/pictrs:/mnt:Z # this is the folder of which you need to set ownership. This folder must exist before first launch
    restart: always
    logging: *default-logging
    networks:
      - lemmy-net

  postgres:
    image: pgautoupgrade/pgautoupgrade:17-alpine
    hostname: postgres
    environment:
      - POSTGRES_USER=lemmy
      - POSTGRES_PASSWORD=<< here your lemmy postgres password >> # the same as in the lemmy hjson above
      - POSTGRES_DB=lemmy
    shm_size: 1g
    volumes:
      - /data/lemmy/postgres:/var/lib/postgresql/data:Z
      - /data/lemmy/customPostgresql.conf:/etc/postgresql.conf
    restart: always
    logging: *default-logging
    networks:
      - lemmy-net

  postfix:
    image: mwader/postfix-relay
    environment:
      - POSTFIX_myhostname="lemmy.mydomain.com" # DO NOT put the "https://" here
    restart: "always"
    logging: *default-logging
    networks:
      - lemmy-net

networks:
  lemmy-net:
    dns_enabled: true # this is very important for the internal proxy

Please also note that the depends lines have been changed a bit from the docker original example, maybe due to some podman differences.

Note: first startup might fail because the postgress image takes too long to create the daabase and the lemmy image fails. In this case, just wait until it's done, stop it and restart it.

Now pull the images:

podman compose pull

Reverse Proxy

Lemmy not only must have it's own (sub-)domain, but that also identifies your instance. This means that you need to carefully plan the domain name and/or subdomain because you will not be able to change it afterward.

I assume it will be reachable as https://lemmy.mydomain.com.

Following this page create a NGINX config file called /etc/nginx/com.mydomain/lemmy/lemmy.conf like this:

lemmy.mydomain.conf
server {
    listen 443 ssl;
    listen 8443 ssl;
    http2 on;

    server_name lemmy.mydomain.com;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets on;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Hide nginx version
    server_tokens off;

    # Upload limit, relevant for pictrs
    client_max_body_size 20M;

    # Enable compression for JS/CSS/HTML bundle, for improved client load times.
    # It might be nice to compress JSON, but leaving that out to protect against potential
    # compression+encryption information leak attacks like BREACH.
    gzip on;
    gzip_types text/css application/javascript image/svg+xml;
    gzip_vary on;

    # Various content security headers
    add_header Referrer-Policy "same-origin";
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "DENY";
    add_header X-XSS-Protection "1; mode=block";

    location / {
      proxy_pass http://127.0.0.1:10633;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      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_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
      proxy_no_cache $cookie_jwt $http_authorization;
      proxy_cache_bypass $cookie_jwt $http_authorization;
  }
}

Autostart

To start it, and set it up on boot, as usual follow my indications Using Containers on Gentoo, so link the user-containers init script:

ln -s /etc/init.d/user-containers /etc/init.d/user-containers.lemmy

and create the following config file:

/etc/conf.d/user-containers.lemmy
USER=lemmy
DESCRIPTION="Decentralized forum"

Add the service to the default runlevel and start it now:

rc-update add user-containers.lemmy default
rc-service user-containers.lemmy start

Usage Notes

A few notes and hints i learned after setting everything up and running.

  • Federation takes hours. Expect at least half day / one day for your new instance to propagate the fediverse and start being picked up by other lemmy instances. At least a few hours. Manually forcing specified instances by searching for communities on them will speed this up a bit, but not too much.
  • Registering new users will just popup a notification in your admin panel, you will need to go there and accept them. At first i was expecting an email in my inbox (a real email), but i doesnt happen. At the same time, i strongly suggest you don't allow open registrations for legal issues and such.
  • You might want to head to fediseer.com to register your instance. Just type your instance name and admin name, and you will receive an API key in your inbox. Place the key back into the website and your instance will be stored. You can then ask for a guarantee from other instances and provide your own to others.

This website uses technical cookies only. No information is shared with anybody or used in any way but provide the website in your browser.

More information