Lemmy 0.16.7 on OpenBSD 7.2
Tags: lemmy, fediverse, rust, actix
Published: 2023-01-15 05:23:56

## Summary

[Lemmy](https://join-lemmy.org/) is one of Fediverse implementations, which focuses on link aggregators. It also works as a platform for forums and microblogging.

On technical aspects, used are [Rust](https://www.rust-lang.org/) [Actix Web](https://actix.rs/), an actor-model web framework good at concurrency, and [InfernoJS](https://www.infernojs.org/), a blazingly fast client framework inspired by [React](https://reactjs.org/). Therefore, it runs comfortably fast.

This post shows how to install Lemmy and configure it on [OpenBSD](https://www.openbsd.org/), a solid operating system.
As to Rust's platform support, OpenBSD stands in Tier 3, the lowest in [Target Tier Policy](https://doc.rust-lang.org/rustc/target-tier-policy.html), and, however, it works !!

### Environment

- OS: OpenBSD [7.2](https://www.openbsd.org/72.html)
- Database: [PostgreSQL](https://www.postgresql.org/) [14.5](https://www.postgresql.org/docs/release/14.5/) (_released on_ Aug 11, 2022)
- Object Storage: [MinIO](https://min.io/) - [AWS](https://aws.amazon.com/) [S3](https://aws.amazon.com/s3/)-compatible (Optional)
- Web Server: [relayd](https://man.openbsd.org/relayd)
- Apps
  - Lemmy: 0.16.7
    - based on Rust [1.63](https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html) + Actix Web [4](https://github.com/actix/actix-web/wiki/v4-Announcement) + Actix 0.13
  - Lemmy-UI: 0.16.7
    - based on InfernoJS 7.4
  - Image hosting: [pict-rs](https://git.asonix.dog/asonix/pict-rs/) 0.3.2

## Tutorial

### PostgreSQL

#### Install PostgreSQL server and configure it (if undone)

[This post](https://obsd.solutions/en/blog/2022/11/13/postgresql-145-on-openbsd-72-install/index.html) should help.

#### Create database

Start [`psql`](https://www.postgresql.org/docs/current/app-psql.html):

```console
$ psql -U <your-postgres-user>
```

Run to create role:

```sql
create user lemmy with encrypted password '(...)';
```

The output was:

```console
CREATE ROLE
```

Then run to create database belonging to the role:

```sql
create database lemmy with owner lemmy \
    ENCODING 'UTF-8' template template0 LC_COLLATE 'C' LC_CTYPE 'C';
```

The output was:

```console
CREATE DATABASE
```

### MinIO (Optional)

[This post](https://obsd.solutions/en/blog/2023/01/11/minio-on-openbsd-72-install/index.html) and its series may help.

### Prepare Lemmy project

Suppose directories will be created as below:

```
/var
+-- /lemmy
    +-- /lemmy
    +-- /lemmy-ui
    +-- /pict-rs
```

#### Prepare Rust packages

```console
$ doas pkg_add rust
```

The output was:

```console
quirks-6.42 signed on 2023-01-13T18:22:41Z
rust-1.63.0p0:libssh2-1.10.0p0: ok
rust-1.63.0p0: ok
```

#### Add a Lemmy user

Run:

```console
$ doas useradd -d /var/lemmy -m _lemmy
```

Then act as the user:

```console
$ doas su - _lemmy
```

The login shell is perhaps [`ksh`](https://man.openbsd.org/ksh).

You must be in the home directory:

```console
$ pwd
/var/lemmy
```

### Lemmy server

This part is long so separated to another post. The following two are, too.

Go to [this post](https://obsd.solutions/en/blog/2023/01/15/lemmy-server-0167-on-openbsd-72-install/index.html) and then return.

### Lemmy-UI server

Go to [this post](https://obsd.solutions/en/blog/2023/01/15/lemmy-ui-0167-on-openbsd-72-install/index.html) and return.

### pict-rs server

Go to [this post](https://obsd.solutions/en/blog/2023/01/15/pict-rs-032-on-openbsd-72-install/index.html) and return.

### Build network

The servers are ready !! Switch back to your own user (by executing `exit`).

Here is the final network archtecture in this post.
All of Lemmy familly listen to `lo`, the internal network, only.
relayd handles request/response between the external and the internal, including [WebSocket](https://developer.mozilla.org/docs/Web/API/WebSocket) Lemmy-UI uses.

```
[external] <--> [internal]
                 relayd  <--> lemmy
                         <--> lemmy-ui
                              (websocket included)
                         <--> pict-rs
```

Be slightly careful about permissions of `rc.d` scripts.

#### Lemmy (server)

Create:

```console
$ doas nvim /etc/rc.d/lemmy
```

to write in it:

```sh
#!/bin/ksh

daemon="target/release/lemmy_server"
daemon_user="_lemmy"

daemon_execdir="/var/lemmy/lemmy"

. /etc/rc.d/rc.subr

rc_cmd $1
```

#### Lemmy-UI

Create:

```console
$ doas nvim /etc/rc.d/lemmy_ui
```

to write in it:

```sh
#!/bin/ksh

daemon="env LEMMY_UI_HOST=127.0.0.1:1234 LEMMY_INTERNAL_HOST=127.0.0.1:8536 LEMMY_EXTERNAL_HOST=<your-fqdb>:8536 LEMMY_WS_HOST=<your-fqdn>:443 node"
daemon_user="_lemmy"
daemon_flags="dist/js/server.js"

daemon_execdir="/var/lemmy/lemmy-ui"

. /etc/rc.d/rc.subr

rc_cmd $1
```

#### pict-rs

Create:

```console
$ doas nvim /etc/rc.d/lemmy_pict_rs
```

to write in it:

```sh
#!/bin/ksh

daemon="target/release/pict-rs"
daemon_user="_lemmy"
daemon_flags="-c pict-rs.toml"

daemon_execdir="/var/lemmy/pict-rs"

. /etc/rc.d/rc.subr

rc_cmd $1
```

#### `relayd.conf`

Configuration about [`httpd`](https://man.openbsd.org/httpd.8) is optional.
When you have other services in the same machine, you may have to do manage them.

```apache
# $OpenBSD: relayd.conf,v 1.5 2018/05/06 20:56:55 benno Exp $

# prefork 5

#table <httpd> { "127.0.0.1" }
lemmy_server_port = "8536"
table <lemmy_ui> { "127.0.0.1" }
lemmy_ui_port = "1234"
table <lemmy_server> { "127.0.0.1" }
lemmy_server_port = "8536"

your_fqdn = "<your-fqdn>"

cert_keypair = "<cert-keypair-name>"

http protocol "https-filter" {
	return error

	#match request forward to <httpd>
	match request header "Host" value $your_fqdn forward to <lemmy_ui>
	match request url "<your-fqdn>/api/" forward to <lemmy_server>
	match request url "<your-fqdn>/pictrs/" forward to <lemmy_server>

	http websockets

	tls keypair $cert_keypair
}
relay "https-proxy" {
	listen on egress port https tls
	
	protocol "https-filter"

	#forward to <httpd> port http check tcp
	forward to <lemmy_ui> port $lemmy_ui_port check tcp
	forward to <lemmy_server> port $lemmy_server_port check tcp
}

http protocol "lemmy-server" {
	http websockets

	tls keypair $cert_keypair
}
relay "lemmy-server" {
	listen on $your_fqdn port $lemmy_server_port tls

	protocol "lemmy-server"

	forward to <lemmy_server> port $lemmy_server_port check tcp
}
```

## Conclusion

Let's start the servers. Here are command lines to run them temporarily:

```console
$ doas rcctl -f start {lemmy, lemmy_ui, lemmy_pict_rs, relayd}
```

\* Besides, if you want to activate them, run `rcctl enable` beforehand, and `-f` option will be unnecessary.

Open your browser and access to \<your-fqdn\>. You will be welcomed.

![lemmy-setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qhdef5d2duopqp8si5b.png)

After signing up, you will be guided to create an instance:

![lemmy-instance-create-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v0z7ptr3tx77ri3k4rlp.png)

![lemmy-instance-create-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0va41sq930mziobu5mzb.png)

Then, voilà :)

![lemmy-on-openbsd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tmasdkuztwddudpw2dzp.png)

Happy swimming across the fediverse.