How to Host a Website on a Linux VPS in 2026: Complete Step-by-Step Guide

How to Host a Website on a Linux VPS in 2026: Complete Step-by-Step Guide

To host a website on a Linux VPS, deploy a supported server operating system, connect through SSH, secure the server, point the domain to the VPS, install a web server such as Nginx, create a virtual host, upload the website files or configure a reverse proxy, enable HTTPS, configure backups and monitoring, and test the site from an external network.

This tutorial uses Ubuntu 26.04 LTS and Nginx. The commands are also similar on Ubuntu 24.04 LTS and recent Debian releases. AlmaLinux and Rocky Linux use different package, firewall, and web-server directory conventions.

The guide covers three common deployment types:

  • A static HTML, CSS, and JavaScript website.
  • A PHP website using PHP-FPM.
  • A Node.js, Python, or other application behind an Nginx reverse proxy.

Keep an active SSH session open while changing firewall or SSH settings. Confirm a second connection works before closing the first one.

Linux VPS Website Hosting Checklist

Stage Main task Result
1 Choose VPS resources and location A suitable server
2 Deploy and update Linux A supported operating system
3 Secure SSH and firewall Protected administration
4 Configure DNS The domain points to the VPS
5 Install Nginx A working web server
6 Create a server block The correct site answers for the domain
7 Upload or deploy the application Website content is available
8 Enable HTTPS Encrypted browser connections
9 Add monitoring and backups Detection and recovery
10 Test and launch A production-ready website

What You Need Before Starting

  • A Linux VPS with root or sudo access.
  • A domain name you control.
  • An SSH client.
  • The website files or application source code.
  • A supported Linux distribution.
  • A secure place for credentials and SSH keys.
  • A backup destination outside the VPS.

Windows users can connect through PowerShell or Windows Terminal. The guide to installing Linux Bash on Windows 10 provides another command-line option for older Windows environments.

Step 1: Choose the Right VPS for Website Hosting

A basic static website can run on a small VPS. Dynamic sites need more CPU, memory, storage, and database capacity.

Website type vCPU RAM Storage starting point
Small static site 1 1 GB 20 GB SSD
Small business website 1–2 2 GB 30–50 GB SSD or NVMe
WordPress or small PHP site 2 2–4 GB 40–80 GB NVMe
Several websites 2–4 4–8 GB 80–160 GB NVMe
E-commerce or busy application 4+ 8 GB+ 100 GB+ NVMe

These are planning ranges. A cached website can serve significant traffic on a modest server, while inefficient plugins, database queries, or background jobs can overwhelm a larger VPS.

Choose a nearby server location

Place the VPS near the majority of uncached users or near critical external services. Distance, routing, and peering affect response time. Review How to Choose the Best Server Location and Best Server Location for Low Latency.

Choose SSD or NVMe storage

Dynamic websites and databases benefit from low storage latency. NVMe is a strong choice for WordPress, e-commerce, content management systems, and applications that generate many small reads and writes.

Check transfer and port speed

Review monthly transfer, port speed, overage charges, DDoS protection, and traffic graphs. Website traffic includes images, scripts, downloads, API requests, bots, backups, and software updates.

Step 2: Deploy a Supported Linux Operating System

Ubuntu 26.04 LTS is a practical choice for a new server in 2026. It receives standard security maintenance through May 2031. Ubuntu 24.04 LTS also remains supported. Debian, AlmaLinux, and Rocky Linux are suitable alternatives when required by the application or control panel.

Use Best Server OS in 2026 to compare Linux and Windows options. Organizations replacing CentOS can review Best CentOS Replacements.

During VPS deployment:

  • Select a minimal server image.
  • Upload an SSH public key when the provider supports it.
  • Record the public IP address.
  • Enable a provider firewall only after confirming the required rules.
  • Verify that a browser console or rescue mode is available.
  • Set a descriptive server name.

Step 3: Connect Through SSH

Connect using the address from the provider:

ssh root@SERVER_IP

When using a private key stored in a non-default location:

ssh -i ~/.ssh/website_vps root@SERVER_IP

Verify the server host-key fingerprint through the provider dashboard when possible.

If SSH fails, check the server status, IP address, username, key permissions, provider firewall, and port. The Port Ping guide explains how to test whether a specific service port is reachable.

Step 4: Create a Non-Root Administrator

Create a named account:

adduser adminuser
usermod -aG sudo adminuser

Copy the existing SSH keys:

rsync --archive --chown=adminuser:adminuser \
  ~/.ssh /home/adminuser

Open a second terminal and test:

ssh adminuser@SERVER_IP
sudo whoami

The final command should return root. Do not disable root access until the new account works.

See also  VPS with Nested Virtualization in 2026: Definition, Use Cases, and Setup Overview

Step 5: Update the VPS

sudo apt update
sudo apt upgrade -y
sudo apt autoremove --purge -y

Check whether a reboot is required:

test -f /run/reboot-required && echo "Reboot required"

After rebooting, reconnect and inspect failed services:

systemctl --failed

Install useful administration tools:

sudo apt install -y curl wget git unzip rsync \
  ca-certificates htop

Step 6: Configure SSH and the Firewall

After key authentication works, create an SSH hardening file:

sudo nano /etc/ssh/sshd_config.d/99-website-server.conf
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
AllowUsers adminuser

Validate and reload:

sudo sshd -t
sudo systemctl reload ssh

Confirm another SSH connection works before closing the existing session.

Install UFW:

sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Do not expose database ports publicly unless a specific secured architecture requires it. Databases should normally listen on localhost or a private network.

Step 7: Point the Domain to the VPS

Open the DNS management panel for the domain and create the appropriate records.

Record type Name Value
A @ VPS IPv4 address
A www VPS IPv4 address
AAAA @ VPS IPv6 address, only when configured
CNAME www example.com, as an alternative to a second A record

Replace example.com and the example address with real values. Do not publish an AAAA record until IPv6 firewall rules, Nginx listeners, and connectivity have been tested.

Check resolution:

dig +short example.com A
dig +short www.example.com A

DNS caches can delay changes. Lower the TTL before a planned migration, then increase it after the new server is stable.

Step 8: Install Nginx

sudo apt install nginx -y

Start and enable it:

sudo systemctl enable --now nginx
sudo systemctl status nginx

Check the local response:

curl -I http://127.0.0.1

Check the configuration:

sudo nginx -t

Open the server IP in a browser. The default Nginx page should appear if DNS and the domain are not ready yet.

Step 9: Create the Website Directory

Create a dedicated document root:

sudo mkdir -p /var/www/example.com/public
sudo chown -R adminuser:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 750 {} \;
sudo find /var/www/example.com -type f -exec chmod 640 {} \;

Create a test page:

cat <<'EOF' | sudo tee /var/www/example.com/public/index.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Example Website</title>
</head>
<body>
  <h1>Website deployed successfully</h1>
</body>
</html>
EOF

Static files usually do not need write permission for the web-server user. Application upload directories, cache folders, and generated files may require carefully limited write access.

Step 10: Create an Nginx Server Block

Create the configuration:

sudo nano /etc/nginx/sites-available/example.com

Use this static-site configuration:

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

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

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

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

Enable it:

sudo ln -s /etc/nginx/sites-available/example.com \
  /etc/nginx/sites-enabled/example.com

Disable the default site when it is no longer needed:

sudo rm -f /etc/nginx/sites-enabled/default

Test and reload:

sudo nginx -t
sudo systemctl reload nginx

Test the domain:

curl -I http://example.com

Step 11: Upload the Website Files

Upload with rsync

From your local computer:

rsync -avz --delete ./website/ \
  adminuser@SERVER_IP:/var/www/example.com/public/

The --delete option removes remote files that do not exist locally. Use it only when the deployment directory is correct and backed up.

Upload with SCP

scp -r ./website/* \
  adminuser@SERVER_IP:/var/www/example.com/public/

Deploy with Git

Clone to a release directory rather than exposing the repository metadata publicly:

git clone REPOSITORY_URL /tmp/example-release
rsync -av --delete /tmp/example-release/ \
  /var/www/example.com/public/

Use deploy keys or tokens with minimum repository permissions. The guide to running your own Git server explains self-hosted source-control concepts.

Step 12: Enable HTTPS

Before requesting a certificate, confirm:

  • The A record points to the VPS.
  • Port 80 is open.
  • Nginx serves the correct domain.
  • The server time is correct.
  • No CDN or proxy is blocking validation.

Install Certbot and the Nginx plugin from the Ubuntu repositories:

sudo apt install certbot python3-certbot-nginx -y

Request and install the certificate:

sudo certbot --nginx \
  -d example.com \
  -d www.example.com

Choose the HTTPS redirect option when appropriate. Then test renewal:

sudo certbot renew --dry-run

Inspect the timer:

systemctl list-timers | grep certbot

Test the site:

curl -I https://example.com

Step 13: Host a PHP Website

Install PHP-FPM and common extensions:

sudo apt install -y php-fpm php-cli php-curl \
  php-mbstring php-xml php-zip php-mysql

Identify the installed PHP-FPM socket:

ls /run/php/

Add a PHP handler to the server block, using the actual socket name:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php-fpm.sock;
}

On Ubuntu, the real socket usually contains the PHP version, such as php8.x-fpm.sock. Replace the example with the exact file shown on your server.

Test configuration and reload:

sudo nginx -t
sudo systemctl reload nginx

Do not leave a public phpinfo() page on the server. It reveals software and environment details.

Step 14: Use Nginx as a Reverse Proxy

Node.js, Python, Go, Java, and other applications often listen on a private local port while Nginx handles public HTTP and HTTPS traffic.

Example for an application on 127.0.0.1:3000:

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Bind the application to localhost when only Nginx should reach it. Do not expose port 3000 publicly through UFW.

Run the application with systemd

Create a dedicated application user and service. Example:

[Unit]
Description=Example Web Application
After=network-online.target
Wants=network-online.target

[Service]
User=exampleapp
Group=exampleapp
WorkingDirectory=/opt/exampleapp
EnvironmentFile=/etc/exampleapp.env
ExecStart=/opt/exampleapp/venv/bin/python /opt/exampleapp/app.py
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Use the command required by the real application. Store secrets outside the repository and restrict access to the environment file.

Step 15: Install a Database Safely

Dynamic websites may use MariaDB, MySQL, or PostgreSQL. Install only the database required by the application.

Example MariaDB installation:

sudo apt install mariadb-server -y
sudo systemctl enable --now mariadb
sudo mariadb-secure-installation

Create a separate database and user for each application. Grant only required permissions. Keep the database bound to localhost unless a private multi-server architecture requires remote access.

See also  Benefits of Using a Masternode Hosting Provider

Back up databases with application-consistent tools. Copying raw database files while the service is running may produce an unusable backup.

Step 16: Improve Website Performance

Enable compression

Ubuntu’s Nginx package includes common gzip configuration. Verify compression for appropriate text assets and avoid compressing already compressed images and archives.

Configure browser caching

For versioned static assets:

location ~* \.(css|js|jpg|jpeg|png|gif|svg|webp|ico|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    try_files $uri =404;
}

Use long cache periods only when filenames change after content updates. Otherwise, visitors may keep old files.

Use application caching

WordPress and other applications can use full-page caching and object caching. Test exclusions for logged-in users, carts, accounts, checkout, and personalized pages.

Optimize images

Serve appropriately sized images, compress them, use modern formats where compatible, and lazy-load noncritical media. Hosting upgrades cannot compensate for oversized page assets.

Use a CDN when appropriate

A content delivery network can cache static files near users, absorb traffic spikes, and reduce origin transfer. The VPS still needs enough resources for uncached requests, application logic, and cache refills.

Step 17: Configure Logging

Nginx logs are normally stored in /var/log/nginx/.

View recent errors:

sudo tail -n 100 /var/log/nginx/example.com.error.log

Follow access logs:

sudo tail -f /var/log/nginx/example.com.access.log

Check the Nginx service journal:

sudo journalctl -u nginx -n 100 --no-pager

Do not log passwords, session tokens, authorization headers, sensitive query strings, payment details, or unnecessary personal information.

Step 18: Configure Monitoring and Alerts

Monitor both the VPS and the website.

  • External HTTPS availability.
  • HTTP status codes.
  • Response time.
  • TLS certificate expiry.
  • CPU and memory.
  • Disk usage and inode usage.
  • Storage latency.
  • Nginx and application service state.
  • Database availability.
  • Error-log rate.
  • Backup success.

Compare tools in Best Linux System Monitor and The Best Server Management Tool.

Send alerts outside the VPS so they remain available when the server is unreachable.

Step 19: Back Up the Website

Back up:

  • Website files.
  • Databases.
  • Nginx configuration.
  • Application environment configuration.
  • Certificates and renewal settings.
  • Scheduled tasks.
  • Deployment instructions.
  • DNS records.

Keep at least one copy outside the VPS and test restoration. Follow How to Back Up and Restore Data on a VPS for retention, off-server storage, and recovery testing.

Snapshots are useful before major changes, but they should not replace independent backups.

Step 20: Add Automatic Security Updates

sudo apt install unattended-upgrades -y
sudo unattended-upgrade --dry-run --debug

Check for required reboots:

test -f /run/reboot-required && echo "Reboot required"

Automatic updates require monitoring. Verify that Nginx, PHP-FPM, databases, and application services recover correctly after updates and reboots.

Compare endpoint protection in Best Antivirus Software for Servers. Security software is one layer; it does not replace patching, access control, firewalls, and backups.

Hosting Multiple Websites on One VPS

Nginx can host several domains by using a separate server block and document root for each site.

Recommended structure:

/var/www/example.com/public
/var/www/example.net/public
/etc/nginx/sites-available/example.com
/etc/nginx/sites-available/example.net

Use separate:

  • Application users.
  • Databases and database users.
  • Log files.
  • Certificates.
  • Backup paths.
  • Deployment credentials.

A hosting control panel can simplify multi-site management. Compare Best Control Panel for Linux VPS, Best Web Hosting Control Panel, and Plesk vs cPanel.

Website Migration Checklist

  1. Audit files, databases, cron jobs, certificates, DNS, and email dependencies.
  2. Build and secure the new VPS.
  3. Install matching application versions.
  4. Copy files and import the database.
  5. Test using a temporary hostname or local hosts-file entry.
  6. Reduce DNS TTL before the migration.
  7. Place the old site into maintenance mode when necessary.
  8. Perform a final data synchronization.
  9. Update DNS records.
  10. Monitor traffic, errors, forms, transactions, and background jobs.
  11. Keep the old server available for rollback.
  12. Raise DNS TTL after the migration is stable.

Website Hosting Security Checklist

  • The Linux release is supported and patched.
  • SSH uses keys and direct root login is disabled.
  • Only SSH, HTTP, and HTTPS are publicly open unless another service is required.
  • The provider account uses multi-factor authentication.
  • Nginx configuration passes nginx -t.
  • HTTPS renewal has been tested.
  • Applications, plugins, themes, and dependencies are updated.
  • Database ports are not exposed publicly.
  • Secrets are stored outside source code.
  • File ownership and write permissions are limited.
  • Logs are reviewed and do not expose secrets.
  • Backups are off-server and restore-tested.
  • Monitoring detects outages, full disks, and certificate expiry.

Common Problems and Fixes

The domain does not open

Check DNS, firewall rules, Nginx status, and the server block:

dig +short example.com
sudo ufw status
sudo systemctl status nginx
sudo nginx -T

Nginx shows 403 Forbidden

Check document-root permissions, directory execute permissions, file ownership, the configured root path, and the existence of an index file.

Nginx shows 404 Not Found

Verify the requested file exists under the configured document root. For a single-page application, configure fallback routing deliberately rather than returning every missing asset as the application index.

Nginx shows 502 Bad Gateway

The upstream application or PHP-FPM service may be stopped, listening on the wrong socket, or blocked by permissions.

sudo systemctl --failed
sudo ss -ltnp
sudo journalctl -u nginx -n 100

Certbot cannot validate the domain

Confirm the domain resolves to the VPS, port 80 is reachable, the correct server block responds, and a CDN or proxy is not interfering with the selected validation method.

The site is slow

Measure CPU, memory, disk latency, database queries, PHP workers, application logs, cache hit rates, page weight, and external API calls. Do not upgrade the VPS before identifying the bottleneck.

The disk is full

df -h
df -i
sudo du -xhd1 /var /opt /home 2>/dev/null | sort -h

Review logs, caches, old releases, backups, database files, and temporary uploads. Add alerts before the disk reaches full capacity.

See also  VPS Hosting for Elasticsearch: Complete Guide for 2026

Plan Website Email Separately

Hosting a website and operating a reliable mail server are different tasks. Web forms, password resets, order confirmations, and notifications need dependable delivery, reputation management, bounce handling, SPF, DKIM, DMARC, and abuse controls.

For many websites, use a specialized transactional email provider rather than sending directly from the VPS. The application connects to the provider through authenticated SMTP or an API. This avoids placing the website IP address, server resources, and operational workload at the center of email delivery.

When the VPS must send mail directly:

  • Configure a valid hostname and reverse DNS.
  • Create SPF, DKIM, and DMARC records.
  • Restrict relay access.
  • Protect SMTP credentials.
  • Monitor delivery failures and reputation.
  • Separate marketing email from transactional traffic.
  • Keep mailing lists and consent records outside application logs.

Do not install a complete mail stack merely because a contact form needs to send a message. Every extra public service adds security and maintenance responsibility.

Create a Staging Environment and Deployment Workflow

Production should not be the first place where code, database migrations, plugins, Nginx changes, or package updates are tested. A staging environment can be a second small VPS, an isolated virtual host, a container, or a temporary clone created before an important release.

A safe deployment workflow includes:

  1. Back up the database and application configuration.
  2. Test the release in staging.
  3. Run automated tests and application health checks.
  4. Review schema migrations and rollback limits.
  5. Create a versioned release directory.
  6. Switch the active release with a controlled symlink or service restart.
  7. Monitor errors, latency, and transactions.
  8. Keep the previous release available for rollback.

A versioned directory structure can look like:

/var/www/example.com/releases/2026-07-17-1
/var/www/example.com/releases/2026-07-20-1
/var/www/example.com/current -> releases/2026-07-20-1
/var/www/example.com/shared

Store uploads, secrets, and persistent data in a shared directory instead of copying them into every release. Limit the number of old releases so unused files do not fill the disk.

Use a CDN, Reverse Proxy, or Web Application Firewall Carefully

A CDN or reverse-proxy service can cache static files, hide the origin IP in normal traffic, filter selected attacks, terminate TLS, and serve users from nearby edge locations. It does not replace origin security.

When adding a proxy layer:

  • Allow origin access only from trusted proxy networks when practical.
  • Configure Nginx to trust client-IP headers only from approved proxy addresses.
  • Keep HTTPS between the proxy and origin.
  • Monitor both edge and origin errors.
  • Document cache rules and purge procedures.
  • Exclude account, cart, checkout, and personalized pages from unsafe caching.
  • Keep a method for testing the origin directly.

Never trust a user-supplied forwarding header from the public internet. An attacker can forge it unless Nginx accepts that header only from known proxy networks.

Estimate Website Bandwidth and Capacity

Estimate monthly transfer before choosing a VPS:

Monthly website transfer = average delivered page size × page views + downloads + API traffic + backups + software updates

For example, 500,000 page views with an average delivered size of 1.5 MB represent about 750 GB before bots, downloads, and operational traffic. A CDN can reduce origin transfer when assets are cacheable.

Track these capacity indicators:

  • Peak requests per second.
  • 95th-percentile response time.
  • CPU utilization during traffic peaks.
  • Available memory and swap activity.
  • Database query latency.
  • Disk input/output latency.
  • Network throughput.
  • Cache hit ratio.
  • Free disk and inode capacity.

Scale vertically when the application needs more CPU, RAM, or storage on one server. Scale horizontally when the application can run across multiple web nodes behind a load balancer. Horizontal scaling normally requires shared or replicated sessions, media storage, databases, and deployment state.

Calculate the Full Cost of VPS Website Hosting

The monthly VPS price is only one part of the budget. Include:

  • Regular and renewal server price.
  • Backups and snapshot storage.
  • Public IPv4 charges.
  • CDN and data transfer.
  • Control-panel licenses.
  • Monitoring and log retention.
  • Database or email services.
  • Security tools and DDoS protection.
  • Administrator time.
  • Migration and emergency support.

A low-cost VPS is good value when the team can operate it securely. A managed VPS may be less expensive overall when a website generates revenue and the organization lacks Linux administration skills.

Production Launch Checklist

  • The domain resolves to the correct IPv4 and tested IPv6 addresses.
  • HTTP redirects to HTTPS.
  • The TLS certificate is valid and renewal works.
  • The correct site answers for every domain variant.
  • Application forms, accounts, uploads, email, and background jobs work.
  • Database backups can be restored.
  • External monitoring is active.
  • Disk, CPU, memory, and service alerts are delivered.
  • The provider console and rescue process are documented.
  • The website has a rollback plan.
  • Unnecessary default files and services are removed.
  • Administrative accounts and SSH keys are documented.

Final Verdict

A production-ready website on a Linux VPS requires more than installing Nginx. The complete environment includes a supported operating system, secure SSH access, a restrictive firewall, correct DNS, a tested Nginx server block, HTTPS, application process management, monitoring, backups, and a recovery plan.

Start with 1–2 vCPUs and 2–4 GB RAM for a small dynamic site, then measure real usage. Keep databases private, store secrets outside the code repository, test every Nginx change before reloading, and maintain off-server backups. Upgrade only when monitoring shows a real CPU, memory, storage, or network limit.

Frequently Asked Questions

Can I host a website on a VPS?

Yes. A VPS can host static sites, WordPress, PHP applications, Node.js, Python, databases, APIs, and multiple domains when it has sufficient resources.

How much RAM does a website VPS need?

A static site may use 1 GB. A small dynamic website usually benefits from 2–4 GB, while e-commerce, multiple sites, and busy databases may need 8 GB or more.

Is Nginx or Apache better for a VPS?

Both are capable. Nginx is popular for static files and reverse proxying. Apache offers broad module and application compatibility. Choose based on the application and administrator experience.

Do I need a domain to host a website on a VPS?

No. You can test through the IP address, but a domain is needed for normal public branding and straightforward browser-trusted HTTPS certificates.

Does a VPS website need HTTPS?

Yes. HTTPS protects browser connections, credentials, forms, and session data. Configure automatic certificate renewal and monitor expiry.

Can I host multiple websites on one VPS?

Yes. Use separate Nginx server blocks, document roots, application users, databases, logs, certificates, and backups.

Should I install a database on the same VPS?

It is practical for small websites. Larger or high-availability systems may separate the database. Keep database ports private and maintain tested backups.

Do I need a control panel?

No. Nginx and applications can be managed through the command line. A panel is useful for managing many websites, customers, DNS zones, databases, and email accounts.

How much does it cost to host a website on a VPS?

A small unmanaged Linux VPS often costs about $4–$20 per month. Backups, management, licenses, premium networking, and larger resources increase the total.

Are VPS snapshots enough for website backups?

No. Use independent off-server file and database backups with retention, monitoring, and tested restoration.

Leave a Comment