Step-by-Step Guide: Deploy a Kirby CMS Website on Linode Using Nginx
Prerequisites #
Before you begin, ensure you have:
- A Linode (Akamai) account.
- SSH access to your terminal.
- Basic knowledge of Linux commands.
Step 1: Create Compute Instance #
Read: workflow.
Step 2: Set Up Nginx & PHP #
Install Nginx #
Install:
sudo apt install nginx -y
Start:
sudo systemctl start nginx
Auto start at boot:
sudo systemctl enable nginx
Verify installation:
Press Q
to exit.
sudo systemctl status nginx
Or visit: http://<public_ipv4>
Install PHP #
Install:
sudo apt install php-fpm -y
Verify PHP installation:
php -v
Check fpm.sock
PHP version:
ls /run/php/
Example: php8.3-fpm.sock
Verify if php-fpm
service is running:
Press Q
to exit.
sudo systemctl status php<version>-fpm
Example version: 8.3
Configure PHP #
Create backup:
sudo cp /etc/php/8.3/fpm/php.ini /etc/php/8.3/fpm/php.ini.bak
Open:
sudo vim /etc/php/8.3/fpm/php.ini
Modify:
max_execution_time = 60
memory_limit = 256M
post_max_size = 25M
upload_max_filesize = 25M
Configure Nginx #
Create backup:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
Edit:
sudo vim /etc/nginx/sites-available/default
Modify (uncomment to enable setting):
Make sure to remove the #
before the last }
.
server {
...
# pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php<version>-fpm.sock;
}
...
}
Test config:
sudo nginx -t
Restart:
sudo systemctl restart nginx
Verify Installation #
Create page:
sudo vim /var/www/html/test.php
Add:
<?php phpinfo(); ?>
Verify: http://<public_ipv4>/test.php
Step 3: Install PHP Extensions & ImageMagick #
Install additional packages:
sudo apt install imagemagick php-common php-curl php-gd php-imagick php-intl php-mbstring php-xml php-zip -y
Verify PHP modules:
php -m
Or: http://<public_ip4v>/test.php
Remove page:
sudo rm /var/www/html/test.php
Step 4: Install Kirby CMS Starterkit #
Create directory:
sudo mkdir -p /var/www/<name>/public_html
Example name: example.com
Download Kirby CMS starterkit:
The starterkit is perfect for testing if everything works as expected.
sudo git clone https://github.com/getkirby/starterkit /var/www/<domain>/public_html/
Step 5: Create Server Block Configuration #
Virtual host file.
Create:
sudo vim /etc/nginx/sites-available/<name>
Example name: example.com
Add:
server {
listen 80;
listen [::]:80;
server_name <public_ip4v> or <domain> <sub.domain>;
root /var/www/<name>/public_html;
index index.php; # Allow specific filetypes
rewrite ^/(content|site|kirby)/(.*)$ /error last;
rewrite ^/\.(?!well-known/) /error last;
rewrite ^/(?!app\.webmanifest)[^/]+$ /index.php last;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php<version>-fpm.sock; # Adjust PHP version
}
}
Create symbolic link to enable site:
sudo ln -s /etc/nginx/sites-available/<name> /etc/nginx/sites-enabled/
Test configuration:
sudo nginx -t
Reload Nginx:
sudo systemctl reload nginx
Step 6: Set Permissions #
Apply permissions globally to /var/www/
or individually to /var/www/<name>
.
Goal: Secure and functional permissions for web content
- Directories:
755
- Owner (
www-data
): Read, write, execute. - Group and others: Read and execute (required for Nginx to access directory contents).
- Owner (
- Files:
644
- Owner (
www-data
): Read and write. - Group and others: Read-only (Nginx only needs to read files).
- Owner (
Change owner:
Default Nginx user: www-data
. Verify: /etc/nginx/nginx.conf
sudo chown -R www-data:www-data /var/www/<name>
Set file permissions to 644
:
sudo find /var/www/<name> -type f -exec chmod 644 {} \;
Set folder permissions to 755
:
sudo find /var/www/<name> -type d -exec chmod 755 {} \;
Verify:
ll /var/www
Step 7: Test Website #
Check Headers #
200 OK
means the server successfully received and processed the request. The site is up and responding normally.
curl -I <public_ip4v>
Enable Panel #
Open:
sudo vim /var/www/<name>/public_html/site/config/config.php
Modify:
<?php
return [
'panel' => [
'install' => true
],
];
Create account: http://<public_ipv4>/panel
Security Checks #
Access to sensitive folders and files must be blocked.
The following URL's should redirect to the error page:
- Content folder:
http://<public_ipv4>/content/site.txt
- Kirby folder:
http://<public_ipv4>/kirby/bootstrap.php
- Site folder:
http://<public_ipv4>/site/config/config.php
- Hidden files and folders:
http://<public_ipv4>/git/config
Various Checks #
- Do all pages load correctly?
- Check browser developer tools (Network and Console) for errors.
- Does the Panel work (e.g. account creation)?
- Can you create, edit and delete content?
- Can you view file details (images, documents, archives) in the Panel?
- Do images load quickly?
- Can you upload images, documents and archives via the Panel?
Step 8: Upload Website #
Install #
Wipe:
sudo rm -rfv /var/www/<name>/public_html/{*,.*}
Git clone Kirby CMS plainkit:
sudo git clone https://github.com/getkirby/plainkit /var/www/<name>/public_html/
Enable Panel #
Create config folder:
sudo mkdir -p /var/www/<name>/public_html/site/config/
Open:
sudo vim /var/www/<name>/public_html/site/config/config.php
Modify:
<?php
return [
'panel' => [
'install' => true
],
];
Change owner and set permissions:
sudo chown -R www-data:www-data /var/www/<name>
sudo find /var/www/<name> -type f -exec chmod 644 {} \;
sudo find /var/www/<name> -type d -exec chmod 755 {} \;
Create account: http://<public_ipv4>/panel
Synchronise #
Temporarily set permissions to user:
Required to allow rsync
to read and write files during synchronisation.
sudo chown -R <user>:<user> /var/www/<name>
Synchronise website from local to remote:
rsync -avz --delete \
--exclude='.*' \
--exclude='/kirby' \
--exclude='/media' \
--exclude='/site/accounts' \
--exclude='/site/cache' \
--exclude='/site/sessions' \
--exclude='_.log*' \
<path_to_local_folder> \
linode-<name>:/var/www/<name>/public_html/
Reset permissions to www-data
:
sudo chown -R www-data:www-data /var/www/<name>