Deploying Dancer Apps – The Next Generation
Dave Cross

Dave Cross @davorg

About: Geek, Fintech, SEO, Lefty. Feminist, Atheist. Skeptic. Rationalist. Secularist. Humanist. Republican (UK Meaning!). Londoner. Music lover. Writer. Genealogist.

Location:
London
Joined:
Nov 14, 2018

Deploying Dancer Apps – The Next Generation

Publish Date: May 30
0 0

Last summer, I wrote a couple of posts about my lightweight, roll-your-own approach to deploying PSGI (Dancer) web apps:

In those posts, I described how I avoided heavyweight deployment tools by writing a small, custom Perl script (app_service) to start and manage them. It was minimal, transparent, and easy to replicate.

It also wasn’t great.

What Changed?

The system mostly worked, but it had a number of growing pains:

  • It didn’t integrate with the host operating system in a meaningful way.
  • Services weren’t resilient — no automatic restarts on failure.
  • There was no logging consolidation, no dependency management (e.g., waiting for the network), and no visibility in tools like systemctl.
  • If a service crashed, I’d usually find out via curl, not journalctl.

As I started running more apps, this ad-hoc approach became harder to justify. It was time to grow up.

Enter psgi-systemd-deploy

So today (with some help from ChatGPT) I wrote psgi-systemd-deploy — a simple, declarative deployment tool for PSGI apps that integrates directly with systemd. It generates .service files for your apps from environment-specific config and handles all the fiddly bits (paths, ports, logging, restart policies, etc.) with minimal fuss.

Key benefits:

    • Declarative config via .deploy.env
    • Optional .env file support for application-specific settings
    • Environment-aware templating using envsubst
    • No lock-in — it just writes systemd units you can inspect and manage yourself
  • Safe — supports a --dry-run mode so you can preview changes before deploying

  • Convenient — includes a run_all helper script for managing all your deployed apps with one command

A Real-World Example

You may know about my Line of Succession web site (introductory talk). This is one of the Dancer apps I’ve been talking about. To deploy it, I wrote a .deploy.env file that looks like this:

WEBAPP_SERVICE_NAME=succession
WEBAPP_DESC="British Line of Succession"
WEBAPP_WORKDIR=/opt/succession
WEBAPP_USER=succession
WEBAPP_GROUP=psacln
WEBAPP_PORT=2222
WEBAPP_WORKER_COUNT=5
WEBAPP_APP_PRELOAD=1
Enter fullscreen mode Exit fullscreen mode

And optionally a .env file for app-specific settings (e.g., database credentials). Then I run:

$ /path/to/psgi-systemd-deploy/deploy.sh
Enter fullscreen mode Exit fullscreen mode

And that’s it. The app is now a first-class systemd service, automatically started on boot and restartable with systemctl.

Managing All Your Apps with run_all

Once you’ve deployed several PSGI apps using psgi-systemd-deploy, you’ll probably want an easy way to manage them all at once. That’s where the run_all script comes in.

It’s a simple but powerful wrapper around systemctl that automatically discovers all deployed services by scanning for .deploy.env files. That means no need to hard-code service names or paths — it just works, based on the configuration you’ve already provided.

Here’s how you might use it:

# Restart all PSGI apps
$ run_all restart

# Show current status
$ run_all status

# Stop them all (e.g., for maintenance)
$ run_all stop
Enter fullscreen mode Exit fullscreen mode

And if you want machine-readable output for scripting or monitoring, there’s a --json flag:

$ run_all --json is-active | jq .
[
  {
    "service": "succession.service",
    "action": "is-active",
    "status": 0,
    "output": "active"
  },
  {
    "service": "klortho.service",
    "action": "is-active",
    "status": 0,
    "output": "active"
  }
]
Enter fullscreen mode Exit fullscreen mode

Under the hood, run_all uses the same environment-driven model as the rest of the system — no surprises, no additional config files. It’s just a lightweight helper that understands your layout and automates the boring bits.

It’s not a replacement for systemctl, but it makes common tasks across many services far more convenient — especially during development, deployment, or server reboots.

A Clean Break

The goal of psgi-systemd-deploy isn’t to replace Docker, K8s, or full-featured PaaS systems. It’s for the rest of us — folks running VPSes or bare-metal boxes where PSGI apps just need to run reliably and predictably under the OS’s own tools.

If you’ve been rolling your own init scripts, cron jobs, or nohup-based hacks, give it a look. It’s clean, simple, and reliable — and a solid step up from duct tape.

➡ View the code on GitHub

The post Deploying Dancer Apps – The Next Generation first appeared on Perl Hacks.

Comments 0 total

    Add comment