Pixelfed

󰃭 2024-10-24

Install Pixelfed on Debian (Bookworm)

Prerequisites

Install dependencies.

apt install -y php-bcmath php-curl exif php-gd php8.2-common php-intl php-json php-mbstring libcurl4-openssl-dev php-redis php-tokenizer php-xml php-zip php-pgsql php-fpm composer

Set the following upload limits for PHP processes.

post_max_size = 2G
file_uploads = On
upload_max_filesize = 2G
max_file_uploads = 20
max_execution_time = 1000

Create the PostgreSQL database:

sudo -u postgres psql
CREATE USER pixelfed CREATEDB;
CREATE DATABASE pixelfed;
GRANT ALL PRIVILEGES ON DATABASE pixelfed TO pixelfed;
\q

Create dedicated pixelfed user.

useradd -rU -s /bin/bash pixelfed

Configure PHP-FPM pool and socket.

cd /etc/php/8.2/fpm/pool.d/
cp www.conf pixelfed.conf

Edit /etc/php/8.2/fpm/pool.d/pixelfed.conf.

; use the username of the app-user as the pool name, e.g. pixelfed
[pixelfed]
user = pixelfed
group = pixelfed
; to use a tcp socket, e.g. if running php-fpm on a different machine than your app:
;    (note that the port 9001 is used, since php-fpm defaults to running on port 9000;)
;    (however, the port can be whatever you want)
; listen = 127.0.0.1:9001;
;    but it's better to use a socket if you're running locally on the same machine:
listen = /run/php-fpm/pixelfed.sock
listen.owner = caddy
listen.group = caddy
listen.mode = 0660
; [...]

Installation

Setup Pixelfed files

Download the source from GitHub.

cd /usr/share/caddy
git clone -b dev https://github.com/pixelfed/pixelfed.git pixelfed

Set correct permissions.

cd pixelfed
chown -R pixelfed:pixelfed .
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

Become the pixelfed user.

su - pixelfed

Initialize PHP dependencies.

composer update
composer install --no-ansi --no-interaction --optimize-autoloader

Configure environment variables

cp .env.example .env

Edit /usr/share/caddy/pixelfed/.env.

APP_NAME="hyperreal's Pixelfed"
APP_DEBUG="false"
APP_URL="https://pixelfed.hyperreal.coffee"
APP_DOMAIN="pixelfed.hyperreal.coffee"
ADMIN_DOMAIN="pixelfed.hyperreal.coffee"
SESSION_DOMAIN="pixelfed.hyperreal.coffee"
DB_CONNECTION=pgsql
DB_HOST=localhost
DB_PORT=5432
DB_DATABASE=pixelfed
DB_USERNAME=pixelfed
DB_PASSWORD=<password>
REDIS_HOST=localhost
REDIS_PORT=6379
MAIL_FROM_ADDRESS=onboarding@resend.dev
MAIL_FROM_NAME=Pixelfed
MAIL_ENCRYPTION=tls
MAIL_DRIVER=smtp
MAIL_HOST=smtp.resend.com
MAIL_PORT=465
MAIL_USERNAME=resend
MAIL_PASSWORD=<resend API key>
ACTIVITY_PUB=true
AP_REMOTE_FOLLOW=true

Setting up services

These commands should only be run one time.

php artisan key:generate

Link the storage/ directory to the application.

php artisan storage:link

Run database migrations.

php artisan migrate --force

If the above command fails due to insufficient privileges, then the pixelfed database user needs permission to create tables in the public schema. When we created the database, we ran GRANT ALL PRIVILEGES ON DATABASE pixelfed TO pixelfed; in the psql shell. This granted the pixelfed database user privileges on the database itself, not on things within the database. To fix this, the pixelfed database user needs to own the database and all within it, so go back to the psql shell and run ALTER DATABASE pixelfed OWNER TO pixelfed;

See https://anonoverflow.hyperreal.coffee/questions/74110708/postgres-15-permission-denied-for-schema-public

To enable ActivityPub federation:

php artisan instance:actor

To have routes cached, run the following commands now, and whenever the source code changes or if you change routes.

php artisan route:cache
php artisan view:cache

Run this command whenever you change the .env file for the changes to take effect.

php artisan config:cache

Use Laravel Horizon for job queueing.

php artisan horizon:install
php artisan horizon:publish

Create a systemd service unit for Pixelfed task queueing.

[Unit]
Description=Pixelfed task queueing via Laravel Horizon
After=network.target
Requires=postgresql
Requires=php8.2-fpm
Requires=redis-server
Requires=caddy

[Service]
Type=simple
ExecStart=/usr/bin/php /usr/share/caddy/pixelfed/artisan horizon
User=pixelfed
Restart=on-failure

[Install]
WantedBy=multi-user.target

Use Cron to schedule periodic tasks. As the pixelfed user, run crontab -e.

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

Create a Caddyfile that translates HTTP web requests to PHP workers.

pixelfed.hyperreal.coffee {
    root * /usr/share/caddy/pixelfed/public

    header {
        X-Frame-Options "SAMEORIGIN"
        X-XSS-Protection "1; mode=block"
        X-Content-Type-Options "nosniff"
    }

    php_fastcgi unix//run/php/php-fpm.sock
    file_server
}

Updating Pixelfed

sudo su - pixelfed
cd /usr/share/caddy/pixelfed
git reset --hard
git pull origin dev
composer install
php artisan config:cache
php artisan route:cache
php artisan migrate --force

Enter your instance's address