Install for Pixelfed on Ubuntu 18.04 LTS

Over the last few weeks I have been researching the fediverse and all that it has to offer. One of the projects that caught my eye was Pixefed.

Over the last few weeks I have been researching the fediverse and all that it has to offer.  One of the projects that caught my eye was Pixefed. It is a picture sharing software that resembles Instagram. Here are my steps to install it on my VPS which is an Ubuntu Linux 18.04 based OS.

I found the install to be a bit of a pain, but I managed to get a test site up and running after an hour or so of hammering at it. You can think of this post as more of an add-on to the main docs to help you along the way.

The official online docs for install:
The Arch distro guide helped when I was struggling:

Pre Install

Point your fancy picture domain to your VPS.  I already had this setup, but you will need to have an A record forwarding to your server.

Email Outbound

I signed up for Mailtrap for this experiment, but was not able to get mail working during my install.  Your milage may very.  

Actual Install Time

Install all the dependencies for the software.  You need a basic LEMP or LAMP stack setup plus various things for PHP and Redis to work nicely.  Again this is on my host which already serves this site, so I have most of the software installed previously based on a LEMP stack.

From the official docs you need this software:

  • Apache (with mod_rewrite enabled) or Nginx
  • MySQL 5.6+, PostgreSQL 10+ or MariaDB 10.2.7+
  • PHP 7.2+ with the following extensions: bcmath, ctype, curl, exif, iconv, intl, json, mbstring, openssl, tokenizer, xml and zip
  • Redis for in-memory caching and background task queueing
  • ImageMagick for image processing

I have Nginx, so the config below will represent that.

In addition to the software above I needed to add the following for the PHP and Redis install:

sudo apt-get install jpegoptim optipng libpng-dev php php-bcmat redis-server imagemagick composer php-fpm php-curl php-mbstring php-mysql 

mcrypt is a PIA to install and was causing all sorts of issues until I stumbled on this Stackoverflow post. Just follow it and move on, don't ask questions, just move on:

Next I was having issues getting composer to see my DB, so after some more DuckDuckGo searches I found this to work:

composer update
composer require doctrine/dbal

MySQL DB Setup

Pixelfed needs a database to store your data.  So we create that in MySQL/MariaDB.

Note: I set the permissions to both localhost and during my DB connection issues, you may or may not need to do that.

create database pixelfed;
grant all privileges on pixelfed.* to 'pixelfed'@'' identified by 'pixelfed';
grant all privileges on pixelfed.* to 'pixelfed'@'localhost' identified by 'pixelfed';
flush privileges;

User group Permissions

Your pixelfed user will need to access the directory and files, so we add that user to the www-data group.  

Note: You can use whatever user you want, I am using something different, but the official docs has you create a 'pixelfed' user and run with it.

usermod -aG pixelfed www-data
usermod -aG redis pixelfed
usermod -aG redis www-data

Permissions on web folder

chown -R pixelfed:pixelfed .
find . -type d -exec chmod 775 {} ;
find . -type f -exec chmod 664 {} ;
chmod g+s .

NGINX  host config

Point the web host to your directory that you configured above.

Note: Hopefully you walked through the LetsEncrypt section of the official docs. My test domain already was setup for TLS, so I just pointed the config at my certs.

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    root /opt/pixelfed/public;  <-- POINTING TO THE PUBLIC DIRECTORY

    ssl_certificate /etc/nginx/ssl/;
    ssl_certificate_key /etc/nginx/ssl/;

    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;

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

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        try_files $fastcgi_script_name =404;
        fastcgi_pass unix:/run/php/php7.2-fpm.sock; # make sure this is correct
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # or $request_filename

    location ~ /\.(?!well-known).* {
        deny all;

server {                                             # Redirect http to https
    server_name pixelfed.example;                    # change this to your fqdn
    listen 80;
    listen [::]:80;
    return 301 https://$host$request_uri;

The actual Install

You should be pretty good to go for the rest of the install docs.

Clone the code to a directory, copy the env file and edit it to your liking. Run the PHP Artisan commands, and hopefully it all works.

After I was able to get the site up and running I created a few test users manually using the Artisan commands.

Due to my email config not working I forced the user creation and manually verified the email. If you get email working you probably don't need to do this.

php artisan user:create
Creating a new user...

 > user03

 > user03



 Confirm Password:

 Make this user an admin? (yes/no) [no]:
 > no

 Manually verify email address? (yes/no) [no]:
 > yes

 Are you sure you want to create this user? (yes/no) [no]:
 > yes

Created new user!

I am just using the Artisan Queue Worker and Horizon in a screen session as this was a test. I'd probably go about setting up systemd for these things, but I am not keeping the experiment running after this post.

So to run your site you pop these command into a screen session and have fun:

php artisan horizon
php artisan queue:work

I hope this gets you through the install just a bit easier and you can migrate your way from centralized big tech companies to your very own services.

Purge and Flow