This is an old revision of the document!
pixelfed
This tutorial provides users of Debian GNU/Linux with a roadmap for installing a Pixelfed instance. These isntructions are drawn from the Pixelfed documentation. Most steps were straightforward, however, there were a few issues not covered in their documentation, namely, special permissions for some OAUTH bits, initializing of storage, and a few other things. As with most other tutorials on this Wiki, make sure you first have a hardened VPS w/ LAMP ready to go - if not, head over to Apache Survival first and set that up. Okay, here we go!
Pixelfed requires PHP 8.4 with specific extensions for database, image processing, Redis, and more. Update your package list and install them.
cd /var/www sudo apt update sudo apt install php8.4-fpm php8.4-mysql php8.4-curl php8.4-gd php8.4-mbstring php8.4-xml php8.4-zip php8.4-bcmath php8.4-intl php8.4-redis php8.4-imagick php8.4-imap php8.4-ldap -y sudo systemctl restart php8.4-fpm
This ensures PHP-FPM is running and ready for Apache integration.
Log in to MySQL/MariaDB as root and drop any existing Pixelfed-related database to start fresh.
mysql -u root -p
Inside the MySQL shell, run:
DROP DATABASE IF EXISTS pixelfed; DROP DATABASE IF EXISTS pixel; EXIT;
Create a new database named 'pixel' with a dedicated user for security. Log in to MySQL as root again.
mysql -u root -p
Inside the MySQL shell, run:
CREATE DATABASE pixel CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS 'pixel'@'localhost' IDENTIFIED BY 'lweRt5-xmcvQW2_poRtyUG51.78345^'; GRANT ALL PRIVILEGES ON pixel.* TO 'pixel'@'localhost'; FLUSH PRIVILEGES; EXIT;
This sets up a UTF-8 compatible database optimized for Pixelfed's schema.
sudo rm -rf /var/www/pixelfed
Clone the latest development branch from the official repository. The 'dev' branch often includes fixes and features not yet in stable.
cd /var/www git clone -b dev https://github.com/pixelfed/pixelfed.git pixelfed
sudo chown -R www-data:www-data /var/www/pixelfed sudo chmod -R 775 /var/www/pixelfed/storage /var/www/pixelfed/bootstrap/cache
This prevents permission errors during runtime, such as failed uploads or cache writes.
cd /var/www/pixelfed sudo -u www-data composer install --no-dev --optimize-autoloader
This pulls in Laravel and other required packages without development tools for a production setup.
sudo nano /var/www/pixelfed/.env
Paste or update with the following content (replace placeholders if needed, e.g., passwords, domains, or mail settings):
APP_NAME="GNU/Linux Pics" APP_ENV=production APP_KEY= # Generated later APP_DEBUG=false APP_URL=https://gnulinux.pics APP_DOMAIN=gnulinux.pics ADMIN_DOMAIN=gnulinux.pics SESSION_DOMAIN=gnulinux.pics DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=pixel DB_USERNAME=pixel DB_PASSWORD=lweRt5-xmcvQW2_poRtyUG51.78345^ REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 REDIS_CLIENT=predis REDIS_SCHEME=tcp CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=redis HORIZON_PREFIX=horizon- MAIL_MAILER=smtp MAIL_HOST=mail.haacksnetworking.org MAIL_PORT=587 MAIL_USERNAME=webmaster MAIL_PASSWORD==R0undC@arg3dTer$sProduc3!inu73@4r!ied MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=webmaster@haacksnetworking.org MAIL_FROM_NAME="GNU/Linux Pics" ACTIVITY_PUB=true AP_REMOTE_FOLLOW=true AP_INBOX=true AP_OUTBOX=true AP_SHAREDINBOX=true RELAY=true OPEN_REGISTRATION=true ENFORCE_EMAIL_VERIFICATION=true PF_MAX_USERS=1000 PF_OPTIMIZE_IMAGES=true IMAGE_QUALITY=80 MAX_PHOTO_SIZE=15000 MAX_CAPTION_LENGTH=500 MAX_ALBUM_LENGTH=4 INSTANCE_DISCOVER_PUBLIC=true PF_ENABLE_CLOUD=false FILESYSTEM_CLOUD=s3 #AWS_ACCESS_KEY_ID= #AWS_SECRET_ACCESS_KEY= #AWS_DEFAULT_REGION= #AWS_BUCKET= #AWS_URL= #AWS_ENDPOINT= #AWS_USE_PATH_STYLE_ENDPOINT=false
Save and exit.
sudo -u www-data php artisan migrate --force
sudo -u www-data php artisan storage:link
Verify the symlink:
ls -l /var/www/pixelfed/public/storage
Expected output: storage → ../storage/app/public
If images fail to display after uploads, recheck permissions:
sudo chown -R www-data:www-data /var/www/pixelfed/storage sudo chmod -R 775 /var/www/pixelfed/storage #oauth bits require stronger perms sudo chmod 600 /var/www/pixelfed/storage/oauth-private.key sudo chmod 600 /var/www/pixelfed/storage/oauth-public.key
sudo -u www-data php artisan key:generate
sudo -u www-data php artisan passport:keys --force sudo -u www-data php artisan passport:install --force
sudo -u www-data php artisan horizon:install
sudo -u www-data php artisan config:cache sudo -u www-data php artisan route:cache sudo -u www-data php artisan view:cache sudo -u www-data php artisan optimize
For the non-SSL site (HTTP redirect):
sudo nano /etc/apache2/sites-enabled/000-default.conf
Paste:
<VirtualHost *:80> ServerName gnulinux.pics RewriteEngine On RewriteCond %{SERVER_NAME} =gnulinux.pics RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>
For the SSL site:
sudo nano /etc/apache2/sites-enabled/000-default-le-ssl.conf
Paste:
<VirtualHost *:443> ServerName gnulinux.pics SSLEngine on SSLCertificateFile /etc/letsencrypt/live/gnulinux.pics/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/gnulinux.pics/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf DocumentRoot /var/www/pixelfed/public <Directory /var/www/pixelfed/public> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> <FilesMatch \.php$> SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost/" </FilesMatch> LimitRequestBody 524288000 ErrorLog ${APACHE_LOG_DIR}/gnulinux-pics_error.log CustomLog ${APACHE_LOG_DIR}/gnulinux-pics_access.log combined </VirtualHost>
Ensure AllowOverride All in main config:
sudo nano /etc/apache2/apache2.conf
In the <Directory /var/www/> block ensure:
<Directory /var/www/> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory>
sudo nano /var/www/pixelfed/public/.htaccess
Paste:
Options +FollowSymLinks -Indexes RewriteEngine On RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L]
sudo nano /etc/systemd/system/pixelfed.service
Paste:
[Unit] Description=Pixelfed Horizon Queue Worker (Laravel Horizon) After=network.target apache2.service php8.4-fpm.service redis-server.service mariadb.service Wants=apache2.service php8.4-fpm.service redis-server.service mariadb.service [Service] Type=simple User=www-data Group=www-data WorkingDirectory=/var/www/pixelfed ExecStart=/usr/bin/php artisan horizon Restart=on-failure RestartSec=5s StandardOutput=journal StandardError=journal NoNewPrivileges=yes PrivateTmp=true ProtectSystem=strict ProtectHome=yes ReadWritePaths=/var/www/pixelfed/storage ReadWritePaths=/var/www/pixelfed/bootstrap/cache [Install] WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload sudo systemctl enable pixelfed.service sudo systemctl restart pixelfed.service sudo systemctl status pixelfed.service journalctl -u pixelfed.service -n 50
sudo apache2ctl configtest sudo systemctl reload apache2 sudo systemctl restart apache2 php8.4-fpm pixelfed.service redis-server
sudo -u www-data php artisan user:create
Follow prompts (example values):
redis-cli ping redis-cli keys "horizon:*" sudo systemctl status redis-server sudo systemctl status pixelfed.service journalctl -u pixelfed.service -n 50
sudo -u www-data php artisan config:show queue | grep default
curl -s https://gnulinux.pics/.well-known/nodeinfo curl -s https://gnulinux.pics/api/nodeinfo/2.0 sudo -u www-data php artisan route:list | grep -i nodeinfo
curl -I https://pixelfed.social/.well-known/nodeinfo curl -I https://mastodon.social/.well-known/nodeinfo
tail -n 100 /var/www/pixelfed/storage/logs/laravel.log | grep -i "activitypub\|federat\|outbox\|inbox\|error\|fail\|exception"
cd /var/www/pixelfed git pull origin dev sudo -u www-data composer install --no-dev --optimize-autoloader sudo -u www-data php artisan migrate --force sudo -u www-data php artisan config:cache sudo -u www-data php artisan route:cache sudo systemctl restart pixelfed.service apache2 php8.4-fpm redis-server
Always check GitHub for release notes before updating.
— oemb1905 2026/03/01 17:36