Setting Up a Pleroma Instance in Docker

Looking to set up your own Pleroma instance? This guide should walk you through everything you need to do to make it happen. Of note, this assumes you have some familiarity with Docker and working with it, PostgreSQL and Linux. I also utilize Traefik to handle proxying requests.

First, most of this guide is the same thing that can be found here with a few changes. The reason I don't just tell you to go to that guide is that I have an already existing PostgreSQL installation along with a pre-existing network setup in my Docker stack.

docker-compose.yml

To start with this is my docker-compose.yml file:

services:
  pleroma:
    build: .
    image: pleroma
    container_name: pleroma
    hostname: pleroma.mydomain.com
    environment:
      - TZ=${TZ}
      - UID=${PUID}
      - GID=${PGID}
    ports:
      - 4001:4000
    networks:
      static:
        ipv4_address: 172.18.0.34
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ${DOCKERCONFDIR}/pleroma/uploads:/pleroma/uploads
    depends_on:
      - postgres
    restart: unless-stopped
    cap_add:
      - SYS_PTRACE
  postgres:
    image: postgres:9.6
    container_name: postgres
    hostname: postgres.mydomain.com
    environment:
      - PGID=${PGID}
      - PUID=${PUID}
      - TZ=${TZ}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ${DOCKERCONFDIR}/postgresql/pg_data:/var/lib/postgresql/data
      - ${DOCKERCONFDIR}/postgresql/root:/root
    ports:
      - 5432:5432
    networks:
      static:
          ipv4_address: 172.18.0.14
    restart: unless-stopped
    cap_add:
      - SYS_PTRACE
    networks:
      static:
      driver: bridge
      ipam:
        config:
          - subnet: 172.18.0.0/16
          gateway: 172.18.0.1
version: "2.4"

While this isn't the full configuration file, these are the parts which allow Pleroma to function. As noted above I already have a PostgreSQL instance and a pre-existing network created for my Docker stack. You should also note that I use some variables here, mostly in the environment and volumes sections for each container. You can use them too, or swap them out for their "real" values. I'd recommend using the variables with an .env file, but it's up to you.

PostgreSQL Setup

The first thing I do is create a new PostgreSQL user for Pleroma:

psql -U superuser -h localhost -p 5432

You'll want to change out 'superuser' for a user which can create users within PostgreSQL. The follow will create a database for Pleroma, a PostgreSQL user and allow access to the new database for that user.

CREATE DATABASE pleroma;
CREATE USER pleroma WITH ENCRYPTED PASSWORD 'PASSWORD-HERE';
GRANT ALL PRIVILEGES ON DATABASE pleroma TO pleroma;

It appears the database setup processes creates an EXTENSION, so you'll need to provide your PostgreSQL user with the superuser permission. You can do so by running the following:

ALTER USER pleroma WITH SUPERUSER;

File System Setup

Once setting up PostgreSQL has been completed, you'll want to setup your uploads folder. I've set mine up at /home/jimmy/.docker/config/pleroma/uploads. Next, I setup a folder where I will build the Pleroma Docker image. I've done this at /home/jimmy/.docker/builds/pleroma. Within that directory, I create a new Dockerfile and place the follow contents into it:

FROM elixir:1.9-alpine

ENV UID=911 GID=911 \
    MIX_ENV=prod

ARG PLEROMA_VER=develop

RUN apk -U upgrade \
    && apk add --no-cache \
       build-base \
       git

RUN addgroup -g ${GID} pleroma \
    && adduser -h /pleroma -s /bin/sh -D -G pleroma -u ${UID} pleroma

USER pleroma
WORKDIR pleroma

RUN git clone -b develop https://git.pleroma.social/pleroma/pleroma.git /pleroma \
    && git checkout ${PLEROMA_VER}

COPY config/secret.exs /pleroma/config/prod.secret.exs

RUN mix local.rebar --force \
    && mix local.hex --force \
    && mix deps.get \
    && mix compile

VOLUME /pleroma/uploads/

CMD ["mix", "phx.server"]

This Dockerfile is different than the one provided by the above linked GitHub respository. The difference is the first line. I am utilizing a newer version of elixer which is required. If you do not use this you will likely see the following error in your logs when trying to startup your Pleroma instance:

15:38:00.284 [info] Application pleroma exited: exited in: Pleroma.Application.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (RuntimeError) 
            !!!OTP VERSION WARNING!!!
            You are using gun adapter with OTP version 21.3.8.15, which doesn't support correct handling of unordered certificates chains. Please update your Erlang/OTP to at least 22.2.
            (pleroma) lib/pleroma/application.ex:57: Pleroma.Application.start/2
            (kernel) application_master.erl:277: :application_master.start_it_old/4
15:38:22.720 [info]  SIGTERM received - shutting down

Next create a config folder within your builds/pleroma directory. For example, my full path is /home/jimmy/.docker/builds/pleroma/config. Within there create a file called secret.exs. Open this file in your favorite text editor and paste in the following:

use Mix.Config

config :pleroma, Pleroma.Web.Endpoint,
   http: [ ip: {0, 0, 0, 0}, ],
   url: [host: "pleroma.domain.tld", scheme: "https", port: 443],
   secret_key_base: "<use 'openssl rand -base64 48' to generate a key>"

config :pleroma, :instance,
  name: "Pleroma",
  email: "admin@email.tld",
  limit: 5000,
  registrations_open: true

config :pleroma, :media_proxy,
  enabled: false,
  redirect_on_failure: true,
  base_url: "https://cache.domain.tld"

# Configure your database
config :pleroma, Pleroma.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "pleroma",
  password: "pleroma",
  database: "pleroma",
  hostname: "postgres",
  pool_size: 10

Ensure that you update the host in the url line, the secret_key_base, the name, email, and the database information. Save and exit the file.

Building The Pleroma Docker Image

Alright, so with your Dockerfile and Pleroma configuration files in place we need to build the image! While in the same directory as your Dockerfile, run the following command:

docker build -t pleroma .

This may take a few minutes to complete. Once completed we need to setup the database within PostgreSQL. This is another reason I am putting together this guide, because using the command from the other GitHub repository will not work.

docker run --rm -it --network=main_static pleroma mix ecto.migrate

That will take 30-45 seconds to run. Once completed we need to generate our web push keys. Use the following command in order to do so:

docker run --rm -it --network=main_static pleroma mix web_push.gen.keypair

Copy the output from the above command, and place it at the bottom of your config/secret.exs file. Now we need to rebuild the Pleroma Docker image again with this new configuration, so do so using:

docker build -t pleroma .

You should be all set now! You just need to run docker-compose up -d and it should get everything started up. If all went well you should see something similar to:

Pleroma Instance

Updating Your Pleroma Instance

So you've got your instance up and running but how about keeping it up to date! Fortunately this is relatively easy as well! Just go into the directory with your Pleroma Dockerfile and run the following commands:

docker stop pleroma
docker build --no-cache -t pleroma .
docker run --rm -it --network=main_static pleroma mix ecto.migrate

Now run docker-compose up -d and a new container will be created with your newly built image!

Resources