I use Kirby CMS for almost all my client sites. The following is a guide to how I run Kirby on a Digital Ocean droplet running Nginx on Ubuntu. Personally, I like being able to have full control over the server and auto deploy via Git but there are also much less complicated ways to run Kirby. This guide is more of a reminder for myself, but it could be adapted for other setups.

Create your droplet

On Digital Ocean's website click "create" → "droplets". Create a new droplet (server) with the following settings:

Ubuntu 24.10 x64
Regular SSD 1GB / 1CPU

Add your local computer's SSH key to the droplet creation page.

Initial server setup tutorial

Instructs you on how to login as root and create a new user with sudo privileges.

Follow this tutorial

Install Nginx on server and create server block

Instructs you on how to install Nginx, configure the firewall, and create a server block for your website.

→ Follow this tutorial

Install PHP and PHP packages required for Kirby

In addition to PHP, Kirby requires several packages to run. More info here. You can install PHP and the packages with the following command:

sudo apt install php8.3-fpm php8.3-mbstring php8.3-curl php8.3-gd php8.3-ctype php8.3-xml

Replace 8.3 with the version of PHP you'd like to install.

Edit your Nginx server block

Run the following to edit your server block file. Replace elliott.computer with your server block file.

sudo nano /etc/nginx/sites-available/elliott.computer

Add the following to your server block. Edit the domain and root website path to match yours. Make sure php8.3-fpm.sock is pointed to the correct PHP version you installed.

server {
    server_name elliott.computer;
    root /var/www/elliott.computer;

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Configure PHP for Kirby CMS.

You'll need to adjust a few settings in your php.ini config file. These allow for larger file uploads and avoid timeouts. The main PHP config file is located at /etc/php/8.3/fpm/php.ini. Replace 8.3 with your PHP version.

Edit php.ini by running:

sudo nano /etc/php/8.3/fpm/php.ini

You can search for these lines in the file by using control ^W (on Mac). Here are the recommended settings:

# Memory limit (Kirby recommends at least 128M)
memory_limit = 256M

# Maximum upload file size
upload_max_filesize = 100M
post_max_size = 100M

# Maximum execution time
max_execution_time = 120

Deploying your site to the server using Github actions

I've found this approach works best for me though I've heard Git hooks also work fine. Also, there's always the possibility of deploying using rsync or FTP.

On the server:

# Go to your web directory
cd /var/www/elliott.computer

# Initialize a bare Git repository
git init

# Add your GitHub repository as remote
git remote add origin git@github.com:username/repo-name.git
# On your server, generate a new SSH key
ssh-keygen -t ed25519 -C "github-actions-deploy"

# View and copy the public key
cat ~/.ssh/id_ed25519.pub

# View and copy the private key
cat ~/.ssh/id_ed25519

Add your SSH deploy key as a secret in your Github repo:

Go to 'Settings' → 'Secrets and variables' → 'Actions' and under the 'Secrets' tab add the following:

SERVER_HOST: Your server's IP/domain
SERVER_USER: Your server username
DEPLOY_KEY: The private key generated earlier

Create a new file in your repository at /.github/workflows/deploy.yml. This path has to be exactly like this.

name: Deploy to Digital Ocean Server

on:
  push:
    branches:
      - main  # Or your default branch

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Deploy to Server
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.SERVER_IP }}
        username: ${{ secrets.SERVER_USER }}
        key: ${{ secrets.DEPLOY_KEY }}
        port: ${{ secrets.SSH_PORT }}
        script: |
          cd /var/www/elliott.computer
          git pull origin main

Now your site will automatically deploy when you push to main. Additionally you could create different branches that deploy to staging.elliott.computer, etc.

Installing Kirby

In your Kirby site you'll need to enable panel.install in your site's config.php

Add the following to /site/config/config.php

return [
  'panel' =>[
    'install' => true
  ]
];

Make sure to turn this off after installing!

Changing site's ownership to www-data

It's important to change the ownership of your Kirby site to www-data. You'll then add your user to the www-data group. This allows you to edit files while giving the web server and Kirby the ability to serve/edit content.

# Add your user to www-data group
sudo usermod -a -G www-data $USER

# Set group ownership to www-data
sudo chown -R $USER:www-data /var/www/elliott.computer

You'll need to log out of SSH and back in for the group changes to take effect!

Setting files and folder permissions for Kirby

You'll need to change the folder and file permissions of your entire Kirby site otherwise you won't be able to edit files from the /panel. It's particularly important to do this to the /content folder.

Use these commands to set all files & folders to the correct permissions:

# Set directory permissions to 775 (drwxrwxr-x)
sudo find /var/www/elliott.computer -type d -exec chmod 775 {} \;

# Set file permissions to 644 (-rw-r--r--)
sudo find /var/www/elliott.computer -type f -exec chmod 644 {} \;

Navigate to http://elliott.computer/panel in the browser to complete the install.

Enabling HTTPS

→ Follow digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-22-04


Other tips

I never commit /content. I'll add /content and /media to my .gitignore. I always have a separate local and production /content. You can always sync these with rsync.

Helpful commands for Ubuntu / Nginx

# Restart PHP-FPM
sudo systemctl restart php8.3-fpm
# Restart Nginx
sudo systemctl restart nginx