Installing Pixelfed on Debian 11, without dying in the attempt

These are commands
<?php echo "This is code, or the content of a file!" ?>

These are notes that you should read.

What is Pixelfed?

Pixelfed is an application/service similar to Instagram, but unlike Instagram, Pixelfed is not centralized, it is free and open source.

What does it mean that it is not centralized?

Unlike other services and applications, Pixelfed is decentralized, it does not depend on a single entity and each instance is unique and independent.
Also, each Pixelfed instance can interact with other instances, since it uses open protocols.

Let’s get started!

Required packages

Before configuring everything we will install some packages necessary to make everything work, instead of installing them all together, we will do it independently to avoid any problem.


apt install git zip psmisc build-essential apache2 mariadb-server curl htop bmon mc pngquant optipng jpegoptim gifsicle ffmpeg redis

System user for Pixelfed

We will create a user for the application, we execute the following:

useradd pixelfed -m -d /www/pixelfed -s /bin/false -r -c "Pixelfed User"

We obtain a copy of Github

For this we will use the user that we have already created, we execute:

su -l pixelfed -s /bin/bash ; cd

And we execute:

git clone -b dev pixelfed

We should see something like this:

Clonando en 'pixelfed'... remote: Enumerating objects: 47808, done. remote: Total 47808 (delta 0), reused 0 (delta 0), pack-reused 47808 Recibiendo objetos: 100% (47808/47808), 44.17 MiB | 13.14 MiB/s, listo. Resolviendo deltas: 100% (30423/30423), listo.

(My system is in Spanish)

*I found a BUG!

There is a bug in the code of the version » dev 0.11.4″, this is due to the change of version of Laravel from 8 to 9. What causes the BUG is that when a file is uploaded and directories are created within «storage», these are created with permissions «0700», which prevents any user other than the owner of the directory, can not access it. To solve this I have requested a PULL, in the GitHUB repository #3825, which makes that the user with which PHP is executed at the moment creates the directories with the correct permissions.

To check if this has been corrected, we edit the file «pixelfed/config/filesystems.php».

We look for the lines:

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root'   => storage_path('app'),

We add the following lines (In red, if they are not there they must be added):

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root'   => storage_path('app'),
            'permissions' => [
                'file' => [
                    'public' => 0644,
                    'private' => 0644,
                'dir' => [
                    'public' => 0755,
                    'private' => 0755,

        'public' => [

Save the file and continue.

We stop using the user «pixelfed».

NOTE: Working Directory

The working directory can change according to each one and their preferences, in my case for the WEB applications and WEB sites, I prefer to install everything in a single directory inside the RAIZ of the disk, in my case it is the «/www» and the applications in a directory with its respective name, in this case «pixelfed».
To do this we execute this command:

mkdir /www/pixelfed/ssl -p

«-p» this option will create the parent directories if they do not exist.
«ssl» we will use this directory to store the certificates signed by Let’s Encrypt.

Configuring Apache2

We will configure the apache web server, so that it can access to «/www/pixelfed», by default the apache service has permissions to work in the directory «/var/www/», we will change this so that the service can access to «www» (this is my example, in your case it can be the directory that ).

Edit the file «/etc/apache2/apache2.conf». Look for the lines:

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted

We can change them or add:

<Directory /www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted

Configure the Virtual Host

Inside the directory «/etc/apache2/sites-available» the configurations of each virtual host are stored, we will create a new configuration called «pixelfed.conf», for example.
Considering that in this example we will use the domain «» and the working directory «/www/pixelfed/public», they are all loaded in this example.
We create the file «/etc/apache2/sites-available/pixelfed.conf» and add the following:

<VirtualHost *:80>

    DocumentRoot /www/pixelfed/pixelfed/public
    LogLevel debug
    <Directory /www/pixelfed/pixelfed/public>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted

    ErrorLog ${APACHE_LOG_DIR}/pidexfed.error.log
    CustomLog ${APACHE_LOG_DIR}/pixelfed.access.log combined
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php.pixelfed.sock|fcgi://localhost"

We activate the site by executing:

a2ensite pixelfed.conf 

And we restart the Apache service:

service apache2 restart

SSL support

This configuration example is for the service without SSL. If we need SSL, we will also create the following configuration file «/etc/apache2/sites-available/ssl.pixelfed.conf» and add the following to the file:

<VirtualHost *:443>

    DocumentRoot /www/pixelfed/pixelfed/public

    <Directory /www/pixelfed/pixelfed/public>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php.pixelfed.sock|fcgi://localhost"

    SSLCertificateFile /www/pixelfed/ssl/fullchain.cer
    SSLCertificateKeyFile /www/pixelfed/ssl/pixelfed.key
    Include /etc/apache2/conf-available/letsencrypt.conf

    ErrorLog ${APACHE_LOG_DIR}/ssl.pixelfed.error.log
    CustomLog ${APACHE_LOG_DIR}/ssl.pixelfed.access.log combined

We also create the file «/etc/apache2/conf-available/letsencrypt.conf» and add to it:

SSLEngine on

# Intermediate configuration, tweak to your needs
SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
#SSLCipherSuite         HIGH:MEDIUM:!MD5!EXP:!NULL:!LOW:!ADH
SSLHonorCipherOrder     on
SSLCompression          off

SSLOptions +StrictRequire

Before activating this configuration, we will request the signature of the certificate. The steps to do this are at the end of the document.

Sign a certificate for our domain with ACME.SH

We will download the client «», but you can use any client, I am used to this one.
You can download it from here:

Release Normal release · acmesh-official/ · GitHub

Unzip the «» in the directory of your choice, inside you will find the script «». Psociblemente we will have to register, for this we execute:

./ --register-account --insecure --force --email

And then we sign the certificate for our domain:

./ --issue -d -w /www/pixelfed/pixelfed/public --cert-file /www/pixelfed/ssl/ \
--key-file /www/pixelfed/ssl/ --ca-file /www/pixelfed/ssl/ca.cer \
--fullchain-file /www/pixelfed/ssl/fullchain.cer --force

(where should be replaced by your domain)

We will activate the Virtual Hosts in apache with the following command:

a2ensite ssl.pixelfed.conf

We will also activate the Apache «proxy» modules, which we will use to pass the PHP files from Apache and process them. We will also activate the «Rewrite» module, which is required by Pixelfed. We execute the following command to activate the modules:

a2enmod proxy* rewrite ssl 

And we restart the Apache service with the following command:

systemctl restart apache2

PHP 8.1

We add the alternative PHP repository

Repository: In order to install PHP 8.1 we will use the packages from To do this we will execute the following steps:

apt install apt-transport-https lsb-release ca-certificates

wget -O /etc/apt/trusted.gpg.d/php.gpg

sh -c 'echo "deb $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'

apt update 

Install PHP 8.1 with the following command (The repository has several versions of PHP, so we specify the version we need):

apt-get install php8.1-fpm php8.1 php8.1-common php8.1-cli php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-pgsql php8.1-curl php8.1-xml php8.1-xmlrpc php8.1-imagick php8.1-gd php8.1-mysql php8.1-cli php8.1-intl php8.1-zip php8.1-redis 

Configure PHP FPM

We will create a new PHP pool for our WEB site. For this we will create the file «/etc/php/8.1/fpm/pool.d/pixelfed.conf» and add the following content:

user = pixelfed
group = pixelfed
listen.owner = www-data = www-data
listen.mode = 0660
listen = /var/run/php.pixelfed.sock
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 20

chdir = /www/pixelfed

php_flag[display_errors] = on
php_admin_value[error_log] = /www/pixelfed/php.error.log

php_admin_flag[log_errors] = on

php_admin_value[open_basedir] = /www/pixelfed:/usr/share/:/tmp:/var/lib/php

Modify the php.ini

Edit the file «/etc/php/8.1/fpm/php.ini», find the entry «upload_max_filesize = 2M» and modify it to:

upload_max_filesize = 20M

(20 Megas is enough, this is the parameter that indicates the maximum size that a file can have. If you want to upload videos to your instance, this number should be higher).

We look for the entry «post_max_size = 8M» and modify it:

post_max_size = 20M

(It must have the same value as «upload_max_filesize»).

Save the file and continue restarting PHP-FPM service with the following command:

service php8.1-fpm restart

If there are no errors, we verify with the following command that the php is running:

pstree -cupa | grep php

We should see something like this:

  |   |-php-fpm8.1,1397,www-data
  |   |-php-fpm8.1,1398,www-data
  |   |-php-fpm8.1,1393,pixelfed
  |   |-php-fpm8.1,1394,pixelfed
  |   |-php-fpm8.1,1395,pixelfed
  |   `-php-fpm8.1,1396,pixelfed
  |           |-grep,1405 php

Create a MySQL database

We will create a database for Pixelfed called «pixelfed» (but you can create the one you want). For this as the user «root» we enter to mysql, it should not request password, since MariaDB, does not request it for the system user «root»:

:~# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 30
Server version: 10.5.15-MariaDB-0+deb11u1 Debian 11

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Once inside the MySQL client, we execute the following statement to create the database:


Now we will create a user for the application that has permissions to work in this database.

GRANT ALL ON pixelfed.* TO pixelfed@localhost IDENTIFIED BY 'the_secure_password';

Note that «the_secure_password» should be changed to a slightly more secure password.

To exit the MySQL client, you can type «exit;».

Install PHP Composer

Run the following to install the PHP composer package:

php -r "copy('', 'composer-setup.php');"

php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

php composer-setup.php

php -r "unlink('composer-setup.php');"

We move the package to finish:

mv composer.phar /usr/local/bin/composer

We finish configuring Pixelfed

We use the user «pixelfed» again, executing:

su -l pixelfed -s /bin/bash ; cd

We verify the permissions of the directories and files, execute:

find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

This will correct any errors in file and directory permissions that are not covered by Github.

Install the dependencies

(Even with the user pixelfed)

cd /www/pixelfed/pixelfed ; composer install --no-ansi --no-interaction --optimize-autoloader

Note: We may also need to update some dependencies, this can be done by executing inside the «/www/pixelfed/pixelfed» directory the following command:

composer update

We will see something like this:

Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 181 installs, 0 updates, 0 removals
  - Downloading aws/aws-crt-php (v1.0.2)
  - Downloading dasprid/enum (1.0.3)
  - Downloading bacon/bacon-qr-code (2.0.7)
  - Downloading symfony/polyfill-mbstring (v1.26.0)
  - Downloading symfony/deprecation-contracts (v3.1.1)
  - Downloading symfony/http-foundation (v6.1.7)
  - Downloading psr/http-message (1.0.1)

We copy the environment variables file:

cp .env.example .env

In this file we can change the variables of the application configuration, for this example we are interested in the following lines:

APP_KEY=                                                                                                                                                                                                                                     APP_DEBUG="false"

# Instance Configuration

# Instance URL Configuration

# Database Configuration
                                                                                                                                                                                                                                                                                                                                                                                                                                                                # ActivityPub Configuration                                                                                                                                                                                                                  ACTIVITY_PUB="true"                                                                                                                                                                                                                         AP_REMOTE_FOLLOW="true"                                                                                                                                                                                                                     AP_INBOX="true"                                                                                                                                                                                                                             AP_OUTBOX="true"                                                                                                                                                                                                                            AP_SHAREDINBOX="true"

We save and follow up.

Single-step execution

These commands must be executed with the user «pixelfed», inside the «pixelfed» folder:

su -l pixelfed -s /bin/bash; cd ; cd pixelfed

Execute these commands one by one, in case of error it will have to be investigated.

php artisan key:generate
php artisan storage:link
php artisan migrate --force
php artisan import:cities
php artisan instance:actor
php artisan passport:keys
php artisan route:cache
php artisan view:cache
php artisan config:cache

If everything went well and you have no errors, then you can create the service, this should be done as the «root» user.

We will create the file «/etc/systemd/system/pixelfed.service» with the following content:

Description=Pixelfed task queueing via Laravel Horizon

ExecStart=/usr/bin/php /www/pixelfed/pixelfed/artisan horizon


We enable the service with in the systemd with the following command:

systemctl enable --now pixelfed

Finally as the user «pixelfed», we will create a user and add one in the crontab.

First we add the user by executing the following:

php artisan user:create

We will be asked for some information, such as if we want to make you an administrator and if we want to verify your email manually, we will answer yes to everything:

Creating a new user...

 > Gonzalo

 > goxonline



 Confirm Password:

 Make this user an admin? (yes/no) [no]:
 > yes

 Manually verify email address? (yes/no) [no]:
 > yes

 Are you sure you want to create this user? (yes/no) [no]:
 > yes

Created new user!

Add the following entry to the crontab by executing «crontab -e»:

* * * * * /usr/bin/php /www/pixelfed/pixelfed/artisan schedule:run >> /dev/null 2>&1

If all goes well, enter your domain in a browser, and you should see this:

Pixelfed fresh install home page.
Pagina de inicio de Pixelfed

And that’s it!
Any problems you encounter, leave me a comment!






Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *