• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Installing and Configuring a Minimalist Perl Plack/PSGI Environment on Debian 12 Bookworm using Starman and Nginx

Installing and Configuring a Minimalist Perl Plack/PSGI Environment on Debian 12 Bookworm using Starman and Nginx

Prerequisites and Initial Setup

This guide assumes a fresh Debian 12 (Bookworm) installation with root or sudo privileges. We’ll focus on a minimal setup to get a Perl Plack/PSGI application running efficiently behind Nginx, managed by Starman. This approach prioritizes performance and resource utilization, making it suitable for enterprise environments where every millisecond and megabyte counts.

First, ensure your system is up-to-date:

sudo apt update && sudo apt upgrade -y

Next, install essential build tools and Perl modules:

sudo apt install -y build-essential perl libplack-perl libstarman-perl nginx curl

Developing a Minimal Plack/PSGI Application

For demonstration purposes, we’ll create a simple “Hello, World!” PSGI application. This application will respond to any request with a plain text message. This serves as a baseline to verify our environment.

Create a directory for your application and a file named app.psgi:

sudo mkdir -p /srv/perl/myapp
sudo nano /srv/perl/myapp/app.psgi

Paste the following Perl code into app.psgi:

#!/usr/bin/perl
use strict;
use warnings;

my $app = sub {
    my $env = shift;
    return [
        '200 OK',
        [ 'Content-Type' => 'text/plain' ],
        [ "Hello from Minimal Plack/PSGI on Debian 12!" ],
    ];
};

$app; # PSGI applications return the application subroutine

Configuring Starman as the PSGI Server

Starman is a high-performance Perl PSGI server. We will configure it to run our application in the background, listening on a local port that Nginx will proxy to. Using a socket is generally preferred for performance and security over a TCP port, but for simplicity in this initial setup, we’ll use a TCP port.

Create a systemd service file for Starman to manage the application lifecycle:

sudo nano /etc/systemd/system/myapp.service

Add the following content to the service file. Adjust the user and group if necessary for your deployment.

[Unit]
Description=My Minimal Plack/PSGI Application
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/srv/perl/myapp
ExecStart=/usr/bin/starman --port 5000 --workers 4 --pid /run/myapp.pid /srv/perl/myapp/app.psgi
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Explanation of Starman options:

  • --port 5000: Starman will listen on TCP port 5000.
  • --workers 4: We’re starting with 4 worker processes. This should be tuned based on your server’s CPU cores (typically 2x CPU cores).
  • --pid /run/myapp.pid: Specifies the PID file location.
  • /srv/perl/myapp/app.psgi: The path to our PSGI application file.

Now, enable and start the Starman service:

sudo systemctl daemon-reload
sudo systemctl enable myapp.service
sudo systemctl start myapp.service
sudo systemctl status myapp.service

Verify that Starman is running and listening on port 5000:

sudo ss -tulnp | grep 5000

You should see output indicating a process listening on 0.0.0.0:5000.

Configuring Nginx as a Reverse Proxy

Nginx will act as the public-facing web server, handling incoming HTTP requests and forwarding them to the Starman process. This setup provides benefits like SSL termination, load balancing (if multiple Starman instances were used), static file serving, and request buffering.

Create a new Nginx server block configuration file:

sudo nano /etc/nginx/sites-available/myapp

Paste the following Nginx configuration. Replace your_domain.com with your actual domain name or IP address.

server {
    listen 80;
    server_name your_domain.com; # Or your server's IP address

    location / {
        proxy_pass http://127.0.0.1:5000;
        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_redirect off;
    }

    # Optional: Serve static files directly from Nginx for better performance
    # location /static/ {
    #     alias /srv/perl/myapp/static/;
    #     expires 30d;
    #     access_log off;
    # }
}

Explanation of Nginx directives:

  • listen 80;: Nginx listens on port 80 for HTTP traffic.
  • server_name your_domain.com;: Specifies which domain this server block should respond to.
  • location / { ... }: This block handles all requests.
  • proxy_pass http://127.0.0.1:5000;: Forwards requests to Starman listening on localhost:5000.
  • proxy_set_header ...: Passes important client information to the backend application.

Enable the Nginx site and test the configuration:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

If nginx -t reports successful syntax, reload Nginx. If you encounter errors, carefully review the configuration file for typos or syntax mistakes.

Testing the Environment

With Nginx configured and Starman running, you should now be able to access your application via your server’s domain name or IP address. Use curl to test from the server itself or from another machine.

From your local machine or another server:

curl http://your_domain.com

You should receive the following output:

Hello from Minimal Plack/PSGI on Debian 12!

If you are testing directly on the server, you can use:

curl http://localhost

Production Considerations and Enhancements

This setup provides a functional minimalist environment. For production deployments, consider the following enhancements:

  • SSL/TLS Configuration: Secure your application by configuring Nginx to handle SSL/TLS termination. Obtain an SSL certificate (e.g., via Let’s Encrypt) and update the Nginx server block to listen on port 443.
  • Socket Binding for Starman: Instead of listening on a TCP port, configure Starman to bind to a Unix domain socket (e.g., --listen /run/myapp.sock). Update the Nginx proxy_pass directive accordingly (e.g., proxy_pass http://unix:/run/myapp.sock;). This is generally more performant and secure as it avoids the overhead of TCP/IP and limits access to the local filesystem. Ensure the Nginx user (typically www-data) has read/write permissions on the socket file.
  • Worker Tuning: The number of Starman workers (--workers) should be carefully tuned. A common starting point is 2x the number of CPU cores. Monitor CPU and memory usage to find the optimal balance.
  • Logging: Configure Starman and Nginx logging appropriately. Starman can log to STDOUT/STDERR which can be captured by systemd, or to specific files. Nginx logs are typically found in /var/log/nginx/.
  • Health Checks: Implement health check endpoints in your PSGI application and configure Nginx or a load balancer to monitor them.
  • Graceful Restarts: Starman supports graceful restarts, allowing workers to finish current requests before being replaced. This is crucial for zero-downtime deployments.
  • Error Handling: Implement robust error handling in your PSGI application and ensure Nginx is configured to display user-friendly error pages.

By following these steps, you establish a robust, performant, and minimalist Perl Plack/PSGI environment on Debian 12, ready to serve your web applications with efficiency and reliability.

Reader Interactions

Leave a Reply Cancel reply

You must be logged in to post a comment.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store
  • How to refactor legacy event ticket registers queries using modern WP_Query and custom Transient caching
  • Step-by-Step Guide: Offloading high-frequency member profile directories metadata writes to a Redis KV store

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (662)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • PHP (5)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (647)
  • SEO & Growth (492)
  • Server (118)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (726)
  • WordPress Theme Development (357)

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (726)
  • Debugging & Troubleshooting (662)
  • Security & Compliance (647)
  • SEO & Growth (492)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala