This guide explains how to deploy a Brezel instance to a (virtual) server.
For this guide, we assume the base domain is called example.io and Brezel will be accessible under brezel.example.io.
The example IP of the server is given as 5.35.243.342.
First, create a new key pair on your local machine:
Terminal window
ssh-keygen-C"kibro"
Make sure to put those keys (public and private) in a safe and secure place.
Possibly share them with the team using a password manager (e.g. Passbolt).
Now, still on your local machine run this with the correct values to copy the public key to the server so you can log in with the private key:
Now disable password SSH based authentication in /etc/ssh/sshd_config:
Do the next steps as the kibro user on your server!
Terminal window
PasswordAuthenticationno
Make sure no file in /etc/ssh/sshd_config.d/ overrides this setting.
e.g. on Hetzner servers, you need to delete the file /etc/ssh/sshd_config.d/50-cloud-init.conf
Terminal window
sudosystemctlrestartsshd
Note, on some Ubuntu images the service is called ssh not sshd.
Use sudo systemctl restart ssh if it complains that the service sshd is not found, try this.
Set up a ufw Firewall:
This will block unwanted traffic to your server.
We allow SSH, HTTP and HTTPS traffic here. HTTP is only needed for the certificate auto (re)-generation.
Terminal window
sudoufwallowssh
sudoufwallowhttp
sudoufwallowhttps
sudoufwdisable
sudoufwenable
The disable / enable dance at the end is needed to restart the firewall with the new rules.
Install and setup CrowdSec or fail2ban:
Tools like this will block spammy requests to your server and protect it from brute force attacks.
We will use CrowdSec here, but fail2ban is a good alternative.
You fall into this category if you already have a user with sudo access on the server.
Now create a new user for your brezel instance:
Terminal window
sudoadduserbrezel
Add your brezel user to the www-data group to ensure the correct permissions in combination with the Nginx web server we’ll set up and use later on.
Terminal window
sudousermod-aGwww-databrezel
This will be the user that runs and operates the Brezel instance.
Most of the actually Brezel related setup in this guide will use this user, only some commands will require sudo and thus the other user.
Rule of thumb: If sudo is NOT used in a command, try it first with brezel, especially for any php or supervisor commands.
(If additional instructions don’t say otherwise.)
Activate fzf for your user by adding the following to your ~/.bashrc:
Terminal window
# Set up fzf key bindings and fuzzy completion
eval"$(fzf--bash)"
What to do if fzf warns about this command not available on this version
Older Ubuntu versions might not have an up to date fzf installed that have this easy install availabe.
In that case, add this to your ~/.bashrc instead:
Terminal window
# Enable fzf key bindings and fuzzy auto-completion (Debian/Ubuntu)
if [ -f /usr/share/doc/fzf/examples/key-bindings.bash ]; then
This assumes that the ondrej/php ppa is available. It should be if you followed the steps above.
ImageMagick is needed to generate thumbnails.
Due to weird issues with weird aspect ratio PDFs when generating high DPI (“original”) quality thumbnails, it is
highly recommended to use ImageMagick 7.x!
Unfortunately, the default repositories and the default php8.4-imagick package use ImageMagick 6.x, so we need to build it from source.
It is important that we have the development libraries for various formats (especially the ghostscript libs for PDF support) installed before building ImageMagick from source.
Make sure you uninstall any existing imagick version first to avoid conflicts.
Just run the following commands to be sure (some might error out, but that is fine):
If you indeed got some errors, or just want to verify that it worked, run these commands:
Terminal window
php-m|grepimagick# Should output "imagick"
php--riimagick# Should show version info and you should find "PDF" in the supported formats
Setup for SSL certificates:
There are two variants to choose from. The one we’ve always used is “Certbot”, see option 1.
However, especially when you are dealing with an installation in a closed network that is only accessible via a VPN, you might want to use the “acme.sh” variant instead.
If sudo snap install --classic certbot does not work because you are behind some kind of firewall or don’t have access to snap, you can also install certbot via sudo apt install certbot python3-certbot-nginx
In the installation process, read closely what it asks you and answer accordingly.
You want to remove the test database and disallow remote root login.
And you should set a secure password for the root user.
At this point you can already create a “brezel” database user with the necessary permissions while you are at it.
mariadb -u root -p
CREATE USER 'brezel'@'localhost' IDENTIFIED BY '<your secure password>';
GRANT ALL ON *.* TO 'brezel'@'localhost' WITH GRANT OPTION;
Configure your php-fpm settings in /etc/php/8.4/fpm/pool.d/www.conf:
pm = dynamic
pm.max_children = 300 ; Handle at max X requests at once
pm.max_requests = 1500 ; Restart worker after X requests to prevent memory leaks
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 50
pm.process_idle_timeout = 15s
You can either just paste these values at the end of the file or search for the values and change them.
Now ensure that file permissions are properly kept.
For that edit the php-fpm systemd service file using sudo systemctl edit php8.4-fpm.service
and add the following lines IN BETWEEN THE COMMENTS, as instructed:
This will create SSH keys for the brezel user and add them to GitLab as “deploy keys”.
That way, the server can pull your Brezel from the remote repository.
Switch to the brezel user.
Terminal window
su-brezel
Generate a new key pair:
Terminal window
ssh-keygen-b4096
You will be asked for a path. The default is probably fine.
Just ensure it is in the home directory of the brezel user (~/.ssh/id_<something>).
Hit enter.
You will then be asked for a passphrase.
We want no passphrase.
Leave the field empty and hit enter.
Hit enter again to confirm the empty password.
It will then output something like this:
Now, go to GitLab, to the repository of your Brezel instance and go to Settings > Repository > Deploy Keys.
We want our server to be able to read from the GitLab repository.
Paste the contents of ~/.ssh/id_<something>.pub to the Key field. Give it a meaningful title like Production [brezel.example.io].
Make sure that the instance folder is owned by brezel and www-data with both having permissions to read, write and create files.
We also need to make sure that this ownership is propagated to all subdirectories and files, including newly created files.
To do that, run the following commands:
Switch back to kibro and run:
Terminal window
# Set your project's root directory
APP_PATH="/var/www/vhosts/api.brezel.example.io"
# Set ownership to your user and the www-data group
sudochown-Rbrezel:www-data ${APP_PATH}
# Set permissions for all directories to 2775 (rwxrwx-r-x) including the setgid bit
sudofind ${APP_PATH} -typed-execchmod2775{}\;
# Set permissions for all files to 664 (rw-rw-r--)
sudofind ${APP_PATH} -typef-execchmod664{}\;
# Apply the 'setgid' bit to all directories, just in case
sudofind ${APP_PATH} -typed-execchmodg+s{}\;
# Ensure laravel specific directories are writable as per docs (technically already done, but better be safe than sorry)
sudochmod-R2775 ${APP_PATH}/storage
# Make sure acl is installed
sudoapt-getinstallacl
# Make sure existing folders that need it follow the rules that both brezel and www-data can read/write them
In general the Brezel instance will be deployed to the API subdomain.
The SPA domain will receive the contents of the minified frontend found in the dist/ folder.
This will update the permissions of the newly created auth keys to that both www-data and the brezel user can read
and write them which is needed for login to work!
After this, a basic Brezel should be up and running. For the full functionality, you need to set up additional services.
Available since:brezel/api@1.0.0
Since 1.0.0, Brezel ships with a Laravel Reverb based Brotcast server integrated!
Once you setup Supervisor, the server will be started automatically.
If you are not using the Laravel Reverb based Brotcast server, setup brotcast via Docker
Then create a docker-compose.yml file with the following content:
If you want to use event/cron, you need to set up a cronjob.
Very basically: this should trigger php bakery schedule in the directory of your instance every minute as the user that normally runs your brezel (when using nginx and following this setup it will be www-data).
How you achieve this depends on you, especially on your local setup, but on a server it makes sense to use cron.
If your brezel does stuff like creating pdfs or filling .docx templates, you need to set up the export service.
This is a container based environment that provides services like WKHtmlToPdf, Pandoc and more.
If you choose to use the Docker variant, make sure you add the kibro user to the docker group and continue this installation as the kibro user.
Adding brezel to the docker group is not recommended as it gives root-like permissions to the brezel user, which is not desired.
Supervisor handles the starting and stopping all the php-based services Brezel needs and ships with brezel/api.
That includes brotcast (if you use Reverb), the queues and so on.