Skip to content

Instantly share code, notes, and snippets.

@alkavan
Last active June 8, 2024 17:06
Show Gist options
  • Save alkavan/de22105721acfbd0474d9076fe2b9717 to your computer and use it in GitHub Desktop.
Save alkavan/de22105721acfbd0474d9076fe2b9717 to your computer and use it in GitHub Desktop.
Rocky Linux 8 | Web Server

Rocky Linux 8 - Web Application Server Installation Guide

Notice

This cheatsheet assumes the user is knowledgeable about bare installations of virtual private servers on cloud providers and is looking for quick but comprehensive instructions.

Some trivial commands might be missed or skipped.
However, this document can also work as quick tutorial for newcomers to the RHEL eco-system.

Also, I would like to promote Rocky Linux as a solid alternative for enterprise systems. Machines with Rocky Linux are provided by DigitalOcean a great and super stable cloud provider I've been using for years. All the following servers/services can be installed and run stable on a 1CPU/2GB/50GB, 2CPU/2GB/50GB or 2CPU/4GB/50GB droplets (choose by your load).

Initial System Setup

Update system.

dnf update

Set your timezone.

timedatectl set-timezone UTC
date

Set the machine hostname.

hostnamectl set-hostname my.domain

Install nano text editor.

dnf install nano

Reboot system, login back to server (as root).

reboot

Create non-root superuser

Create yourself a user.

adduser webmaster

Copy root key to user home (you can remove it from the root user later).

cp -r -p /root/.ssh/ /home/webmaster/
chown -R webmaster:webmaster /home/webmaster/.ssh

Add your user to wheel group (as supplementary group, primary group still webmaster).

usermod -a -G wheel webmaster

For using sudo without requiring a password create the following configuration:

nano /etc/sudoers.d/wheel

Then add the following line:

# allow wheel group use without password
%wheel  ALL=(ALL)       NOPASSWD: ALL

Logout server, and login again as webmaster user.

exit

Reconnect with webmaster user and check sudo access is working ...

sudo su

Install Firewall

You might need to install the service.

dnf install firewalld

Check firewall status (should be off in most cases).

firewall-cmd --state

If firewall not running start it.

systemctl start firewalld.service

Check the current state of firewall (ssh should be enabled):

firewall-cmd --get-active-zones
firewall-cmd --list-all

Add temporary http/https rule(s) to public zone:

firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=https

Add permanent http/https rule(s) to public zone:

firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --zone=public --add-service=https --permanent

Or ...

firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent

Enable EPEL Repository

dnf install epel-release
dnf update

Apache 2.4

Install apache 2.4 HTTP and HTTPS web server and dependencies.

dnf install httpd httpd-filesystem httpd-manual httpd-tools mod_ssl

Start server, check server is working, and enable during boot:

systemctl start httpd
systemctl status httpd
systemctl enable httpd

PHP 8.0

Install Remi's PHP repository (EL8):

dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
dnf module list php
dnf module enable php:remi-8.0

Install PHP packages:

dnf install php \
php-fpm \
php-common \
php-bcmath \
php-mbstring \
php-cli \
php-dba \
php-gd \
php-opcache \
php-intl \
php-pdo \
php-mysqlnd \
php-pgsql \
php-process \
php-tidy \
php-xml \
php-xmlrpc \
php-json \
php-pecl-memcached \
php-pecl-igbinary \
php-pecl-msgpack

Restart the web server and fpm:

systemctl restart php-fpm httpd
systemctl status php-fpm httpd
systemctl enable php-fpm

Create php test page:

echo "<?php phpinfo(); ?>" > /var/www/html/index.php

Open browser, goto: http://<server_ip>/ You should see PHP info page, remove the index page afterwards.

rm /var/www/html/index.php

PostgreSQL 13

Enable version 13 module:

dnf module list postgresql
dnf module enable postgresql:13 

Install postgresql server and client packages:

dnf install postgresql \
postgresql-libs \
postgresql-server \
postgresql-contrib \
postgresql-docs \
postgresql-devel \
postgresql-plperl \
postgresql-plpython3 \
postgresql-pltcl

Initialize data directory:

postgresql-setup initdb

Setup database service (enable if works):

systemctl start postgresql
systemctl status postgresql
systemctl enable postgresql

Check you can access the database locally:

su - postgres
psql

Remote Access (security risk, use SSH tunnel)

If you wish to connect the database remotly, add it to firewall rules.
You should prefer ssh tunnel and not allow remote connections!

firewall-cmd --permanent --zone=public --add-service=postgresql
systemctl restart firewalld.service

Database Authentication Settings

By default postgres is configured to authenticate all remote users with ident service.
This will not work for applications or even SSH tunnel.

Edit database configuration file, change password authentication to scram-sha-256.

nano /var/lib/pgsql/data/postgresql.conf
- #password_encryption = md5
+ password_encryption = scram-sha-256

Edit the client authentication configuration:

nano /var/lib/pgsql/data/pg_hba.conf

And edit it the following way (duplicate two host lines):

# IPv4 local connections:
#host    all             all             127.0.0.1/32            ident
host    all             all             127.0.0.1/32      	    scram-sha-256
# IPv6 local connections:
#host    all             all             ::1/128                 ident
host    all             all             ::1/128                 scram-sha-256

This should force all remote connections to authenicate using scram-sha-256 method.

Finally, restart the server and check it's status.

systemctl restart postgresql
systemctl status postgresql

Database User Creation

Create superuser role, no database, no password.

createuser -w -d -s webmaster

Use psql postgres from the webmaster account to login locally, and change the password.

alter user webmaster with password 'myawesomepassword';
select rolpassword from pg_authid where rolname = 'webmaster';

You should get back the encrypted password starts with SCRAM-SHA-256.

Memcached

This cache server enables TCP/IP access to system cache.
It is a good solution to be used locally for standalone machine, or remotly on another machine.

dnf -y install memcached

Edit configuration and adjust to machine settings.

nano /etc/sysconfig/memcached

Enable service (if status is okay).

systemctl start memcached
systemctl status memcached
systemctl enable memcached

Generating Let's Encrypt SSL Certificate

Install certbot tool and apache module.

dnf install certbot python3-certbot-apache

Generate the domain certifcate only (without configuration of the web server):

certbot certonly -d mydomain.com

Generate certificate for your website (and configure apache):

certbot --apache -d mydomain.com

To renew all certificates you can run sudo certbot renew --dry-run if okay then without the --dry-run flag.
Or just renew the certificate fo a spesific domain:

certbot renew -d mydomain.com

Swap Space

There are some good resons not to enable swap space on production machines.
However, this gist assumes either you're using this for a small website,
or you know excactly what you're doing.

Check if server has swap, if it does, you can skip this step.

swapon -s

Check how much memory the machine has, and how much disk space.

free -m && df -h

Create swap file on disk, and confirm size and permissions.

dd if=/dev/zero of=/swapfile count=2048 bs=1MiB
chmod 600 /swapfile
ls -lh /swapfile

Enable generate and enable swap space.

mkswap /swapfile
swapon /swapfile
swapon -s

If you want to make swap permanent, edit the filesystem configuration:

nano /etc/fstab

Then add the following line at the bottom:

/swapfile   swap    swap    sw  0   0

Swap Optimization

CentOS defaults to a swappiness setting of 30, which is a fair middle ground for most desktops and local servers. For a VPS system, we'd probably want to move it closer to 0.

sysctl vm.swappiness=10 

Cache Pressure

This option controls the tendency of the kernel to reclaim the memory which is used for caching of directory and inode objects. At the default value of vfs_cache_pressure=100 the kernel will attempt to reclaim dentries and inodes at a "fair" rate with respect to pagecache and swapcache reclaim.

Constantly reading and refreshing this information is generally very costly, so storing it on the cache for longer is excellent for your system's performance.

Check your current system settings.

cat /proc/sys/vm/vfs_cache_pressure

To make cache inode information from the cache more slowly. setting this to 50 might me good middle ground for a cloud server:

sysctl vm.vfs_cache_pressure=50

Persistent Cache Settings

This setting will persist until the next reboot. To make the setting persist between reboots, we can add the outputted lines to our sysctl configuration file:

nano /etc/sysctl.conf

Docker

Add docker repository.

dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo

Install docker service.

dnf install -y docker-ce

Start service and, check status:

systemctl start docker
systemctl status docker
systemctl enable docker

Add currect user to docker gorup (you will need to re-login).

usermod -aG docker $USER
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment