Installing Pixelfed Glitch on a Raspberry Pi
Although the official Pixelfed Glitch Docker docs are fairly short, I found a few rough edges when installing it on a Raspberry Pi. This guide pulls the official instructions together with the fixes I needed along the way.
This uses the Docker version of Pixelfed Glitch, with MariaDB and Redis running as Docker containers.
Step 1. Install Docker
Pixelfed Glitch will run inside Docker containers. This means we do not need to manually install PHP, MariaDB, Redis, Node, Composer, or most of the other application dependencies on the Raspberry Pi itself.
i. Update the package list:
sudo apt update && sudo apt upgrade
ii. Install the packages needed to add Docker's repository:
sudo apt install -y ca-certificates curl
iii. Create the keyrings directory:
sudo install -m 0755 -d /etc/apt/keyrings
iv. Download Docker's GPG key:
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
v. Make the key readable:
sudo chmod a+r /etc/apt/keyrings/docker.asc
vi. Add Docker's repository:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF Types: deb URIs: https://download.docker.com/linux/debian Suites: $(. /etc/os-release && echo "$VERSION_CODENAME") Components: stable Architectures: $(dpkg --print-architecture) Signed-By: /etc/apt/keyrings/docker.asc EOF
vii. Update the package list again:
sudo apt update
viii. Install Docker and the Compose plugin:
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
ix. Check Docker is running:
sudo systemctl status docker
x. Enable Docker to start at boot:
sudo systemctl enable docker.service sudo systemctl enable containerd.service
Step 2. Allow your user to run Docker
By default, Docker commands need sudo. To run docker compose as your normal user, add your user to the docker group.
i. Create the group, if it does not already exist:
sudo groupadd docker 2>/dev/null || true
ii. Add your user to it:
sudo usermod -aG docker $USER
iii. Log out of SSH and log back in, or reboot the Pi.
iv. Test Docker without sudo:
docker run hello-world
If this works, Docker is ready.
Step 3. Create the Pixelfed Glitch directory
I installed Pixelfed Glitch under my home directory:
cd /home/pi mkdir -p pixelfed-glitch cd pixelfed-glitch
Change /home/pi to match your own username if needed.
Step 4. Download the Docker files
Download the Docker Compose file and the example environment file from the Pixelfed Glitch repository:
curl -fsSL https://raw.githubusercontent.com/pixelfed-glitch/pixelfed/develop/docker-compose.yml -o docker-compose.yml curl -fsSL https://raw.githubusercontent.com/pixelfed-glitch/pixelfed/develop/.env.docker -o .env
The docker-compose.yml file defines the containers. The .env file holds site-specific settings such as the domain name, database password, upload limits, email settings, and Docker image tags.
Step 5. Edit the environment file
Open the .env file:
nano .env
At minimum, change the following values.
Set the name of the site:
APP_NAME="My Pixelfed Site"
Set the domain name, without https:// and without a trailing slash:
APP_DOMAIN="photos.example.com"
Leave APP_URL like this:
APP_URL="https://${APP_DOMAIN}"
Leave ADMIN_DOMAIN like this:
ADMIN_DOMAIN="${APP_DOMAIN}"
Set a public contact email address:
INSTANCE_CONTACT_EMAIL="[email protected]"
Set a secure database password:
DB_PASSWORD="CHANGE_THIS_TO_A_LONG_RANDOM_PASSWORD"
If you do not plan to send email at first, you can disable mandatory email verification:
ENFORCE_EMAIL_VERIFICATION="false"
Make sure OAuth is enabled, as this is needed for Pixelfed mobile apps:
OAUTH_ENABLED="true"
Leave APP_KEY empty at this stage:
APP_KEY=
Pixelfed will generate this later. If you ever set it manually, it must be one single Laravel key, for example:
APP_KEY=base64:CHANGE_THIS_TO_ONE_VALID_KEY_ONLY
Do not paste two keys together on the same line.
Step 6. Prepare Pixelfed's storage directories
The Docker image expects several Laravel storage paths to exist. Creating them now avoids a startup error such as:
Please provide a valid cache path.
Run:
cd /home/pi/pixelfed-glitch sudo mkdir -p docker-compose-state/data/pixelfed/storage/app/public sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/cache/data sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/sessions sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/testing sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/views sudo mkdir -p docker-compose-state/data/pixelfed/storage/logs sudo mkdir -p docker-compose-state/data/pixelfed/storage/docker/lock sudo mkdir -p docker-compose-state/data/pixelfed/cache sudo chown -R 33:33 docker-compose-state/data/pixelfed/storage sudo chown -R 33:33 docker-compose-state/data/pixelfed/cache
User ID 33 is www-data, which is the user Pixelfed runs as inside the container.
Step 7. Start Pixelfed Glitch
Start the containers:
docker compose up -d
This downloads the Pixelfed Glitch, MariaDB, and Redis images, creates the containers, and starts the first-time setup.
Check the containers:
docker compose ps
You should eventually see web, worker, cron, db, and redis as Up.
To watch the logs:
docker compose logs --tail=100 --follow
If you only want the web container logs:
docker compose logs --tail=100 web
Step 8. Generate the application and OAuth keys
If the site shows a 500 error and the logs mention either of these:
No application encryption key has been specified. Invalid key supplied
run the following commands:
docker compose exec web php artisan key:generate --force docker compose exec -u www-data web php artisan passport:keys --force
Then clear and rebuild Pixelfed's cached config:
docker compose exec -u www-data web php artisan view:clear docker compose exec -u www-data web php artisan config:clear docker compose exec -u www-data web php artisan cache:clear docker compose exec -u www-data web php artisan config:cache
Restart the Pixelfed containers:
docker compose restart web worker cron
Step 9. Stop first-time setup from running again
After the first-time setup has completed and the keys have been created, edit .env again:
nano .env
Add this line:
DOCKER_APP_RUN_ONE_TIME_SETUP_TASKS="0"
This stops Pixelfed from trying to recreate encryption keys on every container start.
If this is not set, the container may restart repeatedly with an error like:
Encryption keys already exist. Use the --force option to overwrite them.
Restart the stack:
docker compose down docker compose up -d
Do not use docker compose down -v, as that removes Docker volumes.
Step 10. Check the site
Open your Pixelfed URL in a browser:
https://photos.example.com
If you are using NGINX as a reverse proxy, make sure it points to the Docker web port. In the default Pixelfed Glitch Docker file this is:
8080
So the proxy target is:
http://127.0.0.1:8080
Check the running containers:
docker compose ps
If you see a 502 error, the web container is probably not running yet, or it is restarting. Check:
docker compose logs --tail=200 web
Step 11. Create the first user
Create the first account:
docker compose exec -u www-data web php artisan user:create
Follow the prompts.
To make the user an admin:
docker compose exec -u www-data web php artisan user:admin USERNAME
To manually verify an email address:
docker compose exec -u www-data web php artisan user:verifyemail USERNAME
For example:
docker compose exec -u www-data web php artisan user:admin rob docker compose exec -u www-data web php artisan user:verifyemail rob
Step 12. Create another user
Run the same create command again:
docker compose exec -u www-data web php artisan user:create
Follow the prompts and enter the new username.
For example:
bnw
Only run the admin command for accounts that should have admin rights.
Step 13. Useful checks
Check container status:
docker compose ps
Show recent logs:
docker compose logs --tail=200 web
Check the current Pixelfed config values:
docker compose exec -u www-data web php artisan tinker --execute='
echo "app.url=".config("app.url").PHP_EOL;
echo "oauth=".(config("pixelfed.oauth_enabled") ? "true" : "false").PHP_EOL;
echo "session.domain=".config("session.domain").PHP_EOL;
'
Check the application key:
grep '^APP_KEY=' .env
A valid key should look like one single line:
APP_KEY=base64:LONG_RANDOM_STRING_HERE
Check the OAuth key files:
docker compose exec -u www-data web ls -l storage/oauth-private.key storage/oauth-public.key
Step 14. Mobile app login and 2FA
The web version worked fine for me with 2FA enabled.
The mobile app login flow was different. With 2FA enabled, the official Pixelfed app and Impressia both opened a web login pop-up, accepted the username, password, and 2FA code, then stayed in the web version inside the pop-up instead of returning to the app.
The workaround was:
- Keep 2FA enabled on the admin account.
- Use a separate non-admin account for mobile app login.
- Disable 2FA on that non-admin account before logging in to the apps.
If the web interface will not disable 2FA and clicking the green “Enabled” button only adds # to the URL, disable it from the database.
First check the 2FA column names:
docker compose exec -u www-data web php artisan tinker --execute='
print_r(array_values(array_filter(
Schema::getColumnListing("users"),
fn($c) => str_contains(strtolower($c), "two") || str_contains(strtolower($c), "2fa") || str_contains(strtolower($c), "otp")
)));
'
On my install the columns were:
2fa_enabled 2fa_secret 2fa_backup_codes 2fa_setup_at
To disable 2FA for a user called bnw:
docker compose exec -u www-data web php artisan tinker --execute='
DB::table("users")->where("username", "bnw")->update([
"2fa_enabled" => false,
"2fa_secret" => null,
"2fa_backup_codes" => null,
"2fa_setup_at" => null,
]);
echo "2FA disabled for bnw\n";
'
After that, app login worked.
Step 15. Reboot behaviour
The docker-compose.yml file uses:
restart: unless-stopped
This means the containers should come back up after a reboot, as long as Docker itself starts on boot.
Check Docker is enabled:
systemctl is-enabled docker
If needed:
sudo systemctl enable docker
After a reboot, check Pixelfed:
cd /home/pi/pixelfed-glitch docker compose ps
One thing to remember: if you run this command:
docker compose down
the containers are removed. Docker cannot restart removed containers at boot. To recreate and start them:
cd /home/pi/pixelfed-glitch docker compose up -d
Step 16. Backups
At minimum, back up the Pixelfed Glitch install directory:
/home/pi/pixelfed-glitch
This contains:
docker-compose.yml .env docker-compose-state/
The .env file contains secrets, including the database password and application key, so store backups securely.
The docker-compose-state directory contains the MariaDB data, Redis data, Pixelfed storage, and cache folders. For a live database, a proper database dump is safer than only copying files while containers are running.
A simple manual MariaDB dump can be created with:
cd /home/pi/pixelfed-glitch docker compose exec db mariadb-dump -u pixelfed -p pixelfed_prod > pixelfed_db_backup.sql
You will be prompted for the database password from .env.
Troubleshooting notes
Docker permission denied
If you see:
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
your user is not in the docker group, or the current login session has not picked up the new group membership.
Fix:
sudo usermod -aG docker $USER
Then log out and back in.
Missing cache path
If the web container restarts and logs show:
Please provide a valid cache path.
create the Laravel storage and cache folders from Step 6.
Invalid application key
If the site shows a 500 error and logs show:
Unsupported cipher or incorrect key length
check .env:
grep '^APP_KEY=' .env
The key must be one single key. It must not look like this:
APP_KEY=base64:KEY_ONE=base64:KEY_TWO
To replace it on a new install:
new_key="base64:$(openssl rand -base64 32)"
sudo sed -i.bak "s|^APP_KEY=.*|APP_KEY=${new_key}|" .env
Then clear the caches:
docker compose exec -u www-data web php artisan view:clear docker compose exec -u www-data web php artisan config:clear docker compose exec -u www-data web php artisan cache:clear docker compose exec -u www-data web php artisan config:cache docker compose restart web worker cron
First-time setup keeps running
If the web container keeps restarting and logs show:
Encryption keys already exist. Use the --force option to overwrite them.
set this in .env:
DOCKER_APP_RUN_ONE_TIME_SETUP_TASKS="0"
Then restart:
docker compose down docker compose up -d
Sources: Pixelfed Glitch Docker installation docs Pixelfed Glitch configuration docs Docker Engine Debian installation docs Docker Linux post-installation docs