├── .dockerignore ├── .gitignore ├── cli.sh ├── custom-config.exs ├── LICENSE.md ├── start.sh ├── docker-compose.yaml ├── docker-compose.local.yaml ├── Dockerfile ├── base-config.exs ├── .github └── workflows │ └── build.yaml └── README.md /.dockerignore: -------------------------------------------------------------------------------- 1 | data -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | data -------------------------------------------------------------------------------- /cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | 3 | su-exec pleroma mix pleroma.$@ 4 | -------------------------------------------------------------------------------- /custom-config.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :pleroma, :instance, 4 | registrations_open: false 5 | 6 | config :pleroma, Pleroma.Web.Endpoint, 7 | url: [host: "pleroma.example.org"] 8 | 9 | config :pleroma, Pleroma.Web.WebFinger, domain: "example.org" 10 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2022 Henry Gressmann 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PUID=${PUID:-1000} 4 | PGID=${PGID:-1000} 5 | 6 | groupmod -o -g "$PGID" pleroma 7 | usermod -o -u "$PUID" pleroma 8 | 9 | set -e 10 | 11 | echo " 12 | ------------------------------------- 13 | Pleroma Docker by explodingcamera 14 | ------------------------------------- 15 | ------------------------------------- 16 | User: $(whoami) 17 | User uid: $(id -u pleroma) 18 | User gid: $(id -g pleroma) 19 | ------------------------------------- 20 | " 21 | 22 | if [ "$(stat -c %U:%G /app)" != "pleroma:pleroma" ]; then 23 | chown -R pleroma:pleroma /app 24 | fi 25 | 26 | if [ "$(stat -c %U:%G /data)" != "pleroma:pleroma" ]; then 27 | chown -R pleroma:pleroma /data 28 | fi 29 | 30 | echo "-- Waiting for database..." 31 | while ! pg_isready -U ${DB_USER:-pleroma} -d postgres://${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-pleroma} -t 1; do 32 | sleep 1s 33 | done 34 | 35 | echo "-- Running migrations..." 36 | su-exec pleroma mix ecto.migrate 37 | 38 | echo "-- Starting server..." 39 | su-exec pleroma mix phx.server 40 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | db: 3 | image: docker.io/postgres:17-alpine 4 | container_name: pleroma_db 5 | restart: always 6 | healthcheck: 7 | test: ["CMD", "pg_isready", "-U", "pleroma"] 8 | environment: 9 | POSTGRES_USER: pleroma 10 | POSTGRES_PASSWORD: ChangeMe! 11 | POSTGRES_DB: pleroma 12 | volumes: 13 | - ./data/postgres:/var/lib/postgresql/data 14 | web: 15 | image: ghcr.io/explodingcamera/pleroma:stable 16 | container_name: pleroma_web 17 | healthcheck: 18 | test: 19 | ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000 || exit 1"] 20 | restart: always 21 | ports: 22 | - "4000:4000" 23 | volumes: 24 | - ./data/uploads:/data/uploads 25 | - ./data/static:/data/static 26 | - ./custom-config.exs:/data/config.exs 27 | environment: 28 | PUID: 1000 29 | PGID: 1000 30 | DOMAIN: example.com 31 | INSTANCE_NAME: Pleroma 32 | ADMIN_EMAIL: admin@example.com 33 | NOTIFY_EMAIL: notify@example.com 34 | DB_USER: pleroma 35 | DB_PASS: ChangeMe! 36 | DB_NAME: pleroma 37 | depends_on: 38 | - db 39 | -------------------------------------------------------------------------------- /docker-compose.local.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | db: 3 | image: docker.io/postgres:17-alpine 4 | container_name: pleroma_db 5 | restart: always 6 | healthcheck: 7 | test: ["CMD", "pg_isready", "-U", "pleroma"] 8 | environment: 9 | POSTGRES_USER: pleroma 10 | POSTGRES_PASSWORD: ChangeMe! 11 | POSTGRES_DB: pleroma 12 | volumes: 13 | - ./data/postgres:/var/lib/postgresql/data 14 | web: 15 | image: ghcr.io/explodingcamera/pleroma:stable 16 | container_name: pleroma_web 17 | healthcheck: 18 | test: 19 | ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000 || exit 1"] 20 | restart: always 21 | ports: 22 | - "4000:4000" 23 | build: 24 | context: . 25 | args: 26 | - "PLEROMA_VER=stable" 27 | volumes: 28 | - ./data/uploads:/data/uploads 29 | - ./data/static:/data/static 30 | - ./custom-config.exs:/data/config.exs 31 | environment: 32 | PUID: 1000 33 | PGID: 1000 34 | DOMAIN: example.com 35 | INSTANCE_NAME: Pleroma 36 | ADMIN_EMAIL: admin@example.com 37 | NOTIFY_EMAIL: notify@example.com 38 | DB_USER: pleroma 39 | DB_PASS: ChangeMe! 40 | DB_NAME: pleroma 41 | depends_on: 42 | - db 43 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/elixir:1.16-otp-26-alpine as builder 2 | 3 | ARG PLEROMA_VERSION=stable 4 | ARG PLEROMA_REPO=https://git.pleroma.social/pleroma/pleroma.git 5 | ENV MIX_ENV=prod 6 | 7 | # Install build dependencies 8 | RUN apk add --no-cache git gcc g++ musl-dev make cmake file-dev ncurses postgresql-client imagemagick libmagic ffmpeg exiftool 9 | 10 | WORKDIR /app 11 | RUN git clone --filter=blob:none --no-checkout ${PLEROMA_REPO} . \ 12 | && git checkout ${PLEROMA_VERSION} 13 | 14 | 15 | RUN echo "import Mix.Config" > config/prod.secret.exs \ 16 | && mix local.hex --force \ 17 | && mix local.rebar --force \ 18 | && mix deps.get --only prod \ 19 | && mix deps.compile 20 | 21 | FROM docker.io/elixir:1.16-otp-26-alpine as runner 22 | ENV MIX_ENV=prod 23 | ARG EXTRA_PKGS="imagemagick libmagic ffmpeg" 24 | 25 | # Install runtime dependencies 26 | RUN apk add --no-cache shadow su-exec git postgresql-client exiftool ${EXTRA_PKGS} 27 | WORKDIR /app 28 | 29 | ADD start.sh /app/start.sh 30 | ADD cli.sh /app/cli.sh 31 | RUN chmod +x /app/start.sh \ 32 | && chmod +x /app/cli.sh \ 33 | && groupmod -g 1000 users \ 34 | && useradd -u 1000 -U -d /home/pleroma -s /bin/false pleroma \ 35 | && usermod -G users pleroma \ 36 | && mkdir -p \ /data/uploads /data/static \ 37 | && chown -R pleroma:users /data 38 | 39 | COPY --from=builder --chown=pleroma /root/.mix /home/pleroma/.mix 40 | COPY --from=builder --chown=pleroma /app . 41 | 42 | ADD base-config.exs /app/config/prod.secret.exs 43 | 44 | EXPOSE 4000 45 | ENTRYPOINT ["/app/start.sh"] -------------------------------------------------------------------------------- /base-config.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :pleroma, Pleroma.Web.Endpoint, 4 | url: [host: System.get_env("DOMAIN", "localhost"), scheme: "https", port: 443], 5 | http: [ip: {0, 0, 0, 0}, port: 4000] 6 | 7 | config :pleroma, :instance, 8 | name: System.get_env("INSTANCE_NAME", "Pleroma"), 9 | email: System.get_env("ADMIN_EMAIL"), 10 | notify_email: System.get_env("NOTIFY_EMAIL"), 11 | limit: 5000, 12 | registrations_open: true, 13 | federating: true, 14 | healthcheck: true 15 | 16 | config :pleroma, :media_proxy, 17 | enabled: false, 18 | redirect_on_failure: true, 19 | base_url: "https://cache.domain.tld" 20 | 21 | config :pleroma, Pleroma.Repo, 22 | adapter: Ecto.Adapters.Postgres, 23 | username: System.get_env("DB_USER", "pleroma"), 24 | password: System.fetch_env!("DB_PASS"), 25 | database: System.get_env("DB_NAME", "pleroma"), 26 | hostname: System.get_env("DB_HOST", "db"), 27 | pool_size: 10 28 | 29 | # Configure web push notifications 30 | config :web_push_encryption, :vapid_details, subject: "mailto:#{System.get_env("NOTIFY_EMAIL")}" 31 | 32 | config :pleroma, :database, rum_enabled: false 33 | config :pleroma, :instance, static_dir: "/data/static" 34 | config :pleroma, Pleroma.Uploaders.Local, uploads: "/data/uploads" 35 | 36 | # We can't store the secrets in this file, since this is baked into the docker image 37 | if not File.exists?("/data/secret.exs") do 38 | secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64) 39 | signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8) 40 | {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1) 41 | 42 | secret_file = 43 | EEx.eval_string( 44 | """ 45 | import Config 46 | config :pleroma, Pleroma.Web.Endpoint, 47 | secret_key_base: "<%= secret %>", 48 | signing_salt: "<%= signing_salt %>" 49 | config :web_push_encryption, :vapid_details, 50 | public_key: "<%= web_push_public_key %>", 51 | private_key: "<%= web_push_private_key %>" 52 | """, 53 | secret: secret, 54 | signing_salt: signing_salt, 55 | web_push_public_key: Base.url_encode64(web_push_public_key, padding: false), 56 | web_push_private_key: Base.url_encode64(web_push_private_key, padding: false) 57 | ) 58 | 59 | File.write("/data/secret.exs", secret_file) 60 | end 61 | 62 | import_config("/data/secret.exs") 63 | 64 | # For additional user config 65 | if File.exists?("/data/config.exs"), 66 | do: import_config("/data/config.exs"), 67 | else: 68 | File.write("/data/config.exs", """ 69 | import Config 70 | # For additional configuration outside of environmental variables 71 | """) 72 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | schedule: 5 | - cron: 30 12 * * 1 6 | push: 7 | paths: 8 | - Dockerfile 9 | - start.sh 10 | - cli.sh 11 | branches: main 12 | workflow_dispatch: 13 | 14 | jobs: 15 | build: 16 | strategy: 17 | matrix: 18 | version: ["stable", "develop"] 19 | runs-on: ubuntu-latest 20 | permissions: 21 | contents: read 22 | packages: write 23 | 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v3 27 | 28 | - name: Set up Docker Buildx 29 | uses: docker/setup-buildx-action@v2 30 | 31 | - name: Login to GitHub Container Registry 32 | uses: docker/login-action@v2 33 | with: 34 | registry: ghcr.io 35 | username: ${{ github.actor }} 36 | password: ${{ secrets.GITHUB_TOKEN }} 37 | 38 | - name: get latest tag 39 | if: startsWith(matrix.version, 'stable') 40 | id: tag 41 | run: | 42 | tag=$(curl -s https://git.pleroma.social/api/v4/projects/2/repository/tags | jq -r '.[0].name') 43 | tag=$(echo $tag | sed 's/v//') 44 | tag_major=$(echo $tag | cut -d. -f1) 45 | tag_major_minor=$(echo $tag | cut -d. -f1-2) 46 | echo "Tag value is $tag" 47 | echo "tag=$tag" >> $GITHUB_OUTPUT 48 | echo "tag_major=$tag_major" >> $GITHUB_OUTPUT 49 | echo "tag_major_minor=$tag_major_minor" >> $GITHUB_OUTPUT 50 | 51 | - name: Docker meta 52 | id: meta 53 | uses: docker/metadata-action@v4 54 | with: 55 | images: ghcr.io/explodingcamera/pleroma 56 | 57 | - name: Build and push (develop) 58 | if: startsWith(matrix.version, 'develop') 59 | uses: docker/build-push-action@v3 60 | with: 61 | push: true 62 | build-args: | 63 | PLEROMA_VERSION=${{ matrix.version }} 64 | context: . 65 | file: ./Dockerfile 66 | tags: | 67 | ghcr.io/explodingcamera/pleroma:develop 68 | 69 | - name: Build and push (stable) 70 | if: startsWith(matrix.version, 'stable') 71 | uses: docker/build-push-action@v3 72 | with: 73 | push: true 74 | build-args: | 75 | PLEROMA_VERSION=${{ matrix.version }} 76 | context: . 77 | file: ./Dockerfile 78 | tags: | 79 | ghcr.io/explodingcamera/pleroma:latest 80 | ghcr.io/explodingcamera/pleroma:${{ steps.tag.outputs.tag }} 81 | ghcr.io/explodingcamera/pleroma:${{ steps.tag.outputs.tag_major }} 82 | ghcr.io/explodingcamera/pleroma:${{ steps.tag.outputs.tag_major_minor }} 83 | labels: ${{ steps.meta.outputs.labels }} 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pleroma Docker 2 | 3 | Simple Docker image for [Pleroma](https://pleroma.social/). 4 | Currently, only x86_64 is supported. If you want to run Pleroma on other architectures, you should be able to build it yourself using the Dockerfile. I don't run a Pleroma instance myself anymore so there might be some issues with the image whenever a new pleroma version is released. 5 | 6 | # Supported tags 7 | 8 | - [`latest`](https://github.com/explodingcamera/docker-pleroma/pkgs/container/pleroma) - latest stable release 9 | - [`3`](https://github.com/explodingcamera/docker-pleroma/pkgs/container/pleroma) - latest 3.x release 10 | - [`3.15`](https://github.com/explodingcamera/docker-pleroma/pkgs/container/pleroma) - specific minor version 11 | - [`3.15.1`](https://github.com/explodingcamera/docker-pleroma/pkgs/container/pleroma) - specific version 12 | - [`develop`](https://github.com/explodingcamera/docker-pleroma/pkgs/container/pleroma) - latest develop branch build 13 | 14 | Versions are build automatically using GitHub Actions weekly. 15 | 16 | # How to use this image 17 | 18 | ## Start a Pleroma instance 19 | 20 | **Docker Compose** 21 | 22 | ```yaml 23 | version: "3.8" 24 | 25 | services: 26 | db: 27 | image: postgres:17-alpine 28 | container_name: pleroma_db 29 | restart: always 30 | healthcheck: 31 | test: ["CMD", "pg_isready", "-U", "pleroma"] 32 | environment: 33 | POSTGRES_USER: pleroma 34 | POSTGRES_PASSWORD: ChangeMe! 35 | POSTGRES_DB: pleroma 36 | volumes: 37 | - ./data/postgres:/var/lib/postgresql/data 38 | web: 39 | image: ghcr.io/explodingcamera/pleroma:stable 40 | container_name: pleroma_web 41 | healthcheck: 42 | test: 43 | ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000 || exit 1"] 44 | restart: always 45 | ports: 46 | - "4000:4000" 47 | volumes: 48 | - ./data/uploads:/data/uploads 49 | - ./data/static:/data/static 50 | - ./custom-config.exs:/data/config.exs 51 | environment: 52 | PUID: 1000 53 | PGID: 1000 54 | DOMAIN: example.com 55 | INSTANCE_NAME: Pleroma 56 | ADMIN_EMAIL: admin@example.com 57 | NOTIFY_EMAIL: notify@example.com 58 | DB_USER: pleroma 59 | DB_PASS: ChangeMe! 60 | DB_NAME: pleroma 61 | depends_on: 62 | - db 63 | ``` 64 | 65 | **Docker CLI** 66 | 67 | ```bash 68 | docker run -d \ 69 | --name=pleroma \ 70 | -e PUID=1000 \ 71 | -e PGID=1000 \ 72 | -e DOMAIN="example.com" 73 | -e INSTANCE_NAME="Pleroma" 74 | -e ADMIN_EMAIL="admin@example.com" 75 | -e NOTIFY_EMAIL="notify@example.com" 76 | -e DB_USER="pleroma" 77 | -e DB_PASS="ChangeMe!" 78 | -e DB_NAME="pleroma" 79 | -p 4000:4000 \ 80 | -v /path/to/static:/data/static \ 81 | -v /path/to/uploads:/data/uploads \ 82 | -v /path/to/customconfig:/data/config.exs \ # optional 83 | --restart unless-stopped \ 84 | ghcr.io/explodingcamera/pleroma:stable 85 | ``` 86 | 87 | # Running Commands 88 | 89 | ```bash 90 | $ docker exec -it pleroma_web ./cli.sh user new --admin 91 | ``` 92 | 93 | # Configuration 94 | 95 | ## Environment variables 96 | 97 | - `PUID` - User ID (default: `1000`) 98 | - `PGID` - Group ID (default: `1000`) 99 | - `DOMAIN` - Domain name (default: `example.com`) 100 | 101 | ## Pleroma configuration 102 | 103 | See [Pleroma documentation](https://docs.pleroma.social/backend/configuration/auth/) for more information. 104 | 105 | `custom-config.exs` 106 | 107 | ```elixir 108 | import Config 109 | 110 | config :pleroma, :instance, 111 | registrations_open: false 112 | 113 | config :pleroma, Pleroma.Web.Endpoint, 114 | url: [host: "pleroma.example.org"] 115 | 116 | config :pleroma, Pleroma.Web.WebFinger, domain: "example.org" 117 | ``` 118 | 119 | # Build-time variables 120 | 121 | - `PLEROMA_VERSION` - Pleroma version to build (default: `stable`) 122 | - `PLEROMA_REPO` - Pleroma repository to clone (default: `https://git.pleroma.social/pleroma/pleroma.git`) 123 | - `EXTRA_PKGS` - Extra packages to install (default: `imagemagick libmagic ffmpeg`) 124 | 125 | # Other Docker images 126 | 127 | - [angristan/docker-pleroma](https://github.com/angristan/docker-pleroma) 128 | - [potproject/docker-pleroma](https://github.com/potproject/docker-pleroma) 129 | - [rysiek/docker-pleroma](https://git.pleroma.social/rysiek/docker-pleroma) 130 | - [RX14/iscute.moe](https://github.com/RX14/kurisu.rx14.co.uk/blob/master/services/iscute.moe/pleroma/Dockerfile) 131 | --------------------------------------------------------------------------------