Skip to content

Instantly share code, notes, and snippets.

@alkavan
Last active August 19, 2026 10:02
Show Gist options
  • Select an option

  • Save alkavan/55d62b9e041c08f80954d1368e0bade6 to your computer and use it in GitHub Desktop.

Select an option

Save alkavan/55d62b9e041c08f80954d1368e0bade6 to your computer and use it in GitHub Desktop.
Rocky Linux 10 | Web Server Installation

Rocky Linux 10 | Web Server Installation

Notice

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

Some trivial commands might be missed or skipped.

Initial System Setup

1. Update System

dnf update -y

2. Set Machine Timezone

timedatectl set-timezone UTC
date

3. Set Machine Hostname

hostnamectl set-hostname my.domain

4. Install nano text editor, and tmux terminal emulation

dnf install nano tmux

5. Reboot System

reboot

login back to server (as root) to continue.

Enable EPEL Repository (optional)

dnf install -y epel-release
dnf update -y

Now you can install htop (for example):

dnf install htop

Disable cockpit (suggested, but optional)

systemctl stop cockpit.socket cockpit.service
systemctl disable cockpit.socket cockpit.service

Create webmaster superuser

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

Using sudo without a password

Create a new sudoers configuration file:

nano /etc/sudoers.d/wheel

Add the following content:

# 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 (Low Usage)

Swap is generally discouraged on production servers, but useful as a safety net for small sites or low-memory workloads.

1. Check current swap and memory

swapon -s
free -m
df -h

2. Create 1 GB swap file

sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

3. Make swap permanent

echo '/swapfile   swap    swap    sw  0   0' | sudo tee -a /etc/fstab

4. Optimize for rare swap usage

sudo tee -a /etc/sysctl.conf <<EOF

# Use swap only when really necessary
vm.swappiness=10

# Keep inode/dentry cache longer (better performance)
vm.vfs_cache_pressure=50
EOF

sudo sysctl -p

Swap space verification

swapon -s
sysctl vm.swappiness vm.vfs_cache_pressure
cat /proc/swaps

Ngnix Webserver

1. Install Nginx Web Server

sudo dnf install -y nginx
sudo systemctl enable --now nginx

2. Create Website Directory

sudo mkdir -p /var/www/example.com/public
sudo chown -R webmaster:webmaster /var/www/example.com
sudo chmod -R 755 /var/www/example.com

3. Create Nginx Configuration

sudo nano /etc/nginx/conf.d/example.com.conf

Add the following content:

server {
    listen 80;
    listen [::]:80; # comment if no ipv6
    server_name example.com;

    root /var/www/example.com/public;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    # Security headers (optional, but recommended)
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;

    # Deny access to hidden files
    location ~ /\. {
        deny all;
    }

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;
}

Test and reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

4. Allow Document Root in SELinux

sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/example.com(/.*)?"
sudo restorecon -R -v /var/www/example.com

5. Create index.html file:

tee /var/www/example.com/public/index.html > /dev/null << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Welcome!</title>
    <link rel="icon" type="image/x-icon" href="/favicon.ico" />
    <link rel="canonical" href="https://example.com" />
    <meta name="description" content="An example website." />
    <meta name="author" content="Joe D." />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<main>
    <p>Mess with the best, die like the rest.</p>
</main>
</body>
</html>
EOF

TLS/SSL Security

1. Generate Let's Encrypt Certificate

sudo dnf install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com

2. Restart Webserver

sudo systemctl restart nginx

3. Enable Automatic Renewal

sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew.timer

Firewall

This might not be required if using cloud provider security, like AWS Security Groups, or Digital Ocean Firewalls.

Install the firewalld service:

sudo dnf install firewalld

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

sudo firewall-cmd --state

If firewall not running start it.

sudo systemctl start firewalld.service

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

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

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

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

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

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

Or ...

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

Reload firewall:

sudo firewall-cmd --reload
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment