> ## Documentation Index
> Fetch the complete documentation index at: https://wiki.lumiweb.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Web server (Nginx)

> Nginx + PHP + HTTPS on your own server

Let's set up the Nginx web server, serve a static site, add PHP, and chart a path to HTTPS. The commands are for root on Ubuntu/Debian; as a regular user, add `sudo`. The server's IP and root access come from the VPS card in the [@lumivps\_bot](https://t.me/lumivps_bot) bot.

<Tip>
  If you don't want to fiddle with configs by hand, it's easier to deploy your app via [Coolify](/en/vps/panel): it sets up the reverse proxy and SSL for you. This guide is for those configuring things manually.
</Tip>

## Installing Nginx

<Steps>
  <Step title="Install the package">
    ```bash theme={"system"}
    apt update
    apt install nginx
    ```

    The service starts automatically.
  </Step>

  <Step title="Verify">
    Open `http://your-server-IP` in a browser. The Nginx start page should appear ("Welcome to nginx!"). If the page doesn't open, port 80 is most likely closed (see the firewall warning below).
  </Step>
</Steps>

## How the configs are organized

Sites in Nginx on Ubuntu/Debian are described by separate files:

* `/etc/nginx/sites-available/` — this is where the configs for all sites live;
* `/etc/nginx/sites-enabled/` — a symlink to the active ones goes here.

In other words, you create a file in `sites-available` and then "enable" it with a symlink in `sites-enabled`.

```bash theme={"system"}
# enable the site
ln -s /etc/nginx/sites-available/site /etc/nginx/sites-enabled/

# check the syntax before applying
nginx -t

# apply changes without dropping connections
systemctl reload nginx
```

<Note>
  Always run `nginx -t` before `reload`. If there's an error in the config, `reload` won't apply it and Nginx will keep running on the old configuration — the site won't go down.
</Note>

## A simple static site

Create a directory for the site's files and put an `index.html` in it:

```bash theme={"system"}
mkdir -p /var/www/site
echo '<h1>It works</h1>' > /var/www/site/index.html
```

Create the config `/etc/nginx/sites-available/site`:

```nginx /etc/nginx/sites-available/site theme={"system"}
server {
    listen 80;
    listen [::]:80;

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

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

Enable the site and reload Nginx:

```bash theme={"system"}
ln -s /etc/nginx/sites-available/site /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
```

<Tip>
  The default `default` config in `sites-enabled` usually intercepts requests. If your site won't open, remove the default symlink: `rm /etc/nginx/sites-enabled/default` and `reload` again.
</Tip>

## Add PHP

For Nginx to handle `.php` (WordPress, scripts, etc.), you need PHP-FPM:

<Steps>
  <Step title="Install PHP-FPM">
    ```bash theme={"system"}
    apt install php-fpm
    ```
  </Step>

  <Step title="Add a PHP handler to the site config">
    <Note>
      The socket path depends on the PHP version. The package creates a versioned socket; the unversioned `/run/php/php-fpm.sock` doesn't exist — nginx will fail with a 502. First check which sockets you have:

      ```bash theme={"system"}
      ls /run/php/
      ```

      You'll see something like `php8.3-fpm.sock`. Substitute the exact name in the config below.
    </Note>

    Add a `location` block for `.php` inside `server { ... }`:

    ```nginx theme={"system"}
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;  # substitute your version
    }
    ```
  </Step>

  <Step title="Check and reload Nginx">
    ```bash theme={"system"}
    nginx -t
    systemctl reload nginx
    ```
  </Step>

  <Step title="Verify PHP works">
    Create `/var/www/site/info.php` with the contents `<?php phpinfo();` and open `http://example.com/info.php`. A table of PHP information should appear. After checking, delete this file — it exposes the server's configuration.
  </Step>
</Steps>

## HTTPS

A site on `http://` is worth securing with a certificate so that `https://` works. The certificate is installed separately — for free via Let's Encrypt, automated by the `certbot` tool. The full walkthrough is on a separate page:

<Card title="SSL certificate (Let's Encrypt)" icon="lock" href="/en/vps/ssl">
  How to issue a certificate for free and enable HTTPS with auto-renewal.
</Card>

<Warning>
  For the site to be reachable from outside, open ports **80** (HTTP) and **443** (HTTPS) in the firewall. How to set this up — see [firewall](/en/vps/firewall).
</Warning>

An alternative to Nginx is the Apache web server (`apt install apache2`); the principles are the same, but the configs and syntax differ.

## Where to next

<CardGroup cols={2}>
  <Card title="SSL certificate" icon="lock" href="/en/vps/ssl">
    Free HTTPS via Let's Encrypt with auto-renewal.
  </Card>

  <Card title="Firewall" icon="shield-halved" href="/en/vps/firewall">
    Open ports 80 and 443 for web traffic.
  </Card>
</CardGroup>
