CloudLinux.ro
Platform

Recipes: install anything automatically when your server is created

Updated 7/17/2026

Recipes let you fully automate the setup of a new server: write a bash script once, and we run it automatically at the first boot of any server you create with that recipe. It is the same mechanism behind our one-click apps, except the script is yours.

What is a recipe

A recipe is a bash script saved in your account and executed through cloud-init at the server's first boot:

  • it runs exactly once, as root, right after the first boot;
  • it works on any operating system we offer, you pick the image at creation time;
  • everything the script prints is saved to /var/log/app-install.log on the server;
  • the install status (running / done / failed) shows on the server's page in the panel;
  • you can save up to 50 recipes, each up to 16 KB;
  • when creating a server you pick either a recipe or a one-click app, not both.

How to create a recipe

  1. Open Recipes in the control panel and click the add button.
  2. Give it a name, an optional description, and paste your bash script (no #!/bin/bash needed, we add it).
  3. When creating a new server, select the recipe in the configuration step. That's it.

Rules and tips

  • The script runs with set -e: it stops at the first failing command and the status becomes "failed". Check the log to see where it stopped.
  • Nobody is at the keyboard: use export DEBIAN_FRONTEND=noninteractive before apt-get, otherwise an interactive prompt will hang the install.
  • The server boots without waiting for the script, the install keeps running in the background for a few minutes.
  • Save generated passwords to a file on the server (for example /root/credentials.txt) instead of only printing them to the log.
  • Avoid hardcoding passwords or API keys in a recipe unless you must, anyone with access to your account can read them.

Examples

1. Base setup: useful packages, timezone and firewall

A good starting point for almost any Ubuntu/Debian server:

export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get install -y htop curl git unzip ufw fail2ban
timedatectl set-timezone Europe/Bucharest
ufw allow OpenSSH
ufw --force enable
systemctl enable --now fail2ban

2. Docker + your app in a container

Install Docker and start your own service with docker compose, swap the image for yours:

export DEBIAN_FRONTEND=noninteractive
curl -fsSL https://get.docker.com | sh
mkdir -p /opt/app && cd /opt/app
cat > docker-compose.yml <<'EOF'
services:
  web:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - '80:80'
EOF
docker compose up -d

3. Node.js app with PM2, straight from Git

Clone a public repository and run the app as a service that survives reboots:

export DEBIAN_FRONTEND=noninteractive
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs git
npm install -g pm2
git clone https://github.com/your-user/your-app.git /opt/your-app
cd /opt/your-app
npm ci --omit=dev
pm2 start npm --name app -- start
pm2 startup systemd -u root --hp /root
pm2 save

4. Hardening: new user with an SSH key, no root password logins

Replace the example public key with your own before saving the recipe:

useradd -m -s /bin/bash deploy
usermod -aG sudo deploy
echo 'deploy ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/deploy
mkdir -p /home/deploy/.ssh
echo 'ssh-ed25519 AAAA...your-public-key... user@laptop' > /home/deploy/.ssh/authorized_keys
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
systemctl restart ssh || systemctl restart sshd

Troubleshooting

  • Status "failed" on the server page, connect via SSH or the console and run cat /var/log/app-install.log; the last line shows the command that failed.
  • The install seems stuck, usually an interactive prompt (missing DEBIAN_FRONTEND=noninteractive) or a command waiting for input.
  • You want to retry the install, the script stays on the server at /root/.app-install.sh; you can fix it and run it manually.

If you would rather use something ready-made, our one-click app catalog already covers 80+ popular applications, recipes are there for everything specific to your project.

Put this guide into practice on your own VPS

EU cloud servers, billed hourly, ready in minutes, with one-click installs for dozens of apps.

See pricing