Is a Lemmy instance the right fit?
Yes, if your group wants threaded discussions, voting and link sharing on a site you control, and wants to be part of a bigger network. Each Lemmy server, called an instance, hosts its own communities. Thanks to ActivityPub, the protocol that lets servers swap posts much as mail servers swap email, your members can also follow communities on other instances, and people elsewhere can join yours.
The flip side is that you become the admin. Your instance sets its own rules and enforces them; nobody upstream does it for you. If that sounds like more than your group wants to take on, joining an existing instance is the simpler path.
What your server will be doing
The official Docker setup starts six services side by side. You will rarely touch most of them, but it helps to know what each is for:
- lemmy, the backend: it answers the website and apps, and swaps activity with other instances.
- lemmy-ui, the website your members see.
- pictrs, which stores uploaded pictures and makes thumbnails for shared links.
- postgres, the database holding every post, comment, vote and account.
- proxy, a small nginx inside the stack that sends each request to the right service.
- postfix, which sends sign-up and password-reset email.
The Lemmy docs say the default Docker installation uses roughly 150 MB of memory, with negligible processor load. The parts that grow with your community are the database and the picture folder, so think about disk space first and give the database room to cache. The docs mention pgtune for tuning Postgres. One catch: the downloaded customPostgresql.conf is mounted into the database container but never actually loaded, so editing it has no effect by itself. Put your own pgtune results in it (the example is written for an 8 GB, 4-CPU server), then tell Postgres to read it: give the postgres service in docker-compose.yml a command: line that sets config_file to /etc/postgresql.conf, which is how Lemmy's Ansible setup does it. Its comments also ask that shared_buffers match the container's shared memory size, so increase the service's shm_size to suit (the downloaded compose file sets 1g). Thumbnails for linked pages are kept permanently by default, which steadily adds to storage.
The server that fits
A small community runs comfortably on one of our compact cartridge servers, and a growing one on a single-processor machine with its database beside it. Every option on our dedicated server page is a whole physical computer that runs your forum and nobody else's, and you log in as root. If you want to compare Linux setups, our Linux servers page lists the distributions you can install.
- No bandwidth bill. Nothing meters the port, so a post that gets shared across the fediverse does not change your invoice.
- A way back in. Our rack servers and blades, plus two cartridge models (m510 and m710x), give you a remote screen and power button that work even when the system will not boot, so a firewall mistake is not a lockout. Other cartridges give you the power button alone.
- Addresses for mail and federation. You get one IPv4 address with the server and IPv6 at no charge, plus reverse DNS you can set yourself, which helps your mail get delivered.
- Quick start, no lock-in. A ready server is handed over within 30 minutes of the payment being approved, and the term is month to month.
Up and running in an evening
Log in to a fresh Ubuntu server as root and follow these steps in order. The firewall goes on before anything starts listening, and IPv6 is switched on in it first so every rule covers both address families.
apt update && apt install -y docker.io docker-compose-v2 ufw nginx certbot python3-certbot-nginx
docker version
sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
ufw allow OpenSSH && ufw allow 80,443/tcp && ufw --force enable
mkdir -p /srv/lemmy && cd /srv/lemmy
wget https://raw.githubusercontent.com/LemmyNet/lemmy-docs/main/assets/docker-compose.yml
wget -O lemmy.hjson https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/examples/config.hjson
wget https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/templates/nginx_internal.conf
wget https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/files/proxy_params
wget https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/examples/customPostgresql.conf
mkdir -p volumes/pictrs && chown -R 991:991 volumes/pictrs
- Look at the Engine version under Server in what
docker versionprinted. It should be 28 or higher: from Docker Engine 28, a port published on 127.0.0.1 can only be reached from the server itself (moby#45610). If it is lower, stop here. Uninstall Ubuntu'sdocker.ioanddocker-compose-v2packages, set up the Engine from the apt repository that Docker runs itself, as its Ubuntu guide explains, and only then carry on. - Open
docker-compose.yml. Its placeholders are wrapped in double curly braces: swap the one nameddomainfor your forum's address and the ones namedpostgres_passwordfor one long random password. That password doubles as the picture service's key. - In the same file, find the line
"10633:8536"and make it"127.0.0.1:10633:8536". Without an address, Docker publishes the port on all of the server's addresses, IPv4 and IPv6, and its published traffic gets past ufw on IPv4 (the same goes for IPv6 if you have enabled IPv6 networking in Docker itself). - In
nginx_internal.conf, the resolver placeholder (nginx_internal_resolver) becomes127.0.0.11. - Fill in
lemmy.hjsonas shown in the next section, then lock both secret-holding files down, as described there. - Run
docker compose up -d. If something looks wrong,docker compose logs -f lemmyshows what the backend is saying.
Choosing who is in charge
You decide the first admin in the config file, not on the website. Lemmy reads the setup part of lemmy.hjson only the first time it starts and creates that account from it. Our own reasoning, not something the docs state: since the stack only listens on 127.0.0.1 at this point, nobody else can reach the site before your admin exists. The admin password needs 10 to 60 characters, and the site name can be up to 20.
{
hostname: "community.example.net"
database: { host: "postgres", password: "YOUR_LONG_PASSWORD" }
pictrs: { url: "http://pictrs:8080/", api_key: "YOUR_LONG_PASSWORD" }
email: {
smtp_server: "postfix:25"
smtp_from_address: "noreply@community.example.net"
tls_type: "none"
}
setup: {
admin_username: "founder"
admin_password: "choose 10 to 60 characters"
site_name: "Our Club Forum"
admin_email: "founder@example.net"
}
}
This file now holds three secrets, and docker-compose.yml holds the database password too, so neither should be readable by other accounts. Run chmod 600 docker-compose.yml. The Lemmy container reads its config as a non-root user, so ask the image for that user's number, give it the file, then tighten it: LEMMY_UID=$(docker compose run -T --rm --entrypoint id --no-deps lemmy -u), followed by chown "$LEMMY_UID" lemmy.hjson and chmod 600 lemmy.hjson.
When your forum is live, sign in and pick a new admin password under your settings. The docs also suggest you appoint another admin who can step in when you are away.
Opening the doors to the fediverse
Other instances only talk to you over HTTPS, so the next job is a certificate and the outside web server. Get the certificate with certbot certonly --nginx -d community.example.net. Then download the docs' nginx template, https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/templates/nginx.conf, to /etc/nginx/sites-available/lemmy with wget -O, fill in your domain wherever it asks (cache zone names take it with underscores instead of dots and hyphens), point proxy_pass at http://127.0.0.1:10633, create the folder /var/cache/lemmy, symlink the site into sites-enabled, and reload nginx once nginx -t is happy.
- Leave the Host header untouched. Lemmy signs what it sends, and the docs warn that a proxy changing signed headers breaks federation.
- Keep the server's clock right. Signed activities more than an hour off are thrown away.
- In the admin panel, make sure federation is on, then run
curl -sH 'Accept: application/activity+json' https://community.example.net/u/founder. You want JSON back, not a web page. - Search for a community on another instance by its full address and press Follow, so its new posts start arriving.
To check email, log out and ask for a password reset, as the docs suggest. If messages land in spam, send through a mail provider instead: in lemmy.hjson, point smtp_server at the provider, add your smtp_login with its smtp_password, and pick starttls or tls as the tls_type.
Keeping posts and pictures safe
You manage the server; we keep the hardware and the network running, so backups are yours to schedule. The docs name two things worth saving: a dump of the database and the picture folder. Create a private folder for them (mkdir -m 700 /var/backups/lemmy) and save these two lines as the file /etc/cron.d/lemmy-backup:
30 2 * * * root umask 077; cd /srv/lemmy && docker compose exec -T postgres pg_dumpall -c -U lemmy | gzip > /var/backups/lemmy/posts-$(date +\%F).sql.gz
0 3 * * * root umask 077; cd /srv/lemmy && docker compose stop pictrs && tar -C /srv/lemmy/volumes -czf /var/backups/lemmy/pictures-$(date +\%F).tar.gz pictrs; docker compose start pictrs
The second line pauses the picture service while it is archived: pict-rs stores its records in sled, and its own docs advise copying them with the service stopped. It restarts the moment the archive is written. Copy those files to another machine regularly and delete the oldest now and then. Try a restore once so you know it works, on a spare server or a freshly built stack rather than your live forum: start only the database container. If Lemmy itself has already run against that database, Lemmy's backup guide tells you to empty it before restoring: drop its public schema and create it again. Then unzip the dump into its psql as the lemmy user and bring everything else up.
Updating is mostly a matter of changing the version numbers on the images in docker-compose.yml, reading that release's announcement for anything extra, taking a fresh dump, and running docker compose pull followed by docker compose up -d. Pick your domain carefully at the start: the docs warn that changing it after you have federated breaks federation.
What being the admin asks of you
According to the Lemmy docs, admins are responsible for their whole instance, and every instance writes and enforces its own moderation rules, because Lemmy has no central team. In practice that means you, and anyone you appoint, own the content and the moderation on your server.
- Write your instance rules and put them in the sidebar.
- Watch the reports your members send with the flag icon, and act on them: remove, lock, ban, or purge an account with its uploads. Every action shows in the public mod log.
- Ask newcomers to apply before joining. The docs require registration applications from instances that want a place on the join-lemmy.org list, as a guard against bots and trolls.
- Block instances whose rules clash with yours, or federate only with a list you trust.
- Be ready for takedown requests, which the docs say usually reach the admin through the hosting provider or the domain registrar.
Nothing here is legal advice. Your obligations depend on where you and your members live, so for that question talk to a lawyer. Lemmy is licensed AGPL-3.0; if you modify it and run it for others over a network, its section 13 says those users must be offered your source.
Thinking of a fuller fediverse setup? Our guides cover a Matrix server for chat and Mastodon on your own server for microblogging.
Questions people ask
- Is a dedicated server overkill for a small Lemmy community?
- Not necessarily. The smallest cartridge servers are whole machines sized for one job, which is exactly what a small instance is. The benefit is that the database and pictures have the disks to themselves and the port is unmetered.
- Will my members see posts from other Lemmy servers straight away?
- No. A new instance starts empty. Once someone on your server follows a community elsewhere, its new posts are pushed to you; older posts and comments can be pulled in by searching for their address.
- Can people on other fediverse platforms join in?
- Lemmy speaks ActivityPub, and its docs say content can be fetched from other platforms built around communities, such as Piefed or Mbin. Others may work if they use communities in the same way.
- Who is liable for what members post?
- The docs make the admin responsible for the instance and its moderation. What the law adds depends on your country and your members'. We cannot give legal advice, so ask a lawyer.