Installing BookWyrm, an open-source federated social network for book readers, on a Debian 12 server is a straightforward process that allows you to create your own ad-free alternative to platforms like Goodreads. By following this step-by-step guide, you’ll be able to set up BookWyrm and enjoy its features, such as book reviews, ratings, reading activity, bookshelves, book lists, and the ability to follow other users and their reading progress.
Prerequisites
Before we dive into the installation process, let’s make sure we have all the necessary prerequisites in place:
- A server running Debian 12.
- A non-root user with sudo privileges.
- A Fully Qualified Domain Name (FQDN) pointing to your server.
- An SMTP account with an email service like Amazon SES or Mailgun.
Ensure that your server is up to date by running the following commands:
$ sudo apt update $ sudo apt upgrade
We also need to install a few additional packages that our system requires:
$ sudo apt install wget curl nano ufw software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release debian-archive-keyring unzip-y
Step 1 – Configure Firewall
The first step in the installation process is to configure the firewall. By default, Debian comes with ufw (Uncomplicated Firewall). Let’s check if the firewall is running:
$ sudo ufw status
If the firewall is inactive, we can proceed with enabling it and allowing SSH, HTTP, and HTTPS connections:
$ sudo ufw allow OpenSSH $ sudo ufw allow http $ sudo ufw allow https $ sudo ufw enable
Step 2 – Install and Configure PostgreSQL
BookWyrm relies on PostgreSQL as its database management system. We’ll install PostgreSQL 15, as it’s not the default version in Debian 12. Let’s add the PostgreSQL GPG key and repository to our sources list:
$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql-key.gpg >/dev/null
$ sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/postgresql-key.gpg arch=amd64] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
$ sudo apt update
Now, we can install PostgreSQL and the postgresql-contrib package:
$ sudo apt install postgresql postgresql-contrib
After the installation, PostgreSQL should be up and running. We can launch the PostgreSQL shell and configure the BookWyrm database, user, and permissions:
$ sudo -i -u postgres psql
Inside the PostgreSQL shell, run the following commands to create the BookWyrm database, user, and grant the necessary privileges:
postgres=# CREATE DATABASE bookwyrm TEMPLATE template0 ENCODING 'UNICODE'; postgres-# CREATE USER bookwyrmuser WITH PASSWORD 'Your_Password'; postgres-# ALTER DATABASE bookwyrm OWNER TO bookwyrmuser; postgres-# GRANT ALL PRIVILEGES ON DATABASE bookwyrm TO bookwyrmuser; postgres-# \q
Verify that your PostgreSQL credentials work:
$ psql --username bookwyrmuser --password --host localhost bookwyrm
Step 3 – Install Redis
Redis is used by BookWyrm for session and cache storage. Although optional, Redis provides better performance for these tasks compared to using the database. Let’s install Redis 7.0 using the Redis repository:
$ curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
$ sudo apt update
$ sudo apt install redis
Once installed, we can test the Redis connection and set a password:
$ redis-cli
Inside the Redis shell, set a password for the default Redis user:
127.0.0.1:6379> acl setuser default >Your_Redis_Password
Authenticate with the Redis password:
127.0.0.1:6379> AUTH Your_Redis_Password
Exit the Redis shell. Redis is now ready to be used with BookWyrm.
Step 4 – Install Nginx
To serve BookWyrm to users, we’ll install Nginx, a high-performance web server and reverse proxy. Debian 12 ships with an older version of Nginx, so we’ll download the official Nginx repository to get the latest version:
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ http://nginx.org/packages/debian `lsb_release -cs` nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list
$ sudo apt update
$ sudo apt install nginx
After the installation, Nginx should be running by default. We can check its status:
$ sudo systemctl status nginx
Step 5 – Install SSL
To secure BookWyrm with SSL, we’ll use Certbot, a tool that automates the process of obtaining and renewing SSL certificates. We’ll install Certbot using the Snapd version:
$ sudo apt install snapd $ sudo snap install core && sudo snap refresh core $ sudo snap install --classic certbot $ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Ensure that Certbot is functioning correctly:
$ certbot --version
To generate the SSL certificate, run the following command, replacing “bookwyrm.example.com” with your own domain:
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [Christia@example.com]-d bookwyrm.example.com
The SSL certificate will be downloaded to the specified directory.
Step 6 – Download BookWyrm
Let’s create a directory for BookWyrm and clone the production branch from GitHub:
$ sudo mkdir /opt/bookwyrm $ cd /opt/bookwyrm $ sudo git clone https://github.com/bookwyrm-social/bookwyrm.git --branch production --single-branch./
Next, copy the example environment file:
$ sudo cp.env.example.env
Step 7 – Configure BookWyrm
Open the environment file for editing:
$ sudo nano.env
In this file, you’ll find several variables that need to be configured:
SECRET_KEY
: Generate a secret key for BookWyrm.DOMAIN
: Set the fully qualified domain name (FQDN) for your BookWyrm instance.POSTGRES_PASSWORD
,POSTGRES_USER
,POSTGRES_DB
: Set the PostgreSQL credentials.REDIS_ACTIVITY_HOST
,REDIS_BROKER_HOST
: Set the Redis host to “localhost” if Redis is running on the same machine.REDIS_ACTIVITY_PORT
,REDIS_BROKER_PORT
: Set the Redis port to the default port “6379”.REDIS_ACTIVITY_PASSWORD
,REDIS_BROKER_PASSWORD
: Set the Redis passwords chosen in Step 3.FLOWER_USER
,FLOWER_PASSWORD
: Choose a username and password for the Flower service.EMAIL_HOST
,EMAIL_PORT
,EMAIL_HOST_USER
,EMAIL_HOST_PASSWORD
: Configure your email settings.ENABLE_PREVIEW_IMAGES
: Set it to “true” if you want your instance to generate preview images automatically.
Save the file and exit the editor.
Step 8 – Configure Nginx
Copy the Nginx server configuration file:
$ sudo cp /opt/bookwyrm/nginx/server_config /etc/nginx/conf.d/server_config
Create and open the BookWyrm Nginx configuration file:
$ sudo nano /etc/nginx/conf.d/bookwyrm.conf
Paste the following code into the file:
include /etc/nginx/conf.d/server_config; upstream web { server localhost:8000; } server { listen [::]:80; listen 80; server_name bookwyrm.example.com; # redirect http to https return 301 https://bookwyrm.example.com$request_uri; } server { access_log /var/log/nginx/bookwyrm.access.log cache_log; error_log /var/log/nginx/bookwyrm.error.log; listen [::]:443 ssl http2; listen 443 ssl http2; server_name bookwyrm.example.com; client_max_body_size 3M; if ($host != "bookwyrm.example.com") { return 301 $scheme://bookwyrm.example.com$request_uri; } # SSL code ssl_certificate /etc/letsencrypt/live/bookwyrm.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/bookwyrm.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/bookwyrm.example.com/chain.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_prefer_server_ciphers off; ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] valid=60s; resolver_timeout 2s; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; tcp_nopush on; types_hash_max_size 2048; gzip on; proxy_read_timeout 1800s; # store responses to anonymous users for up to 1 minute proxy_cache bookwyrm_cache; proxy_cache_valid any 1m; add_header X-Cache-Status $upstream_cache_status; # ignore the set cookie header when deciding to # store a response in the cache proxy_ignore_headers Cache-Control Set-Cookie Expires; # PUT requests always bypass the cache # logged in sessions also do not populate the cache # to avoid serving personal data to anonymous users proxy_cache_methods GET HEAD; proxy_no_cache $cookie_sessionid; proxy_cache_bypass $cookie_sessionid; # tell the web container the address of the outside client proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; location ~ ^/(login[^-/]|password-reset|resend-link|2fa-check) { limit_req zone=loginlimit; proxy_pass http://web; } # do not log periodic polling requests from logged in users location /api/updates/ { access_log off; proxy_pass http://web; } location / { proxy_pass http://web; } # directly serve images and static files from the # bookwyrm filesystem using sendfile. # make the logs quieter by not reporting these requests location ~ ^/(images|static)/ { root /opt/bookwyrm; try_files $uri =404; add_header X-Cache-Status STATIC; access_log off; } # monitor the celery queues with flower, no caching enabled location /flower/ { proxy_pass http://localhost:8888; proxy_cache_bypass 1; } }
Save the file and exit the editor.
Open the Nginx configuration file for editing:
$ sudo nano /etc/nginx/nginx.conf
Add the following line before the line include /etc/nginx/conf.d/*.conf;
:
server_names_hash_bucket_size64;
Save the file and exit the editor.
Verify the Nginx configuration file syntax:
$ sudo nginx -t
If there are no syntax errors, restart Nginx to apply the new configuration:
$ sudo systemctl restart nginx
Step 9 – Install BookWyrm
Before we can run BookWyrm, we need to install some Python packages and set up the virtual environment. Let’s start by installing the necessary dependencies:
$ sudo apt install python3-venv python3-pip python3-dev libpq-dev
Change the ownership of the BookWyrm directory to the current user:
$ sudo chown -R $USER:$USER.
Create the Python virtual environment:
$ python3-m venv./venv
Install the BookWyrm Python dependencies:
$./venv/bin/pip3 install -r requirements.txt
Migrate the database schema:
$ venv/bin/python3 manage.py migrate
Initialize the database:
$ venv/bin/python3 manage.py initdb
Compile the themes:
$ venv/bin/python3 manage.py compile_themes
Create the static files:
$ venv/bin/python3 manage.py collectstatic --no-input
Create the BookWyrm system user:
$ sudo useradd bookwyrm -r
Change the owner of the installation directory to the BookWyrm user:
$ sudo chown -R bookwyrm:bookwyrm/opt/bookwyrm
From now on, run any BookWyrm-related command as the BookWyrm user:
$ sudo -u bookwyrm echo I am the ${whoami} user
Create BookWyrm service unit file
BookWyrm ships with service unit files for the main service, worker, and scheduler. Let’s copy them to the systemd directory:
$ sudo cp /opt/bookwyrm/contrib/systemd/*.service /etc/systemd/system/
Enable and start the services using the following command:
$ sudo systemctl enable bookwyrm bookwyrm-worker bookwyrm-scheduler --now
Check the status of the BookWyrm service:
$ sudo systemctl status bookwyrm
Repeat the same command for the other two services. All three services should be active and running.
Finally, generate the admin code, which is needed to create the administrator account:
$ sudo -u bookwyrm /opt/bookwyrm/venv/bin/python3 /opt/bookwyrm/manage.py admin_code
Make a note of the code provided. You can retrieve it at any time by running the same command.
Step 10 – Access BookWyrm
Open your browser and navigate to your BookWyrm instance using the URL https://bookwyrm.example.com
. You should see the BookWyrm sign-up page.
If everything appears as expected, click the “Continue” button to proceed. On the next page, enter the admin code you generated in the previous step, along with your desired administrator account credentials. Click the “Sign up” button to continue.
You will then be prompted to configure your