Installation

Cipi installs a complete Laravel-ready production stack on any Ubuntu 24.04+ VPS with a single command. The installer takes roughly 10 minutes and sets up Nginx, MariaDB, PHP, Redis, Supervisor, Fail2ban, UFW, Certbot, Deployer, and the cipi CLI itself.

During installation, the wizard asks for your SSH public key (accepted formats: ssh-rsa, ssh-ed25519, ecdsa) before any package is installed. Cipi creates a dedicated cipi Linux user for admin SSH access and applies SSH hardening: root login is disabled, cipi uses public-key only (group cipi-ssh), app users (group cipi-apps) can connect with password. Login attempts are limited to 3 with a 20-second grace period, and X11 forwarding is disabled.

The installer also generates a random 40-character root password, stores it in /etc/cipi/server.json, and displays it in the installation summary. Pasted SSH keys are automatically sanitized — comments, carriage returns, and excess whitespace are stripped before validation.

Standard installation

bash
$ wget -O - https://cipi.sh/setup.sh | bash

Non-interactive installation

For automated setups, pass your SSH public key via the SSH_PUBKEY environment variable to skip the interactive prompt:

bash
$ SSH_PUBKEY="ssh-ed25519 AAAA..." wget -O - https://cipi.sh/setup.sh | bash
If you don't have an SSH key yet, generate one with: ssh-keygen -t rsa -b 4096

AWS (root login disabled by default)

bash
$ ssh ubuntu@your-server-ip
$ sudo -s
$ wget -O - https://cipi.sh/setup.sh | bash

At the end of the installation you will see a summary screen with the SSH access details, the auto-generated root password, and the MariaDB root password. Save them immediately — they are shown only once. Credentials are stored in /etc/cipi/server.json, which — like all Cipi configuration files — is encrypted at rest using AES-256-CBC via the built-in Vault system. Credentials, SSH keys, .env files, and database dumps are protected both on disk and during transfer (via Sync encrypted archives). Cipi also enforces GDPR-compliant log retention with automatic rotation policies for application, security, and HTTP logs — see Log retention for details.

Save the SSH access details, root password, and MariaDB root password. Shown only once during installation. Credentials are stored encrypted at /etc/cipi/server.json.

Post-installation access

After installation, admin access uses public-key authentication as the cipi user (root login is disabled). App users can SSH directly with ssh myapp@server-ip and the password generated at app creation. To run cipi commands or perform any administrative task, connect as cipi and then escalate:

bash
# 1. connect to the server (key-based auth only)
$ ssh cipi@your-server-ip

# 2. escalate to root to run cipi commands
cipi@server:~$ sudo -s

# 3. now you can use all cipi commands
root@server:~# cipi status
root@server:~# cipi app list

# 4. to work as an app user, switch with su
root@server:~# su - myapp

Requirements

  • Ubuntu 24.04 LTS or higher
  • Root access (or sudo -s on AWS)
  • Ports 22, 80, and 443 open
  • A clean server — do not install Cipi on a server with an existing web stack

Cipi is tested and works on: DigitalOcean, AWS EC2, Vultr, Linode / Akamai, Hetzner, Google Cloud, OVH, Scaleway, and any KVM or bare-metal host running Ubuntu.

Quick Start

1. Create your first app

The interactive wizard asks for a username, primary domain, Git repository URL (SSH format) and branch when applicable, and PHP version. Laravel apps always require a repository; for custom apps you can leave the repository empty to host the site via SFTP only — see custom apps.

bash
$ cipi app create

Or pass all flags directly to skip interactive mode:

bash
$ cipi app create \
    --user=myapp \
    --domain=myapp.com \
    --repository=git@github.com:you/myapp.git \
    --branch=main \
    --php=8.5

At the end, Cipi prints a credentials summary — save it, shown only once — including the server's public IP address (for DNS configuration), the SSH deploy key, database credentials, a ready-to-use mariadb+ssh:// connection URL for GUI clients (TablePlus, DBeaver, Sequel Pro), webhook URL, and webhook token.

2. Add the deploy key to your Git provider

If you have configured a GitHub or GitLab token via cipi git, this step is automatic — Cipi adds the deploy key and creates the webhook for you. See Git auto-setup for details.

Otherwise, copy the ssh-ed25519 ... key shown after app creation and add it as a Deploy Key in your repository:

  • GitHub: Repository → Settings → Deploy keys → Add deploy key
  • GitLab: Repository → Settings → Repository → Deploy keys

3. Prepare your Laravel project

Cipi uses the database driver for cache, sessions, and queues. Run these once inside your Laravel project, commit, and push the generated migrations:

bash
$ php artisan cache:table
$ php artisan session:table
$ php artisan queue:table
$ php artisan migrate
Cipi automatically runs artisan migrate --force on every deploy. The cache, session, and queue tables will be created on first deploy if you commit the migrations.

4. Deploy

bash
$ cipi deploy myapp

Deployer clones your repo into a new releases/N/ directory, runs composer install --no-dev, links .env and storage/, runs migrations, runs artisan optimize, creates storage:link, swaps the current symlink atomically, and restarts queue workers. Zero downtime.

5. Install SSL

bash
$ cipi ssl install myapp

Certbot provisions a Let's Encrypt certificate, configures Nginx for HTTPS, and updates APP_URL in .env. Your Laravel app is now live on https://myapp.com.

Tech Stack

Cipi brings a complete, production-ready stack to your Ubuntu server. Here is everything that gets installed and configured:

Component Role
Ubuntu Base OS (24.04 LTS or higher)
Nginx Web server, reverse proxy, SSL termination
PHP-FPM PHP runtime (multiple versions via ondrej/php PPA)
MariaDB Relational database (drop-in MySQL replacement)
Redis In-memory store for cache, sessions, queues, broadcast
Supervisor Process manager for Laravel queue workers
Deployer Zero-downtime deployment tool
Certbot Let's Encrypt SSL certificates
UFW Firewall (ports 22, 80, 443)
Fail2ban Progressive brute-force protection with recidive jail
unattended-upgrades Automatic security patches
Composer PHP dependency manager
cipi CLI Server management and orchestration

App Structure

When you run cipi app create, Cipi creates a fully isolated environment for the app. Here is everything that gets set up:

/home/myapp/ ← isolated Linux user (chmod 750)
├── .ssh/
│   ├── id_ed25519 ← deploy key (private)
│   └── id_ed25519.pub ← deploy key (public — add to Git)
├── .deployer/
│   └── deploy.php ← Deployer config (auto-generated)
├── current -> releases/3/ ← symlink to active release
├── releases/
│   ├── 1/
│   ├── 2/
│   └── 3/ ← latest release (last 5 kept)
├── shared/
│   ├── .env ← auto-compiled by Cipi
│   └── storage/ ← persistent storage
└── logs/
    ├── nginx-access.log
    ├── nginx-error.log
    ├── php-fpm-error.log
    ├── worker-default.log
    └── deploy.log

In addition to the home directory, Cipi creates these system files:

PHP-FPM pool: /etc/php/8.5/fpm/pool.d/myapp.conf (user=myapp)
Nginx vhost:  /etc/nginx/sites-available/myapp
Supervisor:   /etc/supervisor/conf.d/myapp.conf
Crontab:      * * * * * php artisan schedule:run
MariaDB:      database 'myapp', user 'myapp'@'localhost'

The .env is auto-compiled with all credentials — database name, password, webhook token, and APP_KEY. You never have to touch it manually, but you can always edit it with cipi app env myapp.