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.
dnf update -y
timedatectl set-timezone UTC
date
hostnamectl set-hostname my.domain
dnf install nano tmux
reboot
login back to server (as root) to continue.
dnf install -y epel-release
dnf update -y
Now you can install htop (for example):
dnf install htop
systemctl stop cockpit.socket cockpit.service
systemctl disable cockpit.socket cockpit.service
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
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 is generally discouraged on production servers, but useful as a safety net for small sites or low-memory workloads.
swapon -s
free -m
df -h
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap sw 0 0' | sudo tee -a /etc/fstab
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
swapon -s
sysctl vm.swappiness vm.vfs_cache_pressure
cat /proc/swaps
sudo dnf install -y nginx
sudo systemctl enable --now nginx
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
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
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/example.com(/.*)?"
sudo restorecon -R -v /var/www/example.com
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
sudo dnf install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com
sudo systemctl restart nginx
sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew.timer
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