Add php repository sources
sudo curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
sudo tee /etc/apt/sources.list.d/php.sources <<EOF
Types: deb
URIs: https://packages.sury.org/php/
Suites: $(lsb_release -sc)
Components: main
Signed-By: /usr/share/keyrings/debsuryorg-archive-keyring.gpg
EOF
sudo apt update
Install php and its Apache module
sudo apt install -y php8.5-cli libapache2-mod-php8.5
Install additional modules required by Pixelfed:
sudo apt install -y php8.5-{bcmath,ctype,curl,exif,gd,iconv,imagick,intl,mbstring,mysqli,redis,tokenizer,xml,zip}
php -v:
PHP 8.5.5 (cli) (built: Apr 11 2026 06:53:33) (NTS)
Copyright (c) The PHP Group
Built by Debian
Zend Engine v4.5.5, Copyright (c) Zend Technologies
with Zend OPcache v8.5.5, Copyright (c), by Zend Technologies
sudo apt install -y php8.5-fpm
Configure a pool
sudo cp /etc/php/8.5/fpm/pool.d/www.conf /etc/php/8.5/fpm/pool.d/pixelfed.conf
sudo nano /etc/php/8.5/fpm/pool.d/pixelfed.conf
Modify the uncommented lines
; pool name ('www' here)
[pixelfed]
; Unix user/group of the child processes
user = pixelfed
group = pixelfed
; The address on which to accept FastCGI requests.
listen = /run/php/pixelfed.sock
; Set permissions for unix socket, if one is used.
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
pm.max_children = 4
Edit php.ini file
sudo nano /etc/php/8.5/apache2/php.ini
Find and modify the values of those parameters
; Maximum execution time of each script, in seconds
max_execution_time = 120
; Maximum amount of time each script may spend parsing request data
max_input_time = 120
; Maximum amount of memory a script may consume
memory_limit = 1024M
; Maximum size of POST data that PHP will accept.
post_max_size = 256M
; Maximum allowed size for uploaded files.
upload_max_filesize = 256M
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 500
post_max_size to the maximum size you expect an Instagram archive* to be, upload_max_filesize to the maximum size you expect individual Instagram photos to be, and max_file_uploads to the maximum number of photos (not posts) you'd expect an Instagram archive to contain.
Source: Pixelfed Docs
* the archive is the exported personal data file sent to you by Meta, usually as instagram-user_name-YYYY-MM-DD-hash.zip
Modify those same lines in PHP-FPM ini file
sudo nano /etc/php/8.5/fpm/php.ini
Restart PHP-FPM service
sudo systemctl restart php8.5-fpm.service
cd ~/
curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
HASH=`curl -sS https://composer.github.io/installer.sig`
php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
If Installer verified is returned, install Composer:
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer