vps-dedicated

Installing LAMP or LEMP on a Bare VPS

Setting up a Linux web server from a fresh VPS - Apache or Nginx, MySQL/MariaDB, PHP - the commands and configuration that get you to a working web server.

7 min read

When you provision a bare unmanaged VPS, you get a Linux system with nothing running on it. To host websites you need to install the web stack yourself — Apache or Nginx for the web server, MySQL or MariaDB for the database, PHP for the application layer. This combination is “LAMP” (Apache) or “LEMP” (Nginx, where the “E” is from engine-x). This guide walks through both, on AlmaLinux/RHEL and Ubuntu/Debian.

When you need this (and when you don’t)

Manual LAMP/LEMP install is needed when:

  • You bought an unmanaged VPS with just a base OS image.
  • You want full control over versions, configs, and components.
  • You’re learning Linux server administration.
  • The site is simple enough that a control panel feels excessive.

NOT needed when:

  • Your VPS comes with cPanel, DirectAdmin, or other control panel — that handles the stack.
  • You want to be productive immediately rather than learn server admin.
  • You’ll be hosting multiple sites with mailboxes / SSL / backups (control panels handle these much better).

If you’re managing more than one site or need email hosting, cPanel/DA pays for itself. Managed vs unmanaged comparison.

Before you start

  • SSH access to your VPS (root or sudo user).
  • Domain name pointing at your VPS IP (for SSL later).
  • Basic Linux command-line comfort.

Connect via SSH:

ssh root@your-vps-ip
# or for non-root with sudo:
ssh youruser@your-vps-ip

Update system first

# AlmaLinux / RHEL / CentOS
dnf update -y

# Ubuntu / Debian
apt update && apt upgrade -y

Reboot if kernel was updated: reboot. Reconnect SSH after.

LAMP — Apache + MySQL + PHP

Install Apache

# AlmaLinux
dnf install httpd -y
systemctl enable --now httpd

# Ubuntu
apt install apache2 -y
systemctl enable --now apache2

Visit http://your-vps-ip in browser — should see Apache default page.

Configure firewall

# AlmaLinux (firewalld)
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

# Ubuntu (ufw)
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 22/tcp
ufw enable

Install MariaDB (better than MySQL for most cases)

# AlmaLinux
dnf install mariadb-server -y
systemctl enable --now mariadb

# Ubuntu
apt install mariadb-server -y
systemctl enable --now mariadb

Secure the install:

mysql_secure_installation

Walks through: set root password, remove anonymous users, disallow remote root login, remove test database, reload privileges. Answer Y to all.

Install PHP

# AlmaLinux - enable Remi repo for current PHP versions
dnf install epel-release -y
dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm -y
dnf module reset php -y
dnf module enable php:remi-8.2 -y
dnf install php php-cli php-fpm php-mysqlnd php-zip php-gd php-mbstring php-curl php-xml php-bcmath php-intl -y

# Ubuntu
apt install php php-cli php-fpm php-mysql php-zip php-gd php-mbstring php-curl php-xml php-bcmath php-intl libapache2-mod-php -y

Verify: php -v should show PHP 8.2 (or whichever version you installed).

Test PHP

# AlmaLinux
echo "<?php phpinfo(); ?>" > /var/www/html/info.php

# Ubuntu
echo "<?php phpinfo(); ?>" > /var/www/html/info.php

Visit http://your-vps-ip/info.php. Should show PHP info page. DELETE this file after testing — exposes version info:

rm /var/www/html/info.php

Configure virtual host

AlmaLinux — create /etc/httpd/conf.d/yourdomain.conf:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/yourdomain
    ErrorLog /var/log/httpd/yourdomain-error.log
    CustomLog /var/log/httpd/yourdomain-access.log combined

    <Directory /var/www/yourdomain>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Then:

mkdir -p /var/www/yourdomain
chown -R apache:apache /var/www/yourdomain   # AlmaLinux
# OR
chown -R www-data:www-data /var/www/yourdomain  # Ubuntu
systemctl restart httpd  # or apache2 on Ubuntu

For Ubuntu, virtual host file goes in /etc/apache2/sites-available/yourdomain.conf and you enable with a2ensite yourdomain.

LEMP — Nginx + MariaDB + PHP-FPM

Install Nginx instead of Apache

# AlmaLinux
dnf install nginx -y
systemctl enable --now nginx

# Ubuntu
apt install nginx -y
systemctl enable --now nginx

MariaDB and PHP-FPM install same as LAMP, except don’t install libapache2-mod-php on Ubuntu.

Configure Nginx server block

Create /etc/nginx/conf.d/yourdomain.conf (AlmaLinux) or /etc/nginx/sites-available/yourdomain (Ubuntu):

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    root /var/www/yourdomain;
    index index.php index.html;

    access_log /var/log/nginx/yourdomain-access.log;
    error_log /var/log/nginx/yourdomain-error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /.ht {
        deny all;
    }
}

The php-fpm socket path varies — Ubuntu typically /var/run/php/php8.2-fpm.sock. Find with ls /var/run/php/ or check FPM config.

Test config and restart:

nginx -t
systemctl restart nginx
systemctl restart php-fpm  # or php8.2-fpm on Ubuntu

Adding SSL with Let’s Encrypt

Use Certbot to get free SSL certificates:

# AlmaLinux
dnf install certbot python3-certbot-apache -y  # for Apache
dnf install certbot python3-certbot-nginx -y   # for Nginx

# Ubuntu
apt install certbot python3-certbot-apache -y  # for Apache
apt install certbot python3-certbot-nginx -y   # for Nginx

Run Certbot:

certbot --apache -d yourdomain.com -d www.yourdomain.com
# OR
certbot --nginx -d yourdomain.com -d www.yourdomain.com

Walks through email, agreement, choice to redirect HTTP→HTTPS (say yes). Configures everything automatically.

Certbot installs a cron/systemd timer to auto-renew. Test it:

certbot renew --dry-run

Creating a database for your site

mysql -u root -p
CREATE DATABASE yoursite;
CREATE USER 'yoursiteuser'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON yoursite.* TO 'yoursiteuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Use these credentials in your application’s config (wp-config.php for WordPress, .env for modern frameworks).

Basic security hardening

  • SSH keys instead of passwords. SSH key guide.
  • Change SSH port from 22 to something less scanned (in /etc/ssh/sshd_config).
  • Disable root SSH login. PermitRootLogin no in sshd_config. Use sudo from a regular user.
  • Install fail2ban for brute-force protection: dnf install fail2ban -y or apt install fail2ban -y.
  • Keep updates current. dnf update / apt upgrade weekly.
  • Firewall lockdown. Only ports 22 (or your custom SSH), 80, 443 open by default.

Backups

Without a control panel, you handle backups. Minimum:

  • Daily database dump via cron: mysqldump --all-databases | gzip > /backups/$(date +%F).sql.gz
  • Daily site files archive: tar -czf /backups/$(date +%F).tar.gz /var/www/
  • Sync to off-server location (S3, Backblaze, rsync to another VPS).

Tools like restic or borg make this much nicer than ad-hoc scripts. Or install JetBackup standalone for VPS.

When to give up and install a control panel

If you find yourself:

  • Spending more time on server admin than your actual work.
  • Repeatedly hitting issues that “real hosting” would handle.
  • Wanting to host email, multiple domains, or have collaborators.

Wipe the VPS, reinstall with cPanel or DirectAdmin (or buy a managed VPS plan from iWebVault). Most professionals run their production sites on managed hosting and use bare VPS only for specific needs (Tor service, custom application server, learning).

Common LAMP/LEMP issues

“Apache won’t start — port 80 in use.” Something else is on port 80 (perhaps Nginx from a prior install). ss -tlnp | grep :80 shows what. Stop it.

“PHP page shows source code instead of executing.” PHP module not enabled/loaded. systemctl status php-fpm for FPM, check Apache modules with httpd -M | grep php.

“WordPress install asks for FTP credentials.” File ownership wrong. chown -R apache:apache /var/www/yourdomain (or www-data on Ubuntu).

“Nginx serves 502 Bad Gateway.” PHP-FPM not running, or wrong socket path in Nginx config. Check FPM status, verify socket path matches.

“Certbot fails to issue cert.” DNS not pointing to this server, port 80 not reachable from outside, or DNS hasn’t propagated. Verify with curl http://yourdomain.com from another machine.

What’s next

LAMP/LEMP gets you to a working web server in an hour. The ongoing maintenance — updates, backups, security, email setup, multiple sites — is where bare VPS becomes a part-time job. Make sure that part-time job is one you actually want before committing to it.

Was this helpful?