Policy Walkthrough: Building Lemmy From Source on Bare-Metal Linux

Operating a federated discussion platform without container runtimes requires clear operating procedures. When running Lemmy directly on Linux host infrastructure—such as an LXC container where container engines like Docker cannot be deployed—system administrators must compile the software directly from source code. This administrative policy walkthrough defines the exact environment standards, toolchain controls, file hierarchies, and daemon isolation practices required to compile and maintain a bare-metal Lemmy installation.
Host Operating System and Database Prerequisites
Production server baselines for this deployment procedure apply specifically to Ubuntu 20.04 and Ubuntu 22.04 distributions. Because Lemmy requires modern relational storage capabilities, the database tier must be standardized before building the application:
- Database Engine Standard: The default repository for Ubuntu 20.04 provides PostgreSQL version 12, which is not supported by Lemmy. Systems must configure the official PostgreSQL repository to install PostgreSQL version 16.
- Access Control Authentication: Administrative policy dictates modifying
pg_hba.confto mandate MD5 password authentication instead of peer authentication for local database connections by adding the directivelocal lemmy lemmy md5. - Credential Provisioning: Administrators must provision a dedicated
lemmyuser and database, replacing the default placeholder with a unique database password. For upgrades or migrations from older versions, executing an administrative alter statement granting superuser status to the user may be required. - Base Tooling: The host system must install foundational build and transport tools, including
wget,ca-certificates,pkg-config,gcc,libssl-dev, andlibpq-dev. Installingprotobuf-compilermay also be required on Ubuntu 20.04 or 22.04 hosts.
Reviewing our forum software server requirements guide provides broader context on managing database dependencies across community platforms.
Rust Toolchain Isolation and Source Compilation
To preserve operational integrity and adhere to the principle of least privilege, compilation of the Rust codebase must never execute under an administrative root account. As detailed in the official Lemmy Install from Scratch guide, administrators must provision a non-privileged Linux user to manage the Rust toolchain via Rustup.
The compilation procedure requires the following controlled sequence:
- Download and initialize the Rust toolchain under the unprivileged user account, isolating cargo and toolchain components within that user's home folder.
- Clone the primary codebase repository from GitHub into a local build workspace.
- Check out the designated production release tag, such as version 0.18.5, and initialize and update all git submodules.
- Execute
cargo build --releaseto produce the release binary. On a quad core VPS, compiling release 0.18.5 takes around 7 minutes.
Filesystem Hierarchy and Asset Management Standards
System architecture standards mandate consolidating backend, frontend, and asset storage components within the /opt directory tree. System staff must establish a dedicated system user account using adduser lemmy --system --disabled-login --no-create-home --group to own runtime services.
Directory allocation must strictly follow this physical hierarchy:
/opt/lemmy/lemmy-serverfor the primary server binary andlemmy.hjsonconfiguration./opt/lemmy/lemmy-uifor the user interface codebase and scripts./opt/lemmy/pictrsalongside subdirectoriesfiles,sled-repo, andold. Establishing these specific pictrs storage paths is mandatory, as creating these directories is not optional under the system standard.
File ownership across the entire /opt/lemmy tree must be assigned strictly to the lemmy:lemmy system identity. Image hosting integration via pict-rs requires the magick command from ImageMagick version 7. Because Ubuntu 20.04 only includes ImageMagick 6, the binary must be provisioned manually with permissions set to 755, or installed via the imei.sh script. On standard LXC instances, AppImage installations fail because FUSE triggers permission denied errors during image uploads.
Systemd Service Sandboxing and Daemon Control
Direct host execution requires managing server processes through systemd unit files rather than foreground terminal sessions. In accordance with the Lemmy Install from Scratch documentation, the backend process runs via /etc/systemd/system/lemmy.service.
The configuration specifies execution parameters including WorkingDirectory=/opt/lemmy and configuration variables pointing to /opt/lemmy/lemmy-server/lemmy.hjson and PICTRS_ADDR=127.0.0.1:8080. Host sandboxing directives enforce hardened process boundaries:
ProtectSystem=yes(andProtectSystem=fullfor the UI daemon) to prevent processes from modifying protected operating system directories.PrivateTmp=trueto restrict shared temporary folder exposure.NoNewPrivileges=trueto block privilege escalation attempts.MemoryDenyWriteExecute=trueapplied to the Rust server to block executable memory allocation.
Health checks can be validated directly on localhost. Successful launch emits a log verifying the HTTP server started at 127.0.0.1:8536. An administrative call to curl localhost:8536/api/v3/site confirms backend status, while curl 127.0.0.1:8080 verifies pict-rs responsiveness.
Web UI Compilation and Frontend Daemon Setup
The web presentation interface requires Node 20 and pnpm. Because default operating system packages in Ubuntu 20.04 and 22.04 are outdated, administrators must configure the NodeSource distribution repository to install Node 20 and globally install pnpm.
Frontend compilation occurs within /opt/lemmy/lemmy-ui under the unprivileged system account: checking out release 0.18.5, pulling submodules, executing pnpm i, and building distribution assets via pnpm build:prod. A dedicated systemd unit (lemmy-ui.service) coordinates the Node service at dist/js/server.js, linking internally to backend port 8536 and serving traffic on internal port 1234. Running curl -I localhost:1234 must return an HTTP 200 OK header before opening ingress ports.
For more architectural perspectives on federated board structures, explore our Lemmy platform overview.
Ingress Routing, Cryptographic Headers, and Rate Control
Public access must terminate at an Nginx reverse proxy secured by automated certificates issued through Certbot. Reverse proxy policy requires daily cron renewals using @daily certbot certonly --nginx --cert-name example.com -d example.com --deploy-hook 'nginx -s reload'.
The edge configuration enforces strict network protections:
- TLS Protocols: Connections are constrained to TLSv1.2 and TLSv1.3 protocols, utilizing modern ECDHE cipher suites, session timeouts of 10m, and session cache allocations of 10m.
- Security Headers: Responses mandate Strict-Transport-Security configured with
max-age=63072000to enforce HTTPS for two years, alongsideReferrer-Policy "same-origin",X-Content-Type-Options "nosniff",X-Frame-Options "DENY", andX-XSS-Protection "1; mode=block". - Rate Limiting and Buffers: Request rate limits enforce 1r/s with a burst allowance of 30, and upload boundaries enforce a
client_max_body_sizeof 20M. - Routing: Dynamic backend endpoints, federated routes, and pict-rs calls route directly to port 8536, while standard client browser traffic resolves through the UI service on port 1234.
Sources
- Install from Scratch (join-lemmy.org)
Published October 30, 2026. No affiliate links on this page. Facts come from the sources linked above; check them for updates.