MHOSTMHOST

Nginx: install and your first site

In this article you'll install Nginx on your mHost VPS, enable it as a systemd service, publish a simple static site behind its own server block (vhost), and open the ports it needs in the firewall.

Diagram: the browser talks to Nginx, which forwards the request to the app — both running on the same VPS

What you'll need

  • An mHost VPS running Ubuntu 22.04/24.04, Debian 11/12, or AlmaLinux/Rocky Linux 8/9.
  • SSH access as root or a user with sudo.
  • A domain pointed at the server's IP address. For testing, the bare IP works too — you can set server_name later.
Tip: all commands below assume you're root. If you're using a regular sudo account, prefix each command with sudo.
Tip: if you need MySQL and PHP alongside Nginx, it's easier to use the ready-made LEMP recipe in VMmanager 6 (see the "Ready-made VMmanager 6 recipes" article) — it deploys the whole stack in one run. Below is how to install and configure Nginx by itself, manually.

Step 1. Install Nginx

Ubuntu / Debian

bash
apt update
apt install nginx

AlmaLinux / Rocky Linux

bash
dnf install nginx

The nginx package is already in the standard repository (AppStream) — no third-party repo needed.

Check that it installed:

bash
nginx -v
Tip: apt/dnf install the Nginx version from your distro's own repository — that's fine for a regular site. If you need the latest mainline or stable build straight from the Nginx developers, they maintain their own apt/yum repo — see nginx.org/en/linux_packages.html.

Step 2. Enable and start Nginx via systemd

bash
systemctl enable --now nginx
systemctl status nginx

enable --now both adds Nginx to startup and starts it immediately. The status should show active (running).

Check that the server responds — right on the VPS, before you've opened anything in the firewall:

bash
curl -I http://127.0.0.1/

An HTTP/1.1 200 OK response with a Server: nginx header means Nginx is running and serving its default page.

Step 3. Publish a static site

Create a dedicated folder for the site and drop an index.html into it:

bash
mkdir -p /var/www/example.com/html
bash
cat > /var/www/example.com/html/index.html <<'EOF'
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>example.com</title>
</head>
<body>
  <h1>Nginx работает!</h1>
  <p>Это статический сайт, размещённый на VPS mHost.</p>
</body>
</html>
EOF
Tip: Nginx's worker processes run as a dedicated user, not root — www-data on Ubuntu/Debian, nginx on AlmaLinux/Rocky. Files created the normal way (mkdir, cat, an editor) are world-readable by default, so /var/www doesn't need any extra chown/chmod.

Step 4. Configure a server block (vhost)

The configuration is identical for both distro families — only the file path differs.

Ubuntu / Debian: sites-available and sites-enabled

bash
cat > /etc/nginx/sites-available/example.com <<'EOF'
server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

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

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

Enable the site with a symlink into sites-enabled:

bash
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Tip: the placeholder default site is enabled there too by default (/etc/nginx/sites-enabled/default). It doesn't interfere with your site — Nginx picks the block by server_name — but if you'd rather turn the placeholder off entirely, remove the symlink: rm /etc/nginx/sites-enabled/default.

AlmaLinux / Rocky: conf.d

bash
cat > /etc/nginx/conf.d/example.com.conf <<'EOF'
server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

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

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

The .conf extension is required — only files with it get picked up by the include /etc/nginx/conf.d/*.conf; directive in /etc/nginx/nginx.conf. There's no separate enable step: anything in conf.d is already active.

Tip: don't set default_server on your own site — that flag is already taken by the default block in /etc/nginx/nginx.conf (which also has root /usr/share/nginx/html), and Nginx will refuse to start with a duplicate default server error. Your block will still work fine — Nginx selects it by server_name.
Tip: if you put the site's files somewhere other than /var/www or /usr/share/nginx/html — say, a custom directory — SELinux may make Nginx return 403 Forbidden. Label the directory with the right context (the policycoreutils-python-utils package provides the semanage command):
bash
dnf install policycoreutils-python-utils
semanage fcontext -a -t httpd_sys_content_t "/srv/example.com(/.*)?"
restorecon -Rv /srv/example.com

Step 5. Test the configuration and reload Nginx

bash
nginx -t

You should see syntax is ok and test is successful. Only then reload the configuration:

bash
systemctl reload nginx

reload picks up the changes without dropping existing connections — unlike restart, which restarts Nginx entirely.

Important: if nginx -t reports an error, don't run reload/restart until you've fixed it. Nginx will point to the exact file and line number.

Check that your site is now the one answering by name:

bash
curl -I -H "Host: example.com" http://127.0.0.1/

Step 6. Open ports 80 and 443 in the firewall

Important: ports 80 and 443 need to be open in the firewall, or the site won't be reachable from outside. If ufw isn't set up on the server yet, go through the "Setting up the UFW firewall" article first — it installs ufw, allows SSH (do this first, or you'll lock yourself out of the server), and enables the firewall. If ufw is already running, just add the rules for the web server:

Ubuntu / Debian (ufw)

bash
apt install ufw
ufw allow 80/tcp
ufw allow 443/tcp

AlmaLinux / Rocky (firewalld)

These distros use firewalld by default, not ufw — it's normally already installed and running (check with systemctl status firewalld):

bash
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
Done: open http://example.com (or the server's IP address) in a browser — you should see the "Nginx работает!" page from step 3.

What's next

Right now the site is only reachable over HTTP. To enable HTTPS, set up a Let's Encrypt certificate via Certbot — that's a separate topic. If you need a PHP backend with a database instead of a static site, check out the LEMP recipe in the "Ready-made VMmanager 6 recipes" article — it brings up Nginx, MySQL, and PHP in a single run.