Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Pixelfed Ubuntu
GUIDEInstall Guides

How to Install Pixelfed on Ubuntu 24.04 — Self-Hosted Federated Instagram Alternative

21 min read

How to Install Pixelfed on Ubuntu 24.04 — Self-Hosted Federated Instagram Alternative

Pixelfed is an open-source, federated photo-sharing platform — a sovereign alternative to Instagram built on the ActivityPub protocol. Running your own Pixelfed instance means your photos, captions, and social graph live on hardware you control, and they can still federate with millions of users across Mastodon, PeerTube, and the rest of the fediverse. This tutorial takes you from a blank Ubuntu 24.04 VPS to a production-ready Pixelfed node with TLS, a queue worker, and optional S3 media storage.

Short on time? Deploy Pixelfed on a VPS tuned for media workloads. Launch a Professional VPS and you will be ready to start the install in under two minutes.

Table of Contents

  • What is Pixelfed?
  • Why Self-Host a Federated Instagram Alternative?
  • Prerequisites
  • Step 1: Update the System
  • Step 2: Install PHP 8.3 and Required Extensions
  • Step 3: Install MariaDB and Create the Database
  • Step 4: Install Redis
  • Step 5: Install FFmpeg and ImageMagick
  • Step 6: Clone Pixelfed and Install Dependencies
  • Step 7: Configure the .env File
  • Step 8: Run Migrations and Cache Config
  • Step 9: Set Up Horizon as a Queue Worker
  • Step 10: Configure Nginx and PHP-FPM
  • Step 11: Enable TLS with Let's Encrypt
  • Step 12: Optional — Offload Media to S3
  • Step 13: Verify ActivityPub Federation
  • FAQ
  • Next Steps
  • What is Pixelfed?

    Pixelfed is a federated image-sharing server written in PHP on the Laravel framework. In a single instance you get a photo timeline, stories, collections, direct messages, hashtag discovery, and a clean mobile-friendly web UI. The defining feature is federation: Pixelfed speaks ActivityPub, the same protocol that powers Mastodon and PeerTube, so a user on your Pixelfed instance can be followed by — and interact with — anyone across the fediverse.

    Technically, a Pixelfed node is a Laravel application backed by MariaDB or PostgreSQL for durable storage, Redis for cache and queues, Horizon for background job management, FFmpeg for video transcoding, and ImageMagick for image variants. Media can live on the local filesystem or any S3-compatible object store. The whole stack runs happily on a single VPS for small to medium instances, and horizontally scales by detaching Horizon workers, the database, and object storage onto separate machines when an instance grows.

    The official project documentation at docs.pixelfed.org is the canonical reference for configuration flags, upgrade notes, and federation internals. This tutorial covers the install path; keep that page bookmarked for ongoing operations.

    Why Self-Host a Federated Instagram Alternative?

    Running your own Pixelfed instance rather than using a hosted service (or Instagram) delivers benefits that matter more every year:

    • You own your photos and metadata. No silent algorithmic demotion, no ad-based ranking, no surprise policy change that pulls your content offline. Your posts live in a database you control and remain available as long as your instance is up.
    • No ads, ever. Pixelfed has no ad system and no telemetry pipeline. A chronological timeline shows exactly what the accounts you follow posted.
    • Federation reach without platform lock-in. Users on Mastodon, Mastodon instances, PeerTube, Misskey, and other Pixelfed nodes can follow and interact with your posts using the same ActivityPub protocol. You publish once, reach many networks.
    • Full moderation control. You set the rules for your instance, choose which remote servers to federate with, and can defederate bad actors without waiting for a platform to act.
    • Predictable flat cost. A VPS that runs a healthy Pixelfed instance costs the same whether you post once a week or three times a day. No storage tier upgrades, no bandwidth surprises.
    • EU data residency. Hosting on a VPS in your jurisdiction simplifies GDPR handling because you control the full data lifecycle.
    • Image quality preserved. Pixelfed does not aggressively recompress uploads the way commercial platforms do. Photographers get a platform that respects their work.

    Pixelfed vs. Instagram at a Glance

    FeatureInstagramSelf-Hosted Pixelfed
    Monthly costFree but ad-fundedEUR 19.99/mo VPS (flat)
    Ads in timelineYesNever
    Algorithmic feedYesNo, chronological
    Export your dataLimitedFull data export any time
    Federation / cross-platform followNoYes (ActivityPub)
    Custom moderationNoYes
    Open-sourceNoYes (AGPL)
    Mobile appsOfficial onlyOfficial Pixelfed + many Mastodon clients

    Prerequisites

    Before starting make sure you have:

    • An Ubuntu 24.04 LTS VPS with root or sudo access
    • A domain name (for example pixels.example.com) with an A record pointing at the server's public IP
    • At least 8 GB RAM and 100 GB of free disk (12 GB RAM and 200 GB disk recommended)
    • SMTP credentials for sending account verification and notification emails
    • Ports 80 and 443 open on your firewall
    Recommended Plan: Professional
    >
    For a small-to-medium federated instance we recommend the Professional VPS plan:
    >
    - 6 vCPU cores
    - 12 GB RAM
    - 200 GB NVMe SSD
    - Unmetered bandwidth
    - EUR 19.99/month
    >
    This plan has enough headroom for PHP-FPM workers, Horizon queue processes, MariaDB, Redis, and image/video transcoding running side by side.

    Connect via SSH:

    bash
    ssh root@your-server-ip

    Step 1: Update the System

    Bring the server up to date and install the build utilities we will need.

    bash
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y curl wget git unzip software-properties-common ca-certificates gnupg lsb-release

    If the kernel was updated, reboot before continuing:

    bash
    sudo reboot

    Step 2: Install PHP 8.3 and Required Extensions

    Pixelfed requires PHP 8.1 or newer; we install 8.3 because it offers the best performance. Ubuntu 24.04 ships with PHP 8.3 in its default archive, but the Ondrej PPA gives access to all extension packages and future point releases.

    bash
    sudo add-apt-repository ppa:ondrej/php -y
    sudo apt update
    sudo apt install -y \
      php8.3 php8.3-fpm php8.3-cli php8.3-common \
      php8.3-mysql php8.3-redis php8.3-gd php8.3-imagick \
      php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip \
      php8.3-bcmath php8.3-intl php8.3-tokenizer php8.3-exif \
      php8.3-fileinfo php8.3-opcache

    Verify the version:

    bash
    php -v

    Expected output:

    text
    PHP 8.3.10 (cli) (built: ...)
    Copyright (c) The PHP Group
    Zend Engine v4.3.10, Copyright (c) Zend Technologies
        with Zend OPcache v8.3.10, ...

    Tune php.ini for a media application:

    bash
    sudo tee -a /etc/php/8.3/fpm/conf.d/99-pixelfed.ini > /dev/null <<EOF
    upload_max_filesize = 30M
    post_max_size = 35M
    memory_limit = 512M
    max_execution_time = 120
    EOF

    sudo systemctl restart php8.3-fpm

    Install Composer, which resolves the PHP dependencies Pixelfed declares in composer.json:

    bash
    curl -sS https://getcomposer.org/installer | php
    sudo mv composer.phar /usr/local/bin/composer
    composer --version

    Step 3: Install MariaDB and Create the Database

    bash
    sudo apt install -y mariadb-server mariadb-client
    sudo mysql_secure_installation

    Accept the defaults and set a strong root password when prompted. Create the Pixelfed database and user:

    bash
    sudo mysql -u root -p

    Inside the MariaDB prompt:

    sql
    CREATE DATABASE pixelfed CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'pixelfed'@'localhost' IDENTIFIED BY 'REPLACE_WITH_A_STRONG_PASSWORD';
    GRANT ALL PRIVILEGES ON pixelfed.* TO 'pixelfed'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;

    Keep the password handy — you'll paste it into .env in a later step.

    Step 4: Install Redis

    Redis stores Pixelfed's cache, session data, and queue backlog.

    bash
    sudo apt install -y redis-server
    sudo sed -i 's/^supervised .*/supervised systemd/' /etc/redis/redis.conf
    sudo systemctl enable --now redis-server
    redis-cli ping

    Expected output:

    text
    PONG

    Step 5: Install FFmpeg and ImageMagick

    FFmpeg handles short-video transcoding and ImageMagick generates image variants for every upload. Both must be present before Pixelfed will accept media uploads.

    bash
    sudo apt install -y ffmpeg imagemagick jpegoptim optipng pngquant
    ffmpeg -version | head -1
    convert -version | head -1

    Expected output (versions will differ):

    text
    ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2024 the FFmpeg developers
    Version: ImageMagick 6.9.12-98 Q16 ...

    ImageMagick ships with a restrictive default policy that blocks some formats. Open /etc/ImageMagick-6/policy.xml and make sure the PDF rights stay disabled but that PNG, JPEG, GIF, and WEBP all have rights="read|write".

    Step 6: Clone Pixelfed and Install Dependencies

    Create a system user so Pixelfed does not run as www-data or root, and clone the repository into /var/www/pixelfed:

    bash
    sudo useradd -r -m -d /var/www/pixelfed -s /bin/bash pixelfed
    sudo -u pixelfed git clone -b dev https://github.com/pixelfed/pixelfed.git /var/www/pixelfed
    cd /var/www/pixelfed
    sudo -u pixelfed git checkout $(git tag --sort=-creatordate | head -1)

    Install the PHP dependencies with Composer in production mode:

    bash
    sudo -u pixelfed composer install --no-dev --optimize-autoloader

    This pulls the Laravel framework, Horizon, the ActivityPub library, and everything else declared in composer.json.

    Fix ownership so the web server can read and the pixelfed user can write:

    bash
    sudo chown -R pixelfed:www-data /var/www/pixelfed
    sudo find /var/www/pixelfed -type f -exec chmod 0644 {} \;
    sudo find /var/www/pixelfed -type d -exec chmod 0755 {} \;
    sudo chmod -R ug+rwX /var/www/pixelfed/storage /var/www/pixelfed/bootstrap/cache

    Step 7: Configure the .env File

    Pixelfed reads its configuration from .env at the project root. Copy the example and edit it:

    bash
    sudo -u pixelfed cp .env.example .env
    sudo -u pixelfed php artisan key:generate
    sudo -u pixelfed nano .env

    Set the following values. Replace pixels.example.com, the database password, and SMTP settings with your own.

    ini
    APP_NAME="My Pixelfed"
    APP_ENV=production
    APP_DEBUG=false
    APP_URL=https://pixels.example.com

    DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=pixelfed DB_USERNAME=pixelfed DB_PASSWORD=REPLACE_WITH_THE_PASSWORD_YOU_SET

    REDIS_CLIENT=phpredis REDIS_SCHEME=tcp REDIS_HOST=127.0.0.1 REDIS_PORT=6379 REDIS_PASSWORD=null

    CACHE_DRIVER=redis QUEUE_DRIVER=redis SESSION_DRIVER=redis BROADCAST_DRIVER=redis

    MAIL_MAILER=smtp MAIL_HOST=smtp.your-provider.com MAIL_PORT=587 [email protected] MAIL_PASSWORD=REPLACE_WITH_SMTP_PASSWORD MAIL_ENCRYPTION=tls [email protected] MAIL_FROM_NAME="${APP_NAME}"

    ACTIVITY_PUB=true AP_REMOTE_FOLLOW=true AP_INBOX=true AP_OUTBOX=true AP_SHAREDINBOX=true

    INSTANCE_DESCRIPTION="A friendly Pixelfed instance" OPEN_REGISTRATION=false ENFORCE_EMAIL_VERIFICATION=true PF_MAX_USERS=1000

    MAX_PHOTO_SIZE=15000 MAX_ALBUM_LENGTH=4 MAX_CAPTION_LENGTH=500 IMAGE_QUALITY=80

    FILESYSTEM_CLOUD=local

    The ACTIVITY_PUB=true block is what turns on ActivityPub federation — leave it enabled unless you want a private, non-federating instance.

    Step 8: Run Migrations and Cache Config

    Apply the database schema and build Laravel's optimised caches:

    bash
    cd /var/www/pixelfed
    sudo -u pixelfed php artisan storage:link
    sudo -u pixelfed php artisan migrate --force
    sudo -u pixelfed php artisan import:cities
    sudo -u pixelfed php artisan instance:actor
    sudo -u pixelfed php artisan route:cache
    sudo -u pixelfed php artisan view:cache
    sudo -u pixelfed php artisan config:cache

    Expected tail of output:

    text
    Migration table created successfully.
    Migrating: 2018_08_08_230220_create_users_table
    Migrated:  2018_08_08_230220_create_users_table (12.45ms)
    ...
    Route cache cleared!
    Routes cached successfully!
    Configuration cache cleared!
    Configuration cached successfully!

    Any time you later change .env, re-run php artisan config:cache for the change to take effect.

    Step 9: Set Up Horizon as a Queue Worker

    Horizon is Pixelfed's supervisor for Redis-backed queues. Federated deliveries, media transcoding, email notifications, and feed fan-out are all queued jobs — without Horizon running the site appears to work but nothing happens in the background.

    Create a systemd unit:

    bash
    sudo tee /etc/systemd/system/pixelfed-horizon.service > /dev/null <<'EOF'
    [Unit]
    Description=Pixelfed Horizon Queue Worker
    After=network.target mariadb.service redis-server.service

    [Service] Type=simple User=pixelfed Group=pixelfed WorkingDirectory=/var/www/pixelfed ExecStart=/usr/bin/php artisan horizon Restart=always RestartSec=5

    [Install] WantedBy=multi-user.target EOF

    sudo systemctl daemon-reload sudo systemctl enable --now pixelfed-horizon sudo systemctl status pixelfed-horizon

    Expected status line:

    text
    Active: active (running) since Thu 2026-04-16 11:10:00 UTC; 5s ago

    Pixelfed also ships a scheduler that must fire every minute. Add it to the pixelfed user's crontab:

    bash
    sudo crontab -u pixelfed -e

    Append:

    text
        * cd /var/www/pixelfed && /usr/bin/php artisan schedule:run >> /dev/null 2>&1

    Step 10: Configure Nginx and PHP-FPM

    Install Nginx:

    bash
    sudo apt install -y nginx

    Create the virtual host:

    bash
    sudo tee /etc/nginx/sites-available/pixelfed > /dev/null <<'EOF'
    server {
        listen 80;
        server_name pixels.example.com;
        root /var/www/pixelfed/public;
        index index.php;

    client_max_body_size 35M;

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

    location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; fastcgi_read_timeout 120; }

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

    location /storage/ { expires 30d; add_header Cache-Control "public, immutable"; } } EOF

    sudo ln -s /etc/nginx/sites-available/pixelfed /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx

    Browse to http://pixels.example.com to confirm Pixelfed answers (you will see the homepage served over plain HTTP). If the domain resolves and you see the site, move to TLS.

    Step 11: Enable TLS with Let's Encrypt

    Certbot issues and renews a free certificate from Let's Encrypt and rewrites the Nginx virtual host to redirect HTTP to HTTPS.

    bash
    sudo apt install -y certbot python3-certbot-nginx
    sudo certbot --nginx -d pixels.example.com

    Follow the prompts (agree to the ToS, opt-in or opt-out of the EFF newsletter, and choose the redirect option). Verify the renewal timer:

    bash
    sudo systemctl status certbot.timer

    Now update APP_URL in .env to https://pixels.example.com (if not already), and rebuild config cache:

    bash
    cd /var/www/pixelfed
    sudo -u pixelfed php artisan config:cache
    sudo systemctl restart pixelfed-horizon

    Visiting https://pixels.example.com should now show the Pixelfed welcome screen with a valid certificate.

    Step 12: Optional — Offload Media to S3

    If you expect significant uploads or want to keep the VPS disk lean, move media to S3-compatible object storage (AWS S3, Wasabi, Backblaze B2, MinIO, or Contabo Object Storage all work).

    Set the cloud filesystem in .env:

    ini
    FILESYSTEM_CLOUD=s3
    PF_ENABLE_CLOUD=true

    AWS_ACCESS_KEY_ID=REPLACE_ME AWS_SECRET_ACCESS_KEY=REPLACE_ME AWS_DEFAULT_REGION=eu-central-1 AWS_BUCKET=my-pixelfed-media AWS_URL=https://my-pixelfed-media.s3.eu-central-1.amazonaws.com AWS_ENDPOINT=https://s3.eu-central-1.amazonaws.com AWS_USE_PATH_STYLE_ENDPOINT=false

    Rebuild caches and restart Horizon:

    bash
    cd /var/www/pixelfed
    sudo -u pixelfed php artisan config:cache
    sudo systemctl restart pixelfed-horizon

    New uploads will land in the bucket. For already-uploaded local media, Pixelfed ships an artisan command to migrate existing files — check the current syntax in the official docs before running it.

    Step 13: Verify ActivityPub Federation

    Your instance is federation-ready the moment TLS is valid and ACTIVITY_PUB=true. Confirm the WebFinger and actor endpoints respond:

    bash
    curl https://pixels.example.com/.well-known/webfinger?resource=acct:[email protected] | head
    curl -H "Accept: application/activity+json" https://pixels.example.com/users/admin | head

    Both calls should return JSON (after you create the admin account via the signup page). From a Mastodon account on another server, paste @[email protected] into the search bar — within seconds you should see the profile appear, and a follow from there delivers a signed ActivityPub request into your Horizon queue that you can watch in sudo journalctl -u pixelfed-horizon -f.

    At this point you have a fully functional, federated Pixelfed instance: sign up the first user, mark them admin from the database (or via php artisan user:admin), and start posting.

    FAQ

    What are the minimum server specs for a Pixelfed instance?

    A small personal Pixelfed instance runs comfortably on 4 GB of RAM and 2 vCPU, but for a federated node that handles inbox deliveries from the wider fediverse and stores media for a handful of active users we recommend at least 6 vCPU, 12 GB of RAM, and 200 GB of fast NVMe storage. Media is what fills disk fastest, so plan for growth or offload to S3 from day one.

    Do I need a GPU to run Pixelfed?

    No. Pixelfed is a PHP application and does all of its image and short-video processing on CPU via ImageMagick and FFmpeg. A modern 6 vCPU server handles image variants (thumbnails, small, medium) and MP4 transcoding for normal posting volume with plenty of margin. GPUs come into play only if you attach a separate ML service for automated image description or content classification.

    Can I migrate my Instagram account to Pixelfed?

    Pixelfed can import an Instagram data export. After you request your archive from Instagram and wait for the ZIP to arrive, upload it via the account settings in your Pixelfed instance and the importer will recreate your posts with captions and original timestamps. Follower and following lists do not transfer because Instagram is not part of the fediverse, but you can publish a redirect post so existing followers know where to find you.

    How does federation work in Pixelfed?

    Pixelfed implements the ActivityPub protocol. When federation is enabled, your instance publishes posts, follows, and likes as signed ActivityPub messages that are delivered to remote inboxes on Mastodon, PeerTube, Pixelfed, and any other compatible fediverse server. Users on those platforms can follow your Pixelfed account and see your posts in their timelines, comment, and like, with everything flowing back to your instance through Horizon's queue workers.

    Should I store media on S3 or on the local disk?

    For any public instance, S3-compatible object storage is the safer long-term choice. Media grows quickly with high-resolution photos and short videos, and object storage scales independently of your VPS disk and is trivial to back up with lifecycle rules. For a single-user or small private instance where you just want something simple to operate, local disk on an NVMe-backed VPS works fine — just watch free space and take regular off-server snapshots.

    Is Pixelfed compatible with Mastodon apps?

    Yes, largely. Pixelfed implements a large subset of the Mastodon client API, so many Mastodon mobile apps can log in to a Pixelfed account and browse timelines, post, and follow. That said, photo-centric features such as filters, multi-image albums, and collections are best experienced through the official Pixelfed mobile apps on iOS and Android.

    How do I keep my Pixelfed instance updated?

    Pixelfed ships regular tagged releases. A safe upgrade sequence is: put the site into maintenance mode with php artisan down, back up the database and .env, pull the new tag from git, run composer install --no-dev --optimize-autoloader, apply php artisan migrate --force, rebuild caches with php artisan config:cache route:cache view:cache, restart Horizon with sudo systemctl restart pixelfed-horizon, and bring the site back up with php artisan up. Always read the release notes before upgrading across a minor version.

    Next Steps

    Now that Pixelfed is live on your VPS, consider these follow-ups:

    • Run a Mastodon node alongside Pixelfed — see our guide on how to install Mastodon on Ubuntu to add microblogging to your fediverse footprint with shared TLS and a shared Redis.
    • Add video with PeerTube — pair Pixelfed with PeerTube so your community can share longer video content alongside photos, all federating with the same followers.
    • Set up off-server backups — back up both the MariaDB pixelfed database and the media directory (or S3 bucket) to a separate location nightly. Pixelfed is a stateful service and losing storage means losing posts.
    • Harden the server — enable UFW, fail2ban, and automatic security updates. Restrict SSH to key-based authentication and consider a non-standard SSH port.
    • Monitor Horizon — keep an eye on queue depth at https://pixels.example.com/horizon. A growing backlog usually means you need another worker or more Redis memory.
    • Join the fediverse conversation — read the project blog and release notes at docs.pixelfed.org and follow @[email protected] from your new account to stay current on feature changes.

    Need More Power for Your Fediverse Stack?
    >
    Pixelfed instances grow with their community. If you are planning to host a public instance with hundreds of users, our higher-tier plans give you the RAM and NVMe headroom to keep Horizon snappy and media uploads fast.
    >
    - 6+ vCPU and up to 32 GB RAM for busy instances
    - NVMe storage that handles image variants without IO lag
    - Unmetered bandwidth for federation traffic spikes
    - EU and North American data centres for latency-sensitive audiences
    >
    Deploy Your Pixelfed VPS Now — Plans start at EUR 19.99/month.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket