Docker builds (#231)
authorfloatingghost <hannah@coffee-and-dreams.uk>
Sun, 16 Oct 2022 19:25:54 +0000 (19:25 +0000)
committerfloatingghost <hannah@coffee-and-dreams.uk>
Sun, 16 Oct 2022 19:25:54 +0000 (19:25 +0000)
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/231

14 files changed:
.dockerignore
.gitignore
CHANGELOG.md
Dockerfile
config/docker.exs
docker-compose.yml [new file with mode: 0644]
docker-entrypoint.sh
docker-resources/Caddyfile.example [new file with mode: 0644]
docker-resources/build.sh [new file with mode: 0755]
docker-resources/database/Dockerfile [new file with mode: 0644]
docker-resources/env.example [new file with mode: 0644]
docker-resources/manage.sh [new file with mode: 0755]
docs/docs/installation/docker_en.md [new file with mode: 0644]
docs/docs/installation/frontends.include

index 2b5f1abff4f1b32db53ace024b6efec15d3a02db..1d4f80bdf1223baf93ac584b6537995b19678f89 100644 (file)
@@ -6,12 +6,12 @@ COPYING
 *file
 elixir_buildpack.config
 test/
-instance/
-_build
-deps
 test
 benchmarks
 docs/site
+docker-db
+uploads
+instance
 
 # Required to get version
 !.git
index 8fa79b68f14e79bfe61d62223a4c0aa42a66b9f1..f9de4ed49fac9e4922473f391fe2237cbe6f6ef0 100644 (file)
@@ -17,6 +17,13 @@ secret
 /instance
 /priv/ssh_keys
 vm.args
+.cache/
+.hex/
+.mix/
+.psql_history
+docker-resources/Dockerfile
+docker-resources/Caddyfile
+pgdata
 
 # Prevent committing custom emojis
 /priv/static/emoji/custom/*
@@ -65,3 +72,6 @@ pleroma.iml
 
 # Generated documentation
 docs/site
+
+# docker stuff
+docker-db
index 44d518528714176d4e9c4db5d49e31d176f8161a..f1c2e44609ca2ac3552295acbed1f835e6749886 100644 (file)
@@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 ## Unreleased
 
+## Added
+- Officially supported docker release
+
 ## Changes
 - Follows no longer override domain blocks, a domain block is final
 - Deletes are now the lowest priority to publish and will be handled after creates
index 42ba9616bb79a2f1feb3fabf50443cecff1d5e4d..730730ce3570a555aec881b3867aab893f8c7eb9 100644 (file)
@@ -1,21 +1,9 @@
-FROM elixir:1.13.4-alpine as build
-
-COPY . .
+FROM hexpm/elixir:1.13.4-erlang-24.3.4.5-alpine-3.15.6
 
 ENV MIX_ENV=prod
 
-RUN apk add git gcc g++ musl-dev make cmake file-dev &&\
-       echo "import Config" > config/prod.secret.exs &&\
-       mix local.hex --force &&\
-       mix local.rebar --force &&\
-       mix deps.get --only prod &&\
-       mkdir release &&\
-       mix release --path release
-
-FROM alpine:3.16
-
-ARG BUILD_DATE
-ARG VCS_REF
+ARG HOME=/opt/akkoma
+ARG DATA=/var/lib/akkoma
 
 LABEL org.opencontainers.image.title="akkoma" \
     org.opencontainers.image.description="Akkoma for Docker" \
@@ -26,25 +14,21 @@ LABEL org.opencontainers.image.title="akkoma" \
     org.opencontainers.image.revision=$VCS_REF \
     org.opencontainers.image.created=$BUILD_DATE
 
-ARG HOME=/opt/akkoma
-ARG DATA=/var/lib/akkoma
+RUN apk add git gcc g++ musl-dev make cmake file-dev exiftool ffmpeg imagemagick libmagic ncurses postgresql-client
 
-RUN apk update &&\
-       apk add exiftool ffmpeg imagemagick libmagic ncurses postgresql-client &&\
-       adduser --system --shell /bin/false --home ${HOME} akkoma &&\
-       mkdir -p ${DATA}/uploads &&\
-       mkdir -p ${DATA}/static &&\
-       chown -R akkoma ${DATA} &&\
-       mkdir -p /etc/akkoma &&\
-       chown -R akkoma /etc/akkoma
+EXPOSE 4000
 
-USER akkoma
+ARG UID=1000
+ARG GID=1000
+ARG UNAME=akkoma
 
-COPY --from=build --chown=akkoma:0 /release ${HOME}
+RUN addgroup -g $GID $UNAME
+RUN adduser -u $UID -G $UNAME -D -h $HOME $UNAME
 
-COPY ./config/docker.exs /etc/akkoma/config.exs
-COPY ./docker-entrypoint.sh ${HOME}
+WORKDIR /opt/akkoma
 
-EXPOSE 4000
+USER $UNAME
+RUN mix local.hex --force &&\
+    mix local.rebar --force
 
-ENTRYPOINT ["/opt/akkoma/docker-entrypoint.sh"]
+CMD ["/opt/akkoma/docker-entrypoint.sh"]
index f9f27d141511ea8c3836a880869c38c670953075..fc24a4d67d059deb35d4c52a8601812009ccee12 100644 (file)
@@ -24,11 +24,11 @@ config :pleroma, Pleroma.Repo,
 config :web_push_encryption, :vapid_details, subject: "mailto:#{System.get_env("NOTIFY_EMAIL")}"
 
 config :pleroma, :database, rum_enabled: false
-config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
-config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
+config :pleroma, :instance, static_dir: "/var/lib/akkoma/static"
+config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/akkoma/uploads"
 
 # We can't store the secrets in this file, since this is baked into the docker image
-if not File.exists?("/var/lib/pleroma/secret.exs") do
+if not File.exists?("/var/lib/akkoma/secret.exs") do
   secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
   signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
   {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
@@ -52,16 +52,16 @@ if not File.exists?("/var/lib/pleroma/secret.exs") do
       web_push_private_key: Base.url_encode64(web_push_private_key, padding: false)
     )
 
-  File.write("/var/lib/pleroma/secret.exs", secret_file)
+  File.write("/var/lib/akkoma/secret.exs", secret_file)
 end
 
-import_config("/var/lib/pleroma/secret.exs")
+import_config("/var/lib/akkoma/secret.exs")
 
 # For additional user config
-if File.exists?("/var/lib/pleroma/config.exs"),
-  do: import_config("/var/lib/pleroma/config.exs"),
+if File.exists?("/var/lib/akkoma/config.exs"),
+  do: import_config("/var/lib/akkoma/config.exs"),
   else:
-    File.write("/var/lib/pleroma/config.exs", """
+    File.write("/var/lib/akkoma/config.exs", """
     import Config
 
     # For additional configuration outside of environmental variables
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644 (file)
index 0000000..b8da67a
--- /dev/null
@@ -0,0 +1,61 @@
+version: "3.7"
+
+services:
+  db:
+    image: akkoma-db:latest
+    build: ./docker-resources/database
+    restart: unless-stopped
+    user: ${DOCKER_USER}
+    environment: {
+      # This might seem insecure but is usually not a problem.
+      # You should leave this at the "akkoma" default.
+      # The DB is only reachable by containers in the same docker network,
+      # and is not exposed to the open internet.
+      #
+      # If you do change this, remember to update "config.exs".
+      POSTGRES_DB: akkoma,
+      POSTGRES_USER: akkoma,
+      POSTGRES_PASSWORD: akkoma,
+    }
+    env_file:
+      - .env 
+    volumes:
+      - type: bind
+        source: ./pgdata
+        target: /var/lib/postgresql/data
+
+  akkoma:
+    image: akkoma:latest
+    build: .
+    restart: unless-stopped
+    env_file:
+      - .env
+    links:
+      - db
+    ports: [
+      # Uncomment/Change port mappings below as needed.
+      # The left side is your host machine, the right one is the akkoma container.
+      # You can prefix the left side with an ip.
+
+      # Webserver (for reverse-proxies outside of docker)
+      # If you use a dockerized proxy, you can leave this commented
+      # and use a container link instead.
+      "127.0.0.1:4000:4000",
+    ]
+    volumes:
+      - .:/opt/akkoma
+
+  # Uncomment the following if you want to use a reverse proxy
+  #proxy:
+  #  image: caddy:2-alpine
+  #  restart: unless-stopped
+  #  links:
+  #    - akkoma
+  #  ports: [
+  #     "443:443",
+  #     "80:80"
+  #  ]
+  #  volumes:
+  #    - ./docker-resources/Caddyfile:/etc/caddy/Caddyfile
+  #    - ./caddy-data:/data
+  #    - ./caddy-config:/config
\ No newline at end of file
index f56f8c50a7030435294cdbaccad36f0879d256f4..778ef08e27802bab91d272864cde80d0b7f105d7 100755 (executable)
@@ -8,7 +8,7 @@ while ! pg_isready -U ${DB_USER:-pleroma} -d postgres://${DB_HOST:-db}:5432/${DB
 done
 
 echo "-- Running migrations..."
-$HOME/bin/pleroma_ctl migrate
+mix ecto.migrate
 
 echo "-- Starting!"
-exec $HOME/bin/pleroma start
+mix phx.server
diff --git a/docker-resources/Caddyfile.example b/docker-resources/Caddyfile.example
new file mode 100644 (file)
index 0000000..47b8c7c
--- /dev/null
@@ -0,0 +1,14 @@
+# default docker Caddyfile config for Akkoma
+#
+# Simple installation instructions:
+# 1. Replace 'example.tld' with your instance's domain wherever it appears.
+
+example.tld  {
+  log {
+    output file /var/log/caddy/akkoma.log
+  }
+
+  encode gzip
+
+  reverse_proxy akkoma:4000
+}
diff --git a/docker-resources/build.sh b/docker-resources/build.sh
new file mode 100755 (executable)
index 0000000..daa653d
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+docker-compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) akkoma
+docker-compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) db
diff --git a/docker-resources/database/Dockerfile b/docker-resources/database/Dockerfile
new file mode 100644 (file)
index 0000000..2a38dd1
--- /dev/null
@@ -0,0 +1,10 @@
+FROM postgres:14-alpine
+
+ARG UID=1000
+ARG GID=1000
+ARG UNAME=akkoma
+
+RUN addgroup -g $GID $UNAME
+RUN adduser -u $UID -G $UNAME -D -h $HOME $UNAME
+
+USER akkoma
diff --git a/docker-resources/env.example b/docker-resources/env.example
new file mode 100644 (file)
index 0000000..d6cf0c7
--- /dev/null
@@ -0,0 +1,4 @@
+MIX_ENV=prod
+DB_NAME=akkoma
+DB_USER=akkoma
+DB_PASS=akkoma
diff --git a/docker-resources/manage.sh b/docker-resources/manage.sh
new file mode 100755 (executable)
index 0000000..944f5e2
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+docker-compose run --rm akkoma $@
diff --git a/docs/docs/installation/docker_en.md b/docs/docs/installation/docker_en.md
new file mode 100644 (file)
index 0000000..ecb9276
--- /dev/null
@@ -0,0 +1,160 @@
+# Installing in Docker
+
+## Installation
+
+This guide will show you how to get akkoma working in a docker container,
+if you want isolation, or if you run a distribution not supported by the OTP
+releases.
+
+### Prepare the system
+
+* Install docker and docker-compose
+  * [Docker](https://docs.docker.com/engine/install/) 
+  * [Docker-compose](https://docs.docker.com/compose/install/)
+  * This will usually just be a repository installation and a package manager invocation.
+* Clone the akkoma repository
+  * `git clone https://akkoma.dev/AkkomaGang/akkoma.git -b stable`
+  * `cd akkoma`
+
+### Set up basic configuration
+
+```bash
+cp docker-resources/env.example .env
+echo "DOCKER_USER=$(id -u):$(id -g)" >> .env
+```
+
+This probably won't need to be changed, it's only there to set basic environment
+variables for the docker-compose file.
+
+### Building the container
+
+The container provided is a thin wrapper around akkoma's dependencies, 
+it does not contain the code itself. This is to allow for easy updates
+and debugging if required.
+
+```bash
+./docker-resources/build.sh
+```
+
+This will generate a container called `akkoma` which we can use
+in our compose environment.
+
+### Generating your instance
+
+```bash
+mkdir pgdata
+# if you want to use caddy
+mkdir caddy-data
+mkdir caddy-config
+./docker-resources/manage.sh mix deps.get
+./docker-resources/manage.sh mix compile
+./docker-resources/manage.sh mix pleroma.instance gen
+```
+
+This will ask you a few questions - the defaults are fine for most things,
+the database hostname is `db`, and you will want to set the ip to `0.0.0.0`.
+
+Now we'll want to copy over the config it just created
+
+```bash
+cp config/generated_config.exs config/prod.secret.exs
+```
+
+### Setting up the database 
+
+We need to run a few commands on the database container, this isn't too bad
+
+```bash
+docker-compose run --rm --user akkoma -d db 
+# Note down the name it gives here, it will be something like akkoma_db_run
+docker-compose run --rm akkoma psql -h db -U akkoma -f config/setup_db.psql
+docker stop akkoma_db_run # Replace with the name you noted down
+```
+
+Now we can actually run our migrations
+
+```bash
+./docker-resources/manage.sh mix ecto.migrate
+# this will recompile your files at the same time, since we changed the config
+```
+
+### Start the server
+
+We're going to run it in the foreground on the first run, just to make sure
+everything start up.
+
+```bash
+docker-compose up
+```
+
+If everything went well, you should be able to access your instance at http://localhost:4000
+
+You can `ctrl-c` out of the docker-compose now to shutdown the server.
+
+### Running in the background
+
+```bash
+docker-compose up -d
+```
+
+### Create your first user
+
+If your instance is up and running, you can create your first user with administrative rights with the following task:
+
+```shell
+./docker-resources/manage.sh mix pleroma.user new MY_USERNAME MY_EMAIL@SOMEWHERE --admin
+```
+
+And follow the prompts 
+
+### Reverse proxies
+
+This is a tad more complex in docker than on the host itself. It
+
+You've got two options. 
+
+#### Running caddy in a container
+
+This is by far the easiest option. It'll handle HTTPS and all that for you. 
+
+```bash
+cp docker-resources/Caddyfile.example docker-resources/Caddyfile
+```
+
+Then edit the TLD in your caddyfile to the domain you're serving on.
+
+Uncomment the `caddy` section in the docker-compose file,
+then run `docker-compose up -d` again.
+
+#### Running a reverse proxy on the host
+
+If you want, you can also run the reverse proxy on the host. This is a bit more complex, but it's also more flexible.
+
+Follow the guides for source install for your distribution of choice, or adapt
+as needed. Your standard setup can be found in the [Debian Guide](../debian_based_en/#nginx)
+
+### You're done!
+
+All that's left is to set up your frontends. 
+
+The standard from-source commands will apply to you, just make sure you
+prefix them with `./docker-resources/manage.sh`!
+
+{! installation/frontends.include !}
+
+### Updating Docker Installs
+
+```bash
+git pull
+./docker-resources/build.sh
+./docker-resources/manage.sh mix deps.get
+./docker-resources/manage.sh mix compile
+./docker-resources/manage.sh mix ecto.migrate
+docker-compose restart akkoma
+```
+
+#### Further reading
+
+{! installation/further_reading.include !}
+
+{! support.include !}
index 585be71aeb4a78fd7aaf982741ec9b204bc6e970..6da4018a99dcf587ce4d02173573ec90c49f7f5c 100644 (file)
@@ -21,5 +21,11 @@ For most installations, the following will suffice:
     mix pleroma.frontend install admin-fe --ref stable
     ```
 
+=== "Docker"
+    ```sh
+    ./docker-resources/manage.sh mix pleroma.frontend install pleroma-fe --ref stable
+    ./docker-resources/manage.sh mix pleroma.frontend install admin-fe --ref stable
+    ```
+
 For more customised installations, refer to [Frontend Management](../../configuration/frontend_management)