HowtoForge

How to Install Wallabag on Rocky Linux 9

Wallabag is a read-it-later kind of service. It allows you to save webpages so that you can read them later at your own leisure pace. There are lots of services that allow you to do it like Pocket, Instapaper, etc but having a service installed on a server you own is much better. For one, it won't go out of business and take the links down with it.

This tutorial will cover installing and setting up Wallabag on a server running Rocky Linux 9. It will also cover how to set up Nginx, MySQL, Composer, and PHP, which are all required by Wallabag to run.

Prerequisites

Step 1 - Configure Firewall

The first step is to configure the firewall. Rocky Linux uses Firewalld Firewall. Check the firewall's status.

$ sudo firewall-cmd --state
running

The firewall works with different zones, and the public zone is the default one that we will use. List all the services and ports active on the firewall.

$ sudo firewall-cmd --permanent --list-services

It should show the following output.

cockpit dhcpv6-client ssh

Wallabag needs HTTP and HTTPS ports to function. Open them.

$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --permanent --add-service=https

Reload the firewall to apply the changes.

$ sudo firewall-cmd --reload

List all the services again.

$ sudo firewall-cmd --permanent --list-services

You should get the following output.

cockpit dhcpv6-client http https ssh

Step 2 - Install PHP and its extensions

We need to install PHP 8.1 for Wallabag to work. The first step is to grab the Epel repository.

$ sudo dnf install epel-release -y

Next, install the Remi repository.

$ sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm

Check for available PHP streams.

$ dnf module list php -y
Name                                   Stream                   Profiles                                        Summary                  
php                                    8.1                      common [d], devel, minimal                      PHP scripting language   

Remi's Modular repository for Enterprise Linux 9 - x86_64
Name                                   Stream                   Profiles                                        Summary                 
php                                    remi-7.4                 common [d], devel, minimal                      PHP scripting language   
php                                    remi-8.0                 common [d], devel, minimal                      PHP scripting language   
php                                    remi-8.1                 common [d], devel, minimal                      PHP scripting language   
php                                    remi-8.2                 common [d], devel, minimal                      PHP scripting language   

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled

The default version is 8.1. Enable Remi's PHP 8.1 repository.

$ sudo dnf module reset php -y
$ sudo dnf module enable php:remi-8.1

Install PHP and the required extensions required by Wallabag.

$ sudo dnf install php-fpm php-mysql php-bcmath php-xml php-zip php-curl php-mbstring php-gd php-tidy php-intl php-cli php-opcache

Verify the installation.

$ php --version
PHP 8.1.16 (cli) (built: Feb 14 2023 18:59:41) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.1.16, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.16, Copyright (c), by Zend Technologies

Open the file /etc/php-fpm.d/www.conf.

$ sudo nano /etc/php-fpm.d/www.conf

Find the user=apache and group=apache lines in the file and change them as follows.

...
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx
...

Next, uncomment the socket file owner, group, and default permission line and alter them as shown below.

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server.
; Default Values: user and group are set as the running user
;                 mode is set to 0660
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

Next, comment out the following line as shown by putting a semi-colon in front of it.

;listen.acl_users = apache,nginx

Save the file by pressing Ctrl + X and entering Y when prompted.

Give proper permissions to the PHP session directory.

$ sudo chown -R nginx:nginx /var/lib/php/session/

Enable and start the PHP-FPM service.

$ sudo systemctl enable php-fpm --now

Step 3 - Install Composer

Composer is a dependency management tool for PHP and is required for Wallabag installation.

Run the following commands to download the Composer binary. Wallabag only works with Composer 2.2 LTS so we have modified the command accordingly.

$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php composer-setup.php --2.2
$ php -r "unlink('composer-setup.php');"

Install Composer by moving the binary to the /usr/local/bin directory.

$ sudo mv composer.phar /usr/local/bin/composer

Verify the installation by checking its version.

$ composer --version
Composer version 2.2.21 2023-02-15 13:07:40

Step 4 - Install MySQL

Rocky Linux 9 ships with the latest version of MySQL. You can install it with a single command.

$ sudo dnf install mysql-server

Check the version of MySQL.

$ mysql --version
mysql  Ver 8.0.30 for Linux on x86_64 (Source distribution)

Enable and start the MySQL service.

$ sudo systemctl enable mysqld --now

Run the MySQL secure install script.

$ sudo mysql_secure_installation

You will be asked to install the Validate Password Component. It checks the strength of passwords used in MySQL. Press Y to install it. Next, you will be asked to set the level of the password validation policy. Choose 2 as it is the strongest one.

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: Y

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary                  file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2
Using existing password for root.

Estimated strength of the password: 100

Next, you will be asked to set a new root password. Enter the password according to the requirements set above. Enter Y when prompted to continue with the chosen root password.

Please set the password for root here.

New password: 

Re-enter new password: 

Estimated strength of the password: 100 
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y

Next, enter Y to remove anonymous users, disallow remote root logins, remove the test database, and reload the privilege tables.

By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.

All done!

Step 5 - Configure MySQL

Log in to the MySQL shell. Enter your root password when prompted.

$ sudo mysql -u root -p

Create a sample database.

mysql> CREATE DATABASE wallabag;

Create an SQL user account.

mysql> CREATE USER 'wallabaguser'@'localhost' IDENTIFIED BY 'Your_password2';

Grant all privileges on the database to the user.

mysql> GRANT ALL PRIVILEGES ON wallabag.* TO 'wallabaguser'@'localhost';

Flush user privileges.

mysql> FLUSH PRIVILEGES;

Exit the shell.

mysql> exit

Step 6 - Install Nginx

Rocky Linux 9 ships with an older version of Nginx. You need to download the official Nginx repository to install the latest version.

Create and open the /etc/yum.repos.d/nginx.repo file for creating the official Nginx repository.

$ sudo nano /etc/yum.repos.d/nginx.repo

Paste the following code in it.

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

Save the file by pressing Ctrl + X and entering Y when prompted.

Install the Nginx server.

$ sudo dnf install -y nginx

Verify the installation.

$ nginx -v
nginx version: nginx/1.22.1

Enable and start the Nginx server.

$ sudo systemctl enable nginx --now

Check the status of the server.

$ sudo systemctl status nginx
? nginx.service - nginx - high performance web server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
     Active: active (running) since Tue 2023-02-28 08:01:34 UTC; 5s ago
       Docs: http://nginx.org/en/docs/
    Process: 1489 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
   Main PID: 1490 (nginx)
      Tasks: 2 (limit: 5873)
     Memory: 1.9M
        CPU: 8ms
     CGroup: /system.slice/nginx.service
             ??1490 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
             ??1491 "nginx: worker process"

Step 7 - Install SSL

We need to install Certbot to generate the SSL certificate.

We will use the Snapd package installer for that. Since Rocky Linux doesn't ship with it, install the Snapd installer. It requires the EPEL repository to work which we installed before for PHP so we can skip the step.

Install Snapd.

$ sudo dnf install -y snapd

Enable and Start the Snap service.

$ sudo systemctl enable snapd --now

Install the Snap core package, and ensure that your version of Snapd is up to date.

$ sudo snap install core && sudo snap refresh core

Create necessary links for Snapd to work.

$ sudo ln -s /var/lib/snapd/snap /snap
$ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh

Issue the following command to install Certbot.

$ sudo snap install --classic certbot

Use the following command to ensure that the Certbot command can be run by creating a symbolic link to the /usr/bin directory.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Verify the installation.

$ certbot --version
certbot 2.3.0

Run the following command to generate an SSL Certificate.

$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d wallabag.example.com

The above command will download a certificate to the /etc/letsencrypt/live/wallabag.example.com directory on your server.

Generate a Diffie-Hellman group certificate.

$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Check the Certbot renewal scheduler service.

$ sudo systemctl list-timers

You will find snap.certbot.renew.service as one of the services scheduled to run.

NEXT                        LEFT          LAST                        PASSED        UNIT                      ACTIVATES
.....
Sun 2023-02-28 06:32:00 UTC 9h left       Sat 2023-02-28 18:04:05 UTC 2h 59min ago  snap.certbot.renew.timer  snap.certbot.renew.service
Sun 2023-02-28 06:43:20 UTC 9h left       Sat 2023-02-28 10:49:23 UTC 10h ago       apt-daily-upgrade.timer   apt-daily-upgrade.service
Sun 2023-02-28 09:00:06 UTC 11h left      Sat 2023-02-28 20:58:06 UTC 5min ago      apt-daily.timer           apt-daily.service

Do a dry run of the process to check whether the SSL renewal is working fine.

$ sudo certbot renew --dry-run

If you see no errors, you are all set. Your certificate will renew automatically.

Step 8 - Install Wallabag

Create the /var/www/wallabag/html directory.

$ sudo mkdir /var/www/html/wallabag -p

Download the latest version of Wallabag.

$ wget https://wllbg.org/latest-v2-package

Extract the archive.

$ tar xzf latest-v2-package

Move the files from the extracted directory to the directory created earlier. Modify the command with the correct version number. You can check the latest version of the Wallabag from the GitHub releases page. The latest version at the time of writing this tutorial is 2.5.4.

$ sudo mv wallabag-2.5.4/* /var/www/html/wallabag

Create the asset directory.

$ sudo mkdir /var/www/html/wallabag/data/assets

Change the permissions of the /var/www/html/wallabag directory to the currently logged-in user.

$ sudo chown -R $USER:$USER /var/www/html/wallabag

Switch to the directory.

$ cd /var/www/html/wallabag

Create the parameters.yml file by copying the example file.

$ cp app/config/parameters.yml.dist app/config/parameters.yml

Before we start configuring Wallabag, generate a secret key. Note down the key to be used later.

$ openssl rand -base64 32
QLV/GpZwDobQbyQZQ15FkM1Hvt+ZFJZXw8GW9F4KR3o=

Open the parameters file for editing.

$ nano app/config/parameters.yml

Find the following section and fill in the database credentials. The database port is 3306 for MySQL.

..........
    database_driver: pdo_mysql
    database_host: 127.0.0.1
    database_port: 3306
    database_name: wallabag
    database_user: wallabaguser
    database_password: Your_password2

Fill in the server description and domain name.

    domain_name: https://wallabag.example.com
    server_name: "Howtoforge Wallabag"

Fill in your SMTP details. In our case, we are using Amazon SES service.

    mailer_transport:  smtp
    mailer_user:       YOUR_AES_USERNAME
    mailer_password:   YOUR_AES_PASSWORD
    mailer_host:       email-smtp.us-west-2.amazonaws.com
    mailer_port:       587
    mailer_encryption: tls

Fill in the secret key generated before. If you want to keep two-factor authentication, then make sure the following settings are applied. If you want to turn off user registration, set the value of fouser_registration to false. The fouser_confirmation variable is set to true which means every user registration will need to be confirmed via email. Change the value of the from_email variable to the email id of your choice.

    # A secret key that's used to generate certain security-related tokens
    secret: QLV/GpZwDobQbyQZQ15FkM1Hvt+ZFJZXw8GW9F4KR3o=

    # two factor stuff
    twofactor_auth: true
    twofactor_sender: no-reply@wallabag.org

    # fosuser stuff
    fosuser_registration: true
    fosuser_confirmation: true
.....
    from_email: no-reply@wallabag.org
.....

There are more sentries related to Redis, RabbitMQ, and Sentry settings. You can configure them as per your needs after installing the said packages.

Save the file by pressing Ctrl + X and entering Y when prompted.

Use Composer to download and install the dependencies required by Wallabag.

$ SYMFONY_ENV=prod composer install --no-dev -o --prefer-dist

Finish the installation using Wallabag command-line tool.

$ php bin/console wallabag:install --env=prod

You will be prompted if you want to reset the database and its schema. Enter no as the response both times. Next, you will be asked if you want to create an administrator account. Type yes to proceed and enter the username, password, and email id for the account.

wallabag installer
==================

Step 1 of 4: Checking system requirements.
------------------------------------------

 ------------------------ -------- ---------------- 
  Checked                  Status   Recommendation  
 ------------------------ -------- ---------------- 
  PDO Driver (pdo_mysql)   OK!                      
  Database connection      OK!                      
  Database version         OK!                      
  curl_exec                OK!                      
  curl_multi_init          OK!                      
 ------------------------ -------- ---------------- 

 [OK] Success! Your system can run wallabag properly.                                                                   
                                                                                                                        

Step 2 of 4: Setting up database.
---------------------------------

 It appears that your database already exists. Would you like to reset it? (yes/no) [no]:
 > no

 Seems like your database contains schema. Do you want to reset it? (yes/no) [no]:
 > no

 Clearing the cache...

 Database successfully setup.

Step 3 of 4: Administration setup.
----------------------------------

 Would you like to create a new admin user (recommended)? (yes/no) [yes]:
 > yes

 Username [wallabag]:
 > navjot

 Password [wallabag]:
 > 

 Email [wallabag@wallabag.io]:
 > navjot@example.com

 Administration successfully setup.

Step 4 of 4: Config setup.
--------------------------

 Config successfully setup.
                                                                                                                        
 [OK] wallabag has been successfully installed.                                                                         
                                                                                                                     
 [OK] You can now configure your web server, see https://doc.wallabag.org

Switch back the directory permission to Nginx.

$ sudo chown -R nginx:nginx /var/www/html/wallabag

Step 9 - Configure SELinux

Change the file security context for Wallabag and its sub-directories.

$ sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html/wallabag(/.*)?"
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/wallabag/data(/.*)?"
$ sudo semanage fcontext -a -t httpd_log_t "/var/www/html/wallabag/var/logs(/.*)?"
$ sudo semanage fcontext -a -t httpd_cache_t "/var/www/html/wallabag/var/cache(/.*)?"

Apply the policies.

$ sudo restorecon -R -v /var/www/html/wallabag

Apply the policy to allow Nginx to give access to MySQL.

$ sudo setsebool -P httpd_can_network_connect_db 1

Step 10 - Configure Nginx and PHP

Configure PHP-FPM

Open the file /etc/php/8.1/fpm/pool.d/www.conf.

$ sudo nano /etc/php/8.1/fpm/pool.d/www.conf

We need to set the Unix user/group of PHP processes to nginx. Find the user=www-data and group=www-data lines in the file and change them to nginx.

...
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx
...

Next, uncomment the socket file owner, group, and default permission line and alter them as shown below.

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server.
; Default Values: user and group are set as the running user
;                 mode is set to 0660
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

Next, comment out the following line as shown by putting a semi-colon in front of it.

;listen.acl_users = apache,nginx

Save the file by pressing Ctrl + X and entering Y when prompted.

Increase the execution time for PHP-FPM and PHP-CLI to 60 seconds.

$ sudo sed -i 's/max_execution_time = 30/max_execution_time = 60/' /etc/php/8.1/fpm/php.ini
$ sudo sed -i 's/max_execution_time = 30/max_execution_time = 60/' /etc/php/8.1/cli/php.ini

Increase the memory limit for PHP-FPM from 128MB to 256MB.

$ sudo sed -i 's/memory_limit = 128M/memory_limit = 256M/' /etc/php/8.1/fpm/php.ini

Restart the PHP-FPM service.

$ sudo systemctl restart php8.1-fpm

Change the group of the PHP sessions directory to Nginx.

$ sudo chgrp -R nginx /var/lib/php/sessions

Configure Nginx

Create and open the file /etc/nginx/conf.d/wallabag.conf for editing.

$ sudo nano /etc/nginx/conf.d/wallabag.conf

Paste the following code in it.

server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  wallabag.example.com;

    access_log  /var/log/nginx/wallabag.access.log;
    error_log   /var/log/nginx/wallabag.error.log;

	# SSL
    ssl_certificate      /etc/letsencrypt/live/wallabag.example.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/wallabag.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/wallabag.example.com/chain.pem;
    ssl_session_timeout  5m;
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    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;
    ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    resolver 8.8.8.8;

    root /var/www/html/wallabag/web;

    location / {
        try_files $uri /app.php$is_args$args;
    }

    # Pass PHP Scripts To FastCGI Server
    location ~ ^/app\.php(/|$) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Depends On The PHP Version
        fastcgi_param SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        include fastcgi_params;
        internal;
    }

    location ~ \.php$ {
        return 404;
    }
}

# enforce HTTPS
server {
    listen       80;
    listen       [::]:80;
    server_name  wallabag.example.com;
    return 301   https://$host$request_uri;
}

Notice the root directory to be used in the Nginx configuration is /var/www/html/wallabag/public/.

Save the file by pressing Ctrl + X and entering Y when prompted once finished.

Open the file /etc/nginx/nginx.conf 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_size  64;

Save the file by pressing Ctrl + X and entering Y when prompted.

Verify the Nginx configuration file syntax.

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Restart the Nginx service.

$ sudo systemctl restart nginx

Step 11 - Access Wallabag

Open the URL https://wallabag.example.com in your browser and you will get the following login screen.

Enter your credentials created during installation and press the LOG IN button to proceed. You will be greeted with the Wallabag dashboard.

Wallabag provides you with a multitude of apps for every browser, mobile, or Ebook reader, using which you can add links. And if nothing else fancies you, you can even use a Bookmarklet, the details of which you can access from the How to section by clicking the user icon on the top right of the dashboard.

You will be given links to the browser extensions, mobile apps, and the Wallabag bookmarklet.

That's it. You can start using Wallabag to save articles for reading later.

Conclusion

This concludes our tutorial on installing Wallabag on a Rocky Linux 9 server. If you have any questions, post them in the comments below.

How to Install Wallabag on Rocky Linux 9