How To Install Perl on Ubuntu 26.04 LTS

Install Perl on Ubuntu 26.04

If you’ve just spun up a fresh Ubuntu 26.04 LTS box and someone on your team casually mentioned “the legacy reporting script needs Perl,” you already know the drill: check what’s there, figure out what’s missing, and get it running without breaking anything else on the server. It sounds trivial until you’re three hours deep into a dependency chain because cpanm refuses to compile a module that needs libssl-dev, and the ticket is marked urgent.

Perl has this odd reputation in 2026 — everyone assumes it’s dead, yet it quietly powers backup scripts, log parsers, legacy CMS platforms, monitoring agents, and half the glue code holding together infrastructure that predates Docker. Ubuntu 26.04 LTS ships with a Perl interpreter baked into the base system because so much of the OS tooling — apt, debconf, various package maintenance scripts — still depends on it under the hood. That’s actually good news: you’re rarely starting from zero.

But “Perl is already there” and “Perl is properly set up for your workload” are two very different statements. The system Perl on Ubuntu is intentionally minimal and locked down — Canonical doesn’t want you installing random CPAN modules directly into /usr/lib/perl5 and risking a broken apt on the next dist-upgrade. That’s precisely the mistake a lot of junior admins make, and it’s the kind of thing that turns a five-minute module install into a weekend recovery job.

This guide walks through installing Perl on Ubuntu 26.04 LTS the right way — using apt for the base interpreter, isolating your development environment with Perlbrew or local::lib when you need custom versions, wiring up CPAN correctly with the SSL and build dependencies it actually needs, and hardening the whole setup for production use. Along the way, we’ll cover the errors you’re likely to hit, why they happen, and how experienced admins avoid them entirely.

Checking What’s Already Installed

Before touching apt, run a quick audit. Ubuntu 26.04 LTS typically includes Perl as part of the base install, so reinstalling blindly wastes time and can overwrite configuration you didn’t know existed.

perl -v
which perl
dpkg -l | grep -i perl

The perl -v output tells you the interpreter version and build flags. dpkg -l | grep -i perl shows every Perl-related package already on the system — this matters because Ubuntu splits Perl into perl-base (minimal, always present) and perl (the full package with standard modules). If you only see perl-base, you’re missing a chunk of the standard library, including things like CPAN.pm and Data::Dumper in some trimmed images.

Step-by-Step: Installing Perl via APT

For 95% of use cases — running existing scripts, supporting legacy tools, satisfying a dependency for another package — the distribution’s Perl package is exactly what you want. It’s patched by the security team, tracked by unattended-upgrades, and won’t drift from what the rest of the OS expects.

Step 1: Update Your Package Index

sudo apt update && sudo apt upgrade -y

Never skip this. Running apt install against a stale index on a freshly provisioned VM is one of the most common causes of “package not found” errors that have nothing to do with the package actually being unavailable.

Step 2: Install the Full Perl Package

sudo apt install -y perl

This pulls in perl-base, perl-modules-5.4x (version number depends on the point release shipped with 26.04), and the interpreter binary itself. On most 26.04 images this is already satisfied, and apt will simply report the package as up to date.

Step 3: Verify the Installation

perl -v
perl -V

Lowercase -v gives you the short version banner; uppercase -V dumps the full build configuration — compiler flags, @INC paths, install prefixes. Get comfortable reading -V output early, because when a module fails to load later, this is the first place you check to confirm which @INC path Perl is actually searching.

Step 4: Install Common Supporting Packages

A bare Perl install is rarely enough for real work. These are the packages that come up constantly in production troubleshooting:

  • perl-doc — restores the perldoc command, stripped from minimal cloud images to save space
  • build-essential — provides gcc, make, and headers required to compile XS-based CPAN modules
  • libssl-dev — needed by any module doing HTTPS calls (LWP, IO::Socket::SSL)
  • libio-socket-ssl-perl — the apt-packaged version of SSL socket support, safer than compiling it yourself
  • libcrypt-dev — required by cpanm and CPAN itself for certain hashing operations
sudo apt install -y perl-doc build-essential libssl-dev libio-socket-ssl-perl libcrypt-dev

Installing these upfront saves you from the classic “half-finished cpanm install” scenario where a module compiles 80% of the way and then dies on a missing header file.

Managing Multiple Perl Versions with Perlbrew

Here’s where things get interesting for developers and anyone running modern frameworks like Dancer2, Mojolicious, or Catalyst. The system Perl on Ubuntu 26.04 is deliberately conservative — Canonical doesn’t chase the bleeding edge because too many OS scripts depend on stable behavior. If your application needs a newer Perl release, or you need to test against multiple versions simultaneously, installing directly over the system Perl is a bad idea. You will eventually break something that apt or dpkg relies on.

Perlbrew solves this by installing Perl into your home directory, completely isolated from the system interpreter.

Installing Perlbrew

curl -L https://install.perlbrew.pl | bash

Add the following line to your shell profile once installation completes:

source ~/perl5/perlbrew/etc/bashrc

Reload your shell, then confirm:

perlbrew --version

Installing a Specific Perl Version

perlbrew install perl-5.40.0

This compiles Perl from source, which takes several minutes depending on CPU allocation — on a 2 vCPU cloud instance, budget five to ten minutes. Once done:

perlbrew switch perl-5.40.0
perl -v

Perlbrew updates your shell’s PATH so that perl now points to the compiled version, without touching /usr/bin/perl. System scripts that call /usr/bin/perl explicitly remain untouched — this separation is exactly the point.

For per-project isolation without switching your whole shell environment, use:

perlbrew local perl-5.40.0

This writes a .perlrc file in the current directory, scoping the version to that project only. Handy on shared dev servers where multiple projects need conflicting Perl versions.

Setting Up CPAN Correctly

CPAN (Comprehensive Perl Archive Network) is how you install Perl modules that aren’t packaged for Ubuntu. Running it unconfigured is asking for trouble — the first-run wizard makes assumptions that don’t always match your network or permissions setup.

Initial Configuration

sudo cpan

On first run, choose the automated configuration when prompted — it handles mirror selection and basic settings reasonably well for most servers. If your server sits behind a corporate proxy, set HTTP_PROXY and HTTPS_PROXY environment variables before launching CPAN, otherwise module downloads will silently hang.

Installing cpanminus for Sanity

Most working sysadmins skip cpan entirely in favor of cpanm (cpanminus) — it’s faster, has fewer interactive prompts, and fails loudly instead of getting stuck in dependency resolution loops.

sudo apt install -y cpanminus

Then install modules directly:

cpanm Try::Tiny
cpanm DBI
cpanm DBD::mysql

Using local::lib to Avoid Root-Owned Modules

Installing CPAN modules as root, straight into system directories, is one of those habits that works fine until it doesn’t — usually right when a dist-upgrade tries to overwrite a file you manually modified. The fix is local::lib, which installs modules into your home directory instead.

cpanm --local-lib=~/perl5 local::lib
echo 'eval "$(perl -I ~/perl5/lib/perl5 -Mlocal::lib)"' >> ~/.bashrc
source ~/.bashrc

From this point on, cpanm ModuleName installs into ~/perl5 by default, and your Perl scripts pick these modules up automatically via the environment variables local::lib sets. This is the setup you want for any application server where multiple users or services need different module sets without stepping on each other.

Real-World Use Cases

Legacy CMS and hosting environments. A surprising number of shared hosting panels, older bespoke CMS platforms, and internal reporting tools still run on Perl. When migrating these to Ubuntu 26.04, the system Perl usually satisfies the requirement without any extra work — just verify the module list against the app’s documentation.

Log processing and text munging. Perl’s regex engine remains genuinely excellent for parsing Apache/Nginx logs, especially in pipelines where awk and sed start feeling limiting. A one-liner like this is still faster to write than a Python equivalent for quick log audits:

perl -ne 'print if /ERROR/' /var/log/nginx/error.log

Monitoring agent dependencies. Some older Nagios/Icinga plugins and check scripts are Perl-based. On a fresh 26.04 install, these will fail silently until you install the specific libwww-perl or libnet-snmp-perl packages the plugin expects.

Automation glue scripts. Even in a mostly Python/Bash shop, you’ll occasionally inherit a Perl script that generates config files or handles data transformation for a legacy pipeline. Rewriting it isn’t always worth the risk — sometimes the pragmatic move is just to get Perl running cleanly and leave the script alone.

Troubleshooting Common Errors

“Can’t locate Module/Name.pm in @INC”

This is the single most common Perl error you’ll encounter. It means the interpreter can’t find a required module in any of its search paths. Check where Perl is actually looking:

perl -e 'print join("\n", @INC)'

Then confirm the module is installed in one of those paths, or install it via apt (sudo apt install libmodule-name-perl) or cpanm.

CPAN Fails to Compile Modules with SSL Errors

Usually traced back to a missing libssl-dev or an outdated IO::Socket::SSL. Install the dependencies first, then retry:

sudo apt install -y libssl-dev libio-socket-ssl-perl
cpanm --force IO::Socket::SSL

“gcc: command not found” During Module Compilation

You’re missing build tools. XS-based modules (anything with C code bindings) need a compiler.

sudo apt install -y build-essential

Permission Denied Errors When Installing Modules

You’re likely running cpanm without root privileges against system directories. Either use sudo cpanm ModuleName for system-wide installs, or better, set up local::lib as described earlier so you never need root for module management.

Perlbrew Compilation Hangs or Fails

Usually a resource issue on constrained VMs. Perl compilation is CPU and I/O intensive — on a 1 vCPU / 1GB RAM instance, it can genuinely fail from OOM conditions. Add temporary swap before compiling:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Remove the swapfile afterward if it’s not part of your permanent server configuration.

Best Practices and Optimization Tips

Keep system Perl untouched. Never install CPAN modules with root privileges directly into system Perl’s library paths. Use local::lib or Perlbrew for anything beyond what apt provides. This single habit prevents most of the “why did apt break after a Perl update” incidents.

Pin module versions in production. When deploying Perl applications, use cpanfile and Carton (or cpanm --installdeps .) to lock exact module versions. Untested module upgrades breaking a production cron job at 2 AM is a preventable problem.

Disk I/O matters for CPAN builds. Compiling large modules with many dependencies generates significant temp file I/O. On servers with spinning disks or throttled cloud storage tiers, this can meaningfully slow down builds — moving /tmp to tmpfs helps if RAM allows it.

Watch memory during Perlbrew compiles. Perl’s build process forks multiple compiler processes when -j flags are used for parallel builds. On memory-constrained instances, limit parallelism explicitly:

perlbrew install perl-5.40.0 -j 1

Automate module dependency installs. For repeatable deployments, script your module installation with a cpanfile rather than manually running cpanm commands one by one. This also documents your dependency tree for the next admin who inherits the server.

Firewall and network hardening still apply. CPAN reaches out to external mirrors over HTTPS — make sure outbound rules on your firewall (ufw, iptables, or cloud security groups) permit HTTPS traffic if CPAN installs are timing out mysteriously.

sudo ufw allow out 443/tcp

Keep the system Perl patched via unattended-upgrades. Security patches for Perl (particularly around module vulnerabilities in widely-used packages like libwww-perl) ship through the normal Ubuntu security channel. Make sure unattended-upgrades is enabled and actually running:

sudo systemctl status unattended-upgrades

Restrict file permissions on Perl scripts handling sensitive data. Scripts that touch credentials, API keys, or database connections should never be world-readable. A quick audit:

find /opt/scripts -name "*.pl" -perm -o+r

Tighten anything that shows up with chmod 750.

r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts