Akadata Linux · Version 0 Saphira

Web server

Deploy nginx with php-fpm and Certbot on Akadata Linux: virtual hosts, PHP integration, Node.js reverse proxy, Let's Encrypt TLS, and security headers.

Saphira, the Akadata Linux Version 0 mascot
Technical preview

Web server

nginx, php-fpm, and TLS

nginx is the HTTP server and reverse proxy. php-fpm runs PHP 8.5 behind it. Together they serve static files, dynamic PHP applications, and Node.js backends through a single entry point. Every configuration file is in /etc/nginx/.


Quick start

Start nginx

rc-service nginx start
rc-update add nginx
rc-status

nginx is now serving the default page on port 80. Browse to your server's IP address to confirm.

Configuration layout

/etc/nginx/
├── nginx.conf                 # Main configuration
├── mime.types                 # MIME type mappings
├── sites-available/           # Virtual host definitions
│   └── akadata.ltd.conf
└── sites-enabled/             # Symlinks to enabled virtual hosts
    └── akadata.ltd.conf -> ../sites-available/akadata.ltd.conf

Main configuration — /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 1024;
    use epoll;
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    gzip on;

    include /etc/nginx/sites-enabled/*.conf;
}

Enable a virtual host by symlinking its config from sites-available/ into sites-enabled/. Disable it by removing the symlink.


Virtual hosts

Per‑site configuration

Create one file per domain in /etc/nginx/sites-available/. Enable it with a symlink:

ln -s /etc/nginx/sites-available/akadata.ltd.conf \
    /etc/nginx/sites-enabled/akadata.ltd.conf

rc-service nginx reload

Static site

# /etc/nginx/sites-available/akadata.ltd.conf
server {
    listen 80;
    server_name akadata.ltd www.akadata.ltd;
    root /usr/local/www/akadata.ltd;
    index index.html;

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

PHP application with php-fpm

Start php-fpm first:

rc-service php-fpm start
rc-update add php-fpm
# /etc/nginx/sites-available/app.akadata.ltd.conf
server {
    listen 80;
    server_name app.akadata.ltd;
    root /usr/local/www/app;
    index index.php index.html;

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

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

Node.js reverse proxy

# /etc/nginx/sites-available/api.akadata.ltd.conf
server {
    listen 80;
    server_name api.akadata.ltd;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
    }
}

HAProxy behind nginx — layered architecture

# nginx passes to HAProxy, which distributes to backend pools
location /app/ {
    proxy_pass http://localhost:8405/;
}

Reload nginx after any configuration change. It uses a graceful reload that does not drop active connections:

rc-service nginx reload

Always test the configuration before reloading:

nginx -t
# nginx: configuration file /etc/nginx/nginx.conf test is successful

Man pages: man nginx. Full reference: nginx.org/en/docs.


TLS certificates

Certbot and Let's Encrypt

Certbot obtains free TLS certificates from Let's Encrypt and renews them automatically. It is not yet packaged as a stage4 APK; build it from source or install via pip into a virtual environment.

Install Certbot via pip

python3 -m venv /usr/local/venvs/certbot
source /usr/local/venvs/certbot/bin/activate
pip install certbot certbot-nginx
deactivate

Request a certificate — automatic nginx integration

source /usr/local/venvs/certbot/bin/activate
certbot --nginx -d akadata.ltd -d www.akadata.ltd
deactivate

This obtains a certificate, configures nginx to use it, and adds the HTTPS redirect. The certificate is stored at /etc/letsencrypt/live/akadata.ltd/.

Manual certificate — webroot method

Use this when you do not want Certbot to modify your nginx configuration:

certbot certonly --webroot \
    -w /usr/local/www/akadata.ltd \
    -d akadata.ltd -d www.akadata.ltd

# Then configure nginx manually:
# /etc/nginx/sites-available/akadata.ltd.conf
server {
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/akadata.ltd/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/akadata.ltd/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Redirect HTTP to HTTPS
    server {
        listen 80;
        server_name akadata.ltd www.akadata.ltd;
        return 301 https://$host$request_uri;
    }
}

Automatic renewal

# Certbot sets up a systemd timer or cron job. To test renewal:
source /usr/local/venvs/certbot/bin/activate
certbot renew --dry-run
deactivate

# Add a cron job for automatic renewal (runs daily at 03:00):
crontab -e
# 0 3 * * * /usr/local/venvs/certbot/bin/certbot renew --quiet --post-hook \
#     "rc-service nginx reload"

Certbot certificates are valid for 90 days. The renew command only renews certificates nearing expiry, so running it daily is safe.

Security headers

# In your server block, add these headers:
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Referrer-Policy strict-origin-when-cross-origin;

Man page: certbot --help all. Full reference: eff-certbot.readthedocs.io.