Installation

ServerList Installation Guide

This guide describes how to install an official ServerList release on a clean Linux server. It uses Debian 13, Ubuntu 24.04 and Nginx as reference examples; they are not the only supported Linux/web-server combination.

Official production releases already contain the PHP dependencies and compiled frontend assets. A normal production installation does not require Composer, Node.js or npm.

ServerList is designed for a modern Linux hosting environment.

Recommended:

  • Ubuntu 24.04 LTS or Debian 13
  • PHP 8.4.1 or newer (PHP 8.x)
  • PHP-FPM
  • Nginx
  • PostgreSQL
  • Redis

PHP 8.4.1 is the minimum supported PHP version for both CLI and PHP-FPM. The locked dependencies cannot run on PHP 8.3 or PHP 8.4.0.

The PHP runtime used by the website and command line must have these extensions enabled: cURL, DOM, Fileinfo, Filter, Hash, Iconv, LibXML, Mbstring, OpenSSL, PCRE, PDO, PDO PostgreSQL, Session, Tokenizer, XML, XMLWriter and Redis. The web installer checks them before installation can continue.

1. Prepare the Server

Start with an up-to-date Linux installation.

Update the system:

sudo apt update
sudo apt upgrade -y

Install the basic services:

sudo apt install -y nginx postgresql redis-server unzip python3 sudo cron

PHP 8.4 on Debian 13

Debian 13 provides PHP 8.4 from its official repositories. Install PHP 8.4 and the required extensions:

sudo apt install -y \
    php8.4 \
    php8.4-fpm \
    php8.4-cli \
    php8.4-curl \
    php8.4-pgsql \
    php8.4-redis \
    php8.4-xml \
    php8.4-mbstring

PHP 8.4 on Ubuntu 24.04

Ubuntu 24.04 provides PHP 8.3 in its default repositories, which does not meet ServerList’s PHP 8.4.1 minimum. Install a supported PHP 8.x release.

To install PHP 8.4 on Ubuntu 24.04, first install the required repository tools:

sudo apt install -y software-properties-common ca-certificates lsb-release apt-transport-https

Add the maintained PHP repository:

sudo add-apt-repository -y ppa:ondrej/php

Update the package index:

sudo apt update

Then install PHP 8.4 and the required extensions:

sudo apt install -y \
    php8.4 \
    php8.4-fpm \
    php8.4-cli \
    php8.4-curl \
    php8.4-pgsql \
    php8.4-redis \
    php8.4-xml \
    php8.4-mbstring

Verify PHP-FPM is version 8.4.1 or newer:

php-fpm8.4 -v

On other supported Linux distributions, use a trusted PHP repository suitable for that distribution when PHP 8.4 is not available from the default package repositories.

Verify the CLI also uses PHP 8.4.1 or newer with the required extensions, including native Mbstring, Iconv and LibXML:

php -v
php -m

Verify PostgreSQL:

sudo systemctl status postgresql

Verify Redis:

redis-cli ping

Redis should answer:

PONG

2. Configure PHP Upload Limits

ServerList supports server image uploads up to 5 MB.

For PHP 8.4 with PHP-FPM, create:

/etc/php/8.4/fpm/conf.d/99-serverlist.ini

Add:

; ServerList upload limits
upload_max_filesize = 5M
post_max_size = 10M

Restart PHP-FPM:

sudo systemctl restart php8.4-fpm

Important: ServerList checks the PHP configuration used by the website. Changing only the PHP CLI configuration is not sufficient.

The installer will block installation when the active web PHP configuration does not meet these limits.

3. Create the PostgreSQL Database

Create a dedicated PostgreSQL database and user for ServerList.

Open PostgreSQL:

sudo -u postgres psql

Example:

CREATE USER serverlist WITH PASSWORD 'replace-with-a-strong-password';
CREATE DATABASE serverlist OWNER serverlist;
\q

Use a strong, unique database password in production.

Keep the following information available for the ServerList installer:

Host:       127.0.0.1
Port:       5432
Database:   serverlist
Username:   serverlist
Password:   your chosen password
SSL mode:   prefer

For remote PostgreSQL installations, use the host and SSL configuration provided by your database provider.

4. Prepare Redis

For a standard local Redis installation, the usual values are:

Host:             127.0.0.1
Port:             6379
Username:         empty
Password:         empty
Queue database:   0
Cache database:   1

The queue and cache database numbers should be different.

Remote or secured Redis installations may require a username and/or password.

5. Upload ServerList

Choose a production application directory, for example:

/var/www/serverlist

Create it if necessary:

sudo mkdir -p /var/www/serverlist

Download the official release archive to a non-public location, then extract it into the empty application directory. For example:

sudo tar -xzf /path/to/ServerList-1.3.0.tar.gz -C /var/www/serverlist

Do not extract an update archive over an existing installation; use the updater for every update.

The application directory should contain files and directories such as:

app/
bootstrap/
config/
database/
public/
resources/
routes/
storage/
vendor/
artisan
composer.json
.env.example

A production release may also contain precompiled frontend assets under:

public/build/

Do not configure the website document root as:

/var/www/serverlist

The web server document root must be:

/var/www/serverlist/public

6. Set Ownership and Permissions

The PHP-FPM/webserver user must be able to write to the Laravel runtime directories.

For a simple Ubuntu installation using the standard www-data user:

sudo chown -R www-data:www-data /var/www/serverlist

Ensure the required Laravel directories are writable:

sudo chmod -R ug+rwX /var/www/serverlist/storage
sudo chmod -R ug+rwX /var/www/serverlist/bootstrap/cache

The installer must also be able to create or modify the .env file.

For advanced deployments using a separate deployment user, shared group permissions can be used instead of assigning the complete application to www-data.

Do not use world-writable permissions such as chmod 777.

The installer checks the required filesystem permissions before allowing the installation to continue.

Prepare the updater backup directory (required)

After assigning the final installation owner/group, run this privileged setup step before opening the web installer (or when repairing an existing deployment):

sudo bash /var/www/serverlist/scripts/prepare-backups.sh /var/www/serverlist

Replace both installation paths if you use a different directory. The script creates /var/backups/serverlist outside the application with the installation directory's owner/group and mode 0750. Run the updater as that installation owner. A separate PHP-FPM user does not need write access to private backups.

This step is safe to repeat for the same owner and preserves existing backup contents. It rejects symlinks, unsafe parent directories and a backup directory belonging to another owner rather than taking over another installation's data. Resolve such conflicts explicitly; do not use recursive ownership changes or world-writable permissions. /var/backups must exist, be root-owned and not be group/world writable (the normal Debian/Ubuntu setup).

The web installer performs a read-only requirement check and blocks continuation if the directory is missing or has unsafe ownership/permissions. It never runs sudo or creates privileged directories. Existing installations can run the same setup command; updater preflight checks remain unchanged, including writability and available backup space at update time.

7. Configure Nginx

Create an Nginx virtual host for the ServerList domain.

Example configuration:

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

    server_name servers.example.com;

    root /var/www/serverlist/public;
    index index.php;

    client_max_body_size 10M;

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

    location ^~ /storage/ {
        try_files $uri =404;
    }

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

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Replace servers.example.com with the actual domain.

The important settings are:

Document root: /var/www/serverlist/public
PHP-FPM:       PHP 8.4.1 or newer
Body limit:    at least 10 MB

Apache is also suitable when configured with PHP 8.4.1 or newer. Its virtual host must use /var/www/serverlist/public as the document root, route Laravel requests to index.php, keep .env and the project root private, serve public/storage as static files, and allow a request body of at least 10 MB. Use the configuration method appropriate to your Apache/PHP-FPM installation; do not point Apache at the application root.

Verify the Nginx configuration:

sudo nginx -t

Then reload Nginx:

sudo systemctl reload nginx

Configure TLS/HTTPS now if your certificate process allows it. The installer should receive the final public HTTPS URL in the next section.

8. Generate the Installer Access Key

ServerList protects new installations with a temporary installer access key.

From the application directory, run:

cd /var/www/serverlist
php artisan installer:key

The command displays the temporary installer access key.

Keep this key available while completing the web installer.

The key is temporary and is removed when installation is successfully completed.

If the command is run by a deployment or root user, ServerList attempts to make the generated key readable by the webserver group inherited from the storage directory.

9. Open the Web Installer

Open the ServerList website in a browser.

An uninstalled ServerList installation redirects to:

/install

Enter the temporary installer access key when requested.

The installer contains six steps.

Step 1 - System Requirements

ServerList checks:

  • PHP version
  • required PHP extensions
  • PHP upload limit
  • PHP POST limit
  • writable Laravel directories
  • .env.example
  • ability to create or update .env

All requirements must pass before continuing.

Step 2 - Application Setup

Configure the application URL and timezone.

For production installations, use the final public URL.

Example:

https://servers.example.com

Step 3 - Database & Redis

Enter the PostgreSQL and Redis credentials prepared earlier.

ServerList tests both connections before saving the configuration.

If a connection fails, the installer displays safe troubleshooting guidance without exposing database passwords or internal exception details.

Step 4 - Initialize Application

The installer:

  • generates the Laravel application key
  • runs the database migrations
  • loads the default application data
  • creates the public storage symlink

Do not interrupt this step.

The expected public storage link is:

public/storage -> storage/app/public

Step 5 - Administrator

Create the first ServerList administrator account.

Use a strong, unique password.

Step 6 - Finish

Complete the installation.

ServerList creates its permanent installation lock and removes the temporary installer access credentials.

After successful completion, /install is locked and should return HTTP 404.

The installer generates APP_KEY during initialization. Do not generate or replace it manually after installation: changing it can make existing encrypted data unreadable. The installer also sets the normal production application, session, cache and Redis queue settings.

10. Configure Background Services

The website can load after the installer completes, but normal ServerList operation also requires:

  • Laravel scheduler
  • persistent Redis queue worker

These are operating-system services and are intentionally not installed by the web installer.

Continue with Production Setup.

Then configure outbound email, server-ownership support, and any optional Votifier or Premium features in Administration.

11. Confirm HTTPS before public launch

Production ServerList installations should use HTTPS.

A common configuration is Nginx with Let's Encrypt and Certbot.

If HTTPS was not enabled before the installer, enable it before making the site public and make sure the application URL is the final HTTPS address.

Example:

https://servers.example.com

Do not enable Laravel debug mode on a public production website.

Troubleshooting

PHP upload limit is too low

The PHP-FPM configuration used by the website must contain at least:

upload_max_filesize = 5M
post_max_size = 10M

Restart PHP-FPM after changing these values.

Remember that PHP CLI and PHP-FPM may use different configuration files.

PostgreSQL connection fails

Check:

  • PostgreSQL is running
  • host
  • port
  • database name
  • username
  • password
  • SSL mode
  • firewall or network access when using a remote database

Redis connection fails

Check:

  • Redis is running
  • host
  • port
  • username
  • password
  • firewall or network access when using remote Redis

A local Redis server can be tested with:

redis-cli ping

The expected response is:

PONG

Uploaded images are not visible

The installer normally creates Laravel's public storage link automatically.

Check:

cd /var/www/serverlist
ls -la public/storage

The expected destination is:

storage/app/public

If repairing an existing installation where the link is missing, Laravel can create it with:

php artisan storage:link

Do not overwrite an existing unrelated public/storage path without first investigating it.

Installer cannot create or update .env

Check that the application directory and .env file are writable by the PHP-FPM user.

The .env file contains sensitive configuration and must never be directly accessible through the web server.

Backup directory requirement fails

The installer requires a protected /var/backups/serverlist directory outside the application directory. Re-run the preparation command as an administrator:

sudo bash /var/www/serverlist/scripts/prepare-backups.sh /var/www/serverlist

Do not create a world-writable backup directory or place it under the public web root. See the backup-directory section above if the command reports an ownership or unsafe-parent-directory problem.

Next Step

After the web installer is complete, follow Production Setup.

For the standard single-application VPS, that guide provides one administrator setup command which installs the worker/scheduler and all safe-update controls. Complete that step before considering deployment finished. Standard customers do not write quiescence hooks or edit sudoers/ingress barriers. The earlier backup-directory preparation is retained and rechecked by standard setup.