Pixelfed is a free and ethical, open-source, federated (i.e., decentralized) social image sharing platform. As Mastodon is to Twitter, so Pixelfed is to Instagram. Pixelfed uses the ActivityPub protocol, allowing users to interact with other users (on other servers) within the protocol, such as Mastodon, PeerTube, and Friendica, making Pixelfed a part of the Fediverse.
Much like Mastodon, Pixelfed implements chronological timelines with no implementation of content manipulation algorithms and is privacy-focused with no third party analytics or tracking. It only allows users over 16 years old to use.
You may also have realized that since Pixelfed is federated, users on your instance can follow, comment, and interact with users on any other instance!
Why /var/data/runtime/pixelfed and not just /var/data/pixelfed?
The data won't be able to be backed up by a regular filesystem backup, because it'll be in use. We still need to store it somewhere though, so we use /var/data/runtime, which is excluded from automated backups. See Data Layout for details.
Setup Pixelfed environment
Create /var/data/config/pixelfed/pixelfed.env something like the example below.. (see the official documentation for a list of all possible variables and details)
/var/data/config/pixelfed/pixelfed.env
## CryptoAPP_KEY=## General SettingsAPP_NAME="Pixelfed Prod"APP_ENV=productionAPP_DEBUG=falseAPP_URL=https://pixelfed.example.comAPP_DOMAIN="pixelfed.example.com"ADMIN_DOMAIN="pixelfed.example.com"SESSION_DOMAIN="pixelfed.example.com"OPEN_REGISTRATION=trueENFORCE_EMAIL_VERIFICATION=falsePF_MAX_USERS=1000OAUTH_ENABLED=trueAPP_TIMEZONE=UTCAPP_LOCALE=en## Pixelfed TweaksLIMIT_ACCOUNT_SIZE=trueMAX_ACCOUNT_SIZE=1000000MAX_PHOTO_SIZE=15000MAX_AVATAR_SIZE=2000MAX_CAPTION_LENGTH=500MAX_BIO_LENGTH=125MAX_NAME_LENGTH=30MAX_ALBUM_LENGTH=4IMAGE_QUALITY=80PF_OPTIMIZE_IMAGES=truePF_OPTIMIZE_VIDEOS=trueADMIN_ENV_EDITOR=falseACCOUNT_DELETION=trueACCOUNT_DELETE_AFTER=falseMAX_LINKS_PER_POST=0## Instance#INSTANCE_DESCRIPTION=INSTANCE_PUBLIC_HASHTAGS=false#INSTANCE_CONTACT_EMAIL=INSTANCE_PUBLIC_LOCAL_TIMELINE=false#BANNED_USERNAMES=STORIES_ENABLED=falseRESTRICTED_INSTANCE=false## MailMAIL_DRIVER=logMAIL_HOST=smtp.mailtrap.ioMAIL_PORT=2525MAIL_FROM_ADDRESS=pixelfed@example.comMAIL_FROM_NAME="Pixelfed"MAIL_USERNAME=nullMAIL_PASSWORD=nullMAIL_ENCRYPTION=null## Databases (MySQL)DB_CONNECTION=mysqlDB_DATABASE=pixelfed_prodDB_HOST=dbDB_PASSWORD=pixelfed_db_passDB_PORT=3306DB_USERNAME=pixelfed# pass the same values to the db itselfMYSQL_DATABASE=pixelfed_prodMYSQL_PASSWORD=pixelfed_db_passMYSQL_RANDOM_ROOT_PASSWORD=trueMYSQL_USER=pixelfed## Databases (Postgres)#DB_CONNECTION=pgsql#DB_HOST=postgres#DB_PORT=5432#DB_DATABASE=pixelfed#DB_USERNAME=postgres#DB_PASSWORD=postgres## Cache (Redis)REDIS_CLIENT=phpredisREDIS_SCHEME=tcpREDIS_HOST=redis#REDIS_PASSWORD=redis_passwordREDIS_PORT=6379REDIS_DATABASE=0HORIZON_PREFIX="horizon-"## EXPERIMENTSEXP_LC=falseEXP_REC=falseEXP_LOOPS=false## ActivityPub FederationACTIVITY_PUB=falseAP_REMOTE_FOLLOW=falseAP_SHAREDINBOX=falseAP_INBOX=falseAP_OUTBOX=falseATOM_FEEDS=trueNODEINFO=trueWEBFINGER=true## S3FILESYSTEM_DRIVER=localFILESYSTEM_CLOUD=s3PF_ENABLE_CLOUD=false#AWS_ACCESS_KEY_ID=#AWS_SECRET_ACCESS_KEY=#AWS_DEFAULT_REGION=#AWS_BUCKET=#AWS_URL=#AWS_ENDPOINT=#AWS_USE_PATH_STYLE_ENDPOINT=false## HorizonHORIZON_DARKMODE=false## COSTAR - Confirm Object Sentiment Transform and ReducePF_COSTAR_ENABLED=false# MediaMEDIA_EXIF_DATABASE=false## LoggingLOG_CHANNEL=stderr## ImageIMAGE_DRIVER=imagick## Broadcasting# log driver for local developmentBROADCAST_DRIVER=log## CacheCACHE_DRIVER=redis## PurifyRESTRICT_HTML_TYPES=true## QueueQUEUE_DRIVER=redis## SessionSESSION_DRIVER=redis## Trusted ProxyTRUST_PROXIES="*"## Passport#PASSPORT_PRIVATE_KEY=#PASSPORT_PUBLIC_KEY=
Having created pixelfed.env, set it to be owned by www-data, since the subsequent steps run by the app container will modify it, inserting the APP_KEY:
Create a docker swarm config file in docker-compose syntax (v3), something like the example below.. example:
Fast-track with premix! 🚀
"Premix" is a git repository which includes necessary docker-compose and env files for all published recipes. This means that you can launch any recipe with just a git pull and a docker stack deploy 👍.
🚀 Update: Premix now includes an ansible playbook, enabling you to deploy an entire stack + recipes, with a single ansible command! (more here)
/var/data/config/pixelfed/pixelfed.yml
version:'3.5'services:db:image:mariadbrestart:unless-stopped# makes running maintenance jobs using docker-compose more reliableenv_file:/var/data/config/pixelfed/pixelfed.envnetworks:-internalvolumes:-/var/data/runtime/pixelfed/mariadb:/var/lib/mysqlenvironment:-MYSQL_ROOT_PASSWORD=yeschangemeforproductionredis:image:zknt/redisrestart:unless-stopped# makes running maintenance jobs using docker-compose more reliablenetworks:-internalhealthcheck:test:['CMD','redis-cli','ping']volumes:-/var/data/runtime/pixelfed/redis:/dataworker:image:zknt/pixelfedrestart:unless-stopped# makes running maintenance jobs using docker-compose more reliableenv_file:/var/data/config/pixelfed/pixelfed.enventrypoint:/worker-entrypoint.shnetworks:-internalhealthcheck:test:['CMD','phpartisanhorizon:status|greprunning']volumes:-/var/data/pixelfed:/var/www/storage-/var/data/config/pixelfed/pixelfed.env:/var/www/.envapp:image:zknt/pixelfedrestart:unless-stopped# makes running maintenance jobs using docker-compose more reliableenv_file:/var/data/config/pixelfed/pixelfed.envnetworks:-internal-traefik_publicvolumes:-/var/data/pixelfed:/var/www/storage-/var/data/config/pixelfed/pixelfed.env:/var/www/.envdeploy:labels:# traefik-traefik.enable=true-traefik.docker.network=traefik_public# traefikv2-"traefik.http.routers.pixelfed.rule=Host(`pixelfed.example.com`)"-"traefik.http.routers.pixelfed.entrypoints=https"-"traefik.http.services.pixelfed.loadbalancer.server.port=80"# maintenance:# image: zknt/pixelfed# restart: unless-stopped # makes running maintenance jobs using docker-compose more reliable# env_file: /var/data/config/pixelfed/pixelfed.env# entrypoint: /worker-entrypoint.sh# networks:# - internal# healthcheck:# test: ['CMD', 'php artisan horizon:status | grep running']# volumes:# - /var/data/pixelfed:/var/www/storage# - /var/data/config/pixelfed/pixelfed.env:/var/www/.envnetworks:traefik_public:external:trueinternal:driver:overlayipam:config:-subnet:172.16.17.0/2
Note
Setup unique static subnets for every stack you deploy. This avoids IP/gateway conflicts which can otherwise occur when you're creating/removing stacks a lot. See my list here.
Pre-warming
Unlike most recipes, we can't just deploy Pixelfed into Docker Swarm, and trust it to setup its database and users itself. We have to "pre-warm" it using docker-compose...
Start with docker-compose
From the /var/data/config/pixelfed directory, run the following to start up the Pixelfed environment using docker-compose. This will trigger all the initial database seeding / migration jobs, but all the containers will run on the same host (not in the swarm), so that we can perform additional admin tasks.
You'll see the logs from each of the containers scroll by, and you'll note some warnings / errors displayed before the database is ready. When you see Apache start (as below), then you know it's ready:
app_1 | ++ export APACHE_LOG_DIR=/var/log/apache2
app_1 | ++ APACHE_LOG_DIR=/var/log/apache2
app_1 | ++ export LANG=C
app_1 | ++ LANG=C
app_1 | ++ export LANG
app_1 | + /usr/local/sbin/dumb-init apache2 -DFOREGROUND
app_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.16.17.43. Set the 'ServerName' directive globally to suppress this message
Hit CTRL-C to stop the logs (but not the containers), and proceed to creating your admin user...
Create admin user
Confirm the containers are running, with:
docker-compose-fpixelfed.ymlps
You'll want to see them all up and healthy, as illustrated below:
We've setup the essestials now, everything else can be configured either via the UI or via the .env file, so tear down the docker-compose environment with:
Now hit the URL you defined in your config, and you should see your beautiful new pixelfed instance! Login with the credentials you just setup, and have fun tweaking and snapping some selfies! 1
Summary
What have we achieved? Even though we had to jump through some extra hoops to setup database and users, we now have a fully-swarmed Pixelfed instance, ready to federate with the world!
Summary
Created:
Pixelfed configured, running, and ready for selfies!
Did you receive excellent service? Want to compliment the chef? (..and support development of current and future recipes!) Sponsor me on Github / Ko-Fi / Patreon, or see the contribute page for more (free or paid) ways to say thank you! 👏
Employ your chef (engage) 🤝
Is this too much of a geeky PITA? Do you just want results, stat? I do this for a living - I'm a full-time Kubernetes contractor, providing consulting and engineering expertise to businesses needing short-term, short-notice support in the cloud-native space, including AWS/Azure/GKE, Kubernetes, CI/CD and automation.
Want to know now when this recipe gets updated, or when future recipes are added? Subscribe to the RSS feed, or leave your email address below, and we'll keep you updated.