Skip to content

Instantly share code, notes, and snippets.

@alkavan
Last active June 8, 2024 19:51
Show Gist options
  • Save alkavan/6bfe9295d1abdb4ba10ead844782e862 to your computer and use it in GitHub Desktop.
Save alkavan/6bfe9295d1abdb4ba10ead844782e862 to your computer and use it in GitHub Desktop.
Rocky Linux 9 | Web Application Server

Rocky Linux 9 | Web Application Server Installation

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.

Initial System Setup

Update system.

dnf update -y

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

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

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 -y epel-release
dnf update

Now you can install htop for example:

dnf install htop

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

Create directory for storing web site configurations:

mkdir /etc/httpd/env.d/
echo -e 'IncludeOptional /etc/httpd/env.d/*.conf\n' > /etc/httpd/conf.d/env.conf

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

systemctl start httpd
systemctl status httpd
systemctl enable httpd

PHP 8.1

Install Remi's PHP repository (EL8).

dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
dnf module list php -y
dnf module enable php:remi-8.1

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

Node (JavaScript)

sudo dnf install nodejs npm

PostgreSQL 15

Enable version 15 module:

dnf module list postgresql
dnf module enable postgresql:15

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, uncomment setting.

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

Edit the client authentication configuration:

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

Edit configuration so it looking like this (add scram-sha-256 line):

# 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.


Docker

Notice: there are some good reasons not to use docker on a server machine, as well as some advantages for application that fit the use-case. This is especially true for machines with <= 2GB of memory and <= CPU, use docker only when it's actually required.

Add docker repository:

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

Install docker service:

dnf -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Start service and, check status:

systemctl --now enable docker
systemctl status docker

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

sudo usermod -a -G docker $(whoami)

SSL/TLS Certificates

Install the certbot application with Apache plugin:

sudo dnf install certbot python3-certbot-apache

Or alternatively, install the certbot application with Nginx plugin:

sudo dnf install certbot python3-certbot-nginx

Create a certificate for your domain:

sudo certbot --apache -d mykewldomain.com

Restart the HTTP server:

sudo systemctl restart httpd

Enable the renew cron job:

sudo systemctl start certbot-renew.timer
@baomin
Copy link

baomin commented May 14, 2024

good

@alkavan
Copy link
Author

alkavan commented Jun 7, 2024

good

thanks man! i keep updating it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment