Preface
This guide is heavily based on Stefano Marinelli’s FreeBSD Mastodon Guide. Thank your for giving me permission to use your guide as a base!
Introduction
Pixelfed is a free and open-source image sharing social network service. The platform uses a decentralized architecture which is roughly comparable to e-mail providers, meaning user data is not stored on one central server “Server (computing)”). It uses the ActivityPub protocol, allowing users to interact with other social networks within the protocol, such as Mastodon, PeerTube, and Friendica. Pixelfed and other platforms utilizing this protocol are considered to be part of the Fediverse. Wikipedia
This guide aims to provide a comprehensive walkthrough for installing Pixelfed on a FreeBSD jail, managed by BastilleBSD. While Pixelfed documentation tends to be Linux-centric, this tutorial fills the gap for FreeBSD users.
Note: This guide describes a simple, single-jail installation. For production environments, it’s recommended to separate services (Valkey, PostgreSQL, etc.) into individual jails. This tutorial assumes a basic understanding of FreeBSD and Unix-like systems.
Prerequisites
- A FreeBSD system with BastilleBSD installed
- Basic knowledge of FreeBSD jail management
- Familiarity with command-line operations
Step 1: Creating the Jail
Let’s start by creating a new jail using BastilleBSD:
bastille create pixeltest 14.2-RELEASE 10.0.0.42 bastille0
Step 2: Configuring the Jail
As we’ll be installing PostgreSQL in the jail, we need to add some configurations to the jail’s jail.conf
:
sysvmsg=new;
sysvsem=new;
sysvshm=new;
After adding these lines, restart the jail:
bastille restart pixeltest
bastille console pixeltest
Step 3: Installing Dependencies
Now, let’s install the necessary packages:
pkg install -y php84 php84-ctype php84-bcmath php84-curl php84-exif php84-gd php84-iconv php84-intl php84-mbstring php84-tokenizer php84-xml php84-zip php84-pdo_pgsql nginx postgresql16-server postgresql16-contrib git-lite valkey php84-redis php84-pecl-redis jpegoptim optipng pngquant ffmpeg php84-composer php84-fileinfo php84-simplexml php84-pcntl php84-fileinfo php84-sodium php84-dom php84-fileinfo php84-xmlwriter php84-posix php84-pecl-imagick php84-mysqli
Step 4: Enabling and Configuring Services
Enable Valkey, Nginx, php_fpm and PostgreSQL:
service valkey enable
service nginx enable
service php_fpm enable
service postgresql enable
Valkey Configuration
For simplicity in this jail environment, we’ll disable Valkey’s protected mode. However, this is not recommended for production environments without proper security measures.
Edit /usr/local/etc/valkey.conf
and set:
protected-mode no
Important: In a production environment, ensure proper authentication and network security measures are in place before disabling protected mode.
PostgreSQL Initialization and Configuration
Initialize the PostgreSQL database:
service postgresql initdb
Modify PostgreSQL to accept connections from the jail’s services. Edit /var/db/postgres/data16/pg_hba.conf
and add:
host all all 10.0.0.42/32 trust
Note: In a production environment, consider using more restrictive authentication methods.
Start PostgreSQL and Valkey:
service postgresql start
service valkey start
Step 5: Database Setup
Create the Pixelfed database user:
sudo -u postgres psql
CREATE USER pixelfed CREATEDB;
GRANT USAGE, CREATE ON SCHEMA public TO pixelfed;
\q
Step 6: Creating the Pixelfed User
Create a dedicated user for Pixelfed:
pw add user pixelfed -m
echo 'export LC_ALL="en_US.UTF-8"' >> /home/pixelfed/.profile
Step 7: Installing Pixelfed
Switch to the Pixelfed user and install the software:
Download source via Git
su -l pixelfed
git clone -b dev https://github.com/pixelfed/pixelfed.git pixelfed # checkout dev branch into "pixelfed" folder
git checkout v0.12.4
Initialize PHP dependencies
Run composer install
to fetch the dependencies needed by Pixelfed. It is recommended to run with the following flags:
composer install --no-ansi --no-interaction --optimize-autoloader
Step 8: Pixeled Setup
Configure environment variables
Please consult the official installation guide for this Pixelfed :: Configure environment variables.
Setting up services
One-time setup tasks
One time only, you need to generate the secret APP_KEY
:
php artisan key:generate
One time only, the storage/
directory must be linked to the application:
php artisan storage:link
Database migrations must be run:
php artisan migrate --force
If you want to enable support for location data:
php artisan import:cities
If you enabled ActivityPub federation:
php artisan instance:actor
If you enabled OAuth:
php artisan passport:keys
Routes should be cached whenever the source code changes or whenever you change routes:
php artisan route:cache
php artisan view:cache
Every time you edit your .env file, you must run this command to have the changes take effect:
php artisan config:cache
Job queueing
If you want admins to be able to access the Horizon web dashboard, you will need to run the following commands:
php artisan horizon:install
php artisan horizon:publish
Scheduling periodic tasks
The task scheduler is used to run periodic commands in the background, such as media optimization, garbage collection, and other time-based tasks that should be run every once in a while.
To set up scheduled tasks using Cron:
EDITOR=nano crontab -e
Paste the following cronjob into your crontab:
* * * * * /usr/local/bin/php /home/pixelfed/pixelfed/artisan schedule:run >> /dev/null 2>&1
Step 9: Nginx and php_fpm Configuration
This example assumes that you are using a secure reverse proxy which will handle the encryption part. Nginx as well as php_fpm will run as the pixelfed user.
In case of nginx of is necessary because the upload directories are created with restrictive permissions and that can only be changed by changing the code (at which the Pixelfed developer pointed me).
user pixelfed pixelfed;
server {
listen 80;
server_name pixel.text; # change this to your fqdn
root /home/pixelfed/pixelfed/public; # path to repo/public
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header X-Forwarded-Proto https; # make it play nicely with the proxy
index index.html index.htm index.php;
charset utf-8;
client_max_body_size 15M; # or your desired limit
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-pixelfed-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # or $request_filename
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Furthermore you need to create a php_fpm configuration (in /usr/local/etc/php-fpm.d/) – e.g. pixelfed.conf
[pixelfed]
user = pixelfed
group = pixelfed
listen = /var/run/php-pixelfed-fpm.sock
listen.owner = pixelfed
listen.group = pixelfed
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Step 10: Creating FreeBSD RC Scripts
Create a file /usr/local/etc/rc.d/pixelfed containing, add execute permissions to it and enable it.
#!/bin/sh
# $FreeBSD$
# PROVIDE: pixelfed
# REQUIRE: DAEMON postgresql
# KEYWORD: shutdown
. /etc/rc.subr
name="pixelfed"
start_cmd="start"
stop_cmd="stop"
rcvar=pixelfed_enable
pidfile="/var/run/${name}.pid"
desc="Pixelfed"
load_rc_config ${name}
start() {
/bin/mkdir -p /var/run/pixelfed
/usr/sbin/chown pixelfed:pixelfed /var/run/pixelfed
/usr/bin/su pixelfed -c "export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:~/bin && cd /home/pixelfed/pixelfed && /usr/sbin/daemon -T ${name
} -P /var/run/pixelfed/${name}_supervisor.pid -p /var/run/pixelfed/${name}.pid -f -S -r /usr/local/bin/php /home/pixelfed/pixelfed/artisan horizon"
}
stop() {
/bin/kill -9 `cat /var/run/pixelfed/${name}_supervisor.pid`
/bin/kill -15 `cat /var/run/pixelfed/${name}.pid`
}
run_rc_command "$1"
chmod 755 /usr/local/etc/rc.d/pixelfed
service pixelfed enable
Conclusion
Restart the jail or start the services individually. Logs will be appended to /var/log/messages
.
You now have a functioning Mastodon instance running in a FreeBSD jail. All services are run by the “daemon” user and are supervised.
Remember to regularly update your Pixelfed instance and monitor its performance. For production environments, consider implementing additional security measures and potentially separating services into individual jails.
Enjoy your new Pixelfed instance!