Skip to content

Installer Flags

CLI flags, environment variables, and exit codes for npx @lamalibre/create-portlama.

Usage

bash
npx @lamalibre/create-portlama [flags]

The installer runs as root on a fresh Ubuntu 24.04 server. It is completely non-interactive by default — all configuration happens later through the browser-based onboarding wizard.

Flags

FlagShortDescription
--help-hPrint help message and exit
--yes-ySkip the confirmation prompt
--skip-hardenSkip OS hardening (swap, UFW, fail2ban, SSH)
--devAllow private/non-routable IP addresses
--force-fullRun full installation even on existing installs
--uninstallPrint manual removal guide and exit

--help, -h

Prints a description of what the installer does, lists all flags, and exits with code 0. Does not modify anything on the system.

bash
npx @lamalibre/create-portlama --help

--yes, -y

Skips the interactive confirmation prompt that appears before installation begins. Useful for automated deployments or scripts where you cannot press Enter.

bash
npx @lamalibre/create-portlama --yes

Without this flag, the installer displays a banner listing all changes it will make and waits for the user to press Enter or Ctrl+C.

--skip-harden

Skips all OS hardening tasks:

  • Swap file creation (1 GB)
  • UFW firewall configuration (ports 22, 443, 9292)
  • fail2ban installation and configuration
  • SSH hardening (disabling password authentication)

Everything else (Node.js, nginx, mTLS, panel deployment) still runs.

bash
npx @lamalibre/create-portlama --skip-harden

Use this if you manage your own firewall rules, already have fail2ban configured, or are running on a platform that handles security at a different layer.

--dev

Allows the installer to run on a machine with a private or non-routable IP address (e.g., 192.168.x.x, 10.x.x.x). By default, the installer requires a public IP.

bash
npx @lamalibre/create-portlama --dev

This is useful for:

  • Testing the installer in a local VM
  • Running on a server behind a NAT (where the public IP is not directly assigned to the interface)

When --dev is active, the installer prints the detected IP with a note: (dev mode — private IP accepted).

--force-full

Forces the installer to run the complete installation pipeline, ignoring skip guards that would normally detect an existing installation. This is useful when an installation is in an inconsistent state and you want to ensure all components are fully deployed.

bash
npx @lamalibre/create-portlama --force-full

Use this if:

  • A previous installation was interrupted partway through
  • Components were manually removed and need to be reinstalled
  • You want to ensure every step runs regardless of existing state

--uninstall

Prints a step-by-step guide for manually removing Portlama from the server, then exits with code 0. Does not modify anything on the system.

bash
npx @lamalibre/create-portlama --uninstall

The printed guide covers:

  1. Stop and disable services
  2. Remove nginx configuration
  3. Remove Portlama directories (/etc/portlama/, /opt/portlama/, /var/www/portlama/)
  4. Remove the portlama system user
  5. Remove sudoers rules
  6. Remove fail2ban configuration (optional)
  7. Revert SSH hardening (optional)
  8. Revert firewall changes (optional)
  9. Remove swap file (optional)
  10. Remove Let's Encrypt certificates (optional)

See also: Uninstalling for the full documentation.

Environment Variables

VariableDefaultDescription
PORTLAMA_CONFIG/etc/portlama/panel.jsonOverride the panel config file path (panel-server)
NODE_ENVSet to development (or leave unset) to skip mTLS verification and use dev config path; set to production for production behavior (panel-server)

These environment variables affect the panel server at runtime, not the installer itself. They are listed here because they are the only environment-level configuration Portlama uses.

The installer sets these in the systemd service unit:

ini
Environment=NODE_ENV=production
Environment=CONFIG_FILE=/etc/portlama/panel.json

Note: The systemd unit sets CONFIG_FILE, but the panel server code reads PORTLAMA_CONFIG. The CONFIG_FILE variable is not used by the application. In production this has no effect because the code falls back to /etc/portlama/panel.json when PORTLAMA_CONFIG is unset and NODE_ENV=production.

Exit Codes

CodeMeaning
0Success (installation complete, or --help/--uninstall printed)
1Installation failed (error printed to stderr)

When the installer fails, it prints a boxed error message with the failure reason and a note that you can safely re-run the installer to retry:

  ┌─────────────────────────────────────────────┐
  │  Portlama installation failed.              │
  │  <error message>                            │
  │                                             │
  │  You can safely re-run this installer       │
  │  to retry.                                  │
  └─────────────────────────────────────────────┘

Requirements

The installer checks these requirements at startup and fails with a descriptive error if any are not met:

RequirementCheck
Root accessprocess.getuid() === 0
Ubuntu 24.04Reads /etc/os-release
Public IP (unless --dev)Detects via network interfaces

Installation Phases

The installer runs in two sequential phases:

Phase 1: Environment checks

  1. Verify root access
  2. Detect operating system (must be Ubuntu 24.04)
  3. Detect IP address (must be public unless --dev)

Phase 2: Installation tasks

  1. Harden operating system (skipped with --skip-harden)
    • Create 1 GB swap file
    • Configure UFW firewall (ports 22, 443, 9292)
    • Install and configure fail2ban
    • Harden SSH configuration
    • Install system dependencies (curl, openssl, nginx, certbot)
  2. Install Node.js 20 LTS
  3. Generate mTLS certificates (CA, client cert, PKCS12 bundle)
  4. Configure nginx (self-signed TLS, mTLS snippet, panel vhost on port 9292)
  5. Deploy Portlama panel (system user, directories, server, client, config, systemd, sudoers)

Idempotency

The installer is designed to be re-run safely. Skip guards prevent duplicate work:

ComponentSkip Condition
Swap fileSwap already active
UFW firewallAlready active with required ports
fail2banConfig exists and service is running
SSH hardeningSettings already correct
Node.jsAlready installed at expected version
mTLS certificatesca.key and client.p12 already exist
Panel configExisting panel.json is merged (preserves domain, email, onboarding status)

Components that are always redeployed on re-run:

  • Panel server files (/opt/portlama/panel-server/)
  • Panel client files (/opt/portlama/panel-client/)
  • Systemd service unit
  • Sudoers rules
  • nginx vhost configuration

Examples

Fresh install on a new droplet:

bash
ssh root@203.0.113.42
npx @lamalibre/create-portlama

Automated install (no confirmation prompt):

bash
npx @lamalibre/create-portlama --yes

Install without OS hardening:

bash
npx @lamalibre/create-portlama --yes --skip-harden

Test in a local VM:

bash
npx @lamalibre/create-portlama --dev

Update an existing installation:

bash
npx @lamalibre/create-portlama@latest --yes

View the uninstall guide:

bash
npx @lamalibre/create-portlama --uninstall

Quick Reference

FlagEffect
--help / -hPrint help, exit 0
--yes / -ySkip confirmation
--skip-hardenNo swap, UFW, fail2ban, SSH hardening
--devAllow private IPs
--force-fullFull install even on existing installs
--uninstallPrint removal guide, exit 0
RequirementValue
OSUbuntu 24.04
AccessRoot
IPPublic (or --dev for private)
Exit 0Success
Exit 1Failure

Released under the PolyForm Noncommercial License 1.0.0