Server admin

Adding tools such as ffmpeg.

An event rule can run a command on your server. The command has to exist inside the Farwing container. The Farwing image does not include tools such as ffmpeg, so you add the ones you need with a short Dockerfile.

Why the image is small

The Farwing image holds the server, the portal and the few programs the server itself needs. Most servers do not convert video, scan files or process images, and a larger image is slower to download and has more software to keep patched. So the image leaves these tools out, and you add only the ones you use. The same goes for virus scanning: the image carries no scanner, and Virus scanning connects to one you run.

If you would rather not change the image, a webhook step in a rule can call a service on another machine and have that machine run the tool.

The Dockerfile

Save this as Dockerfile.ffmpeg in the folder that holds your compose.yml:

# Farwing Server with ffmpeg added, so an event rule can run it.
#
# Build and run it with Docker Compose by changing the farwing service to:
#
#   services:
#     farwing:
#       build:
#         context: .
#         dockerfile: Dockerfile.ffmpeg
#       image: farwing-ffmpeg:1
#
# Everything else in your compose file stays as it is.

# Start from the Farwing image you already run. Keep the tag in step with the
# one in your compose file, so an upgrade of Farwing is an upgrade of this
# image too.
FROM ghcr.io/farwing-io/server:1

# The Farwing image is Debian, so ffmpeg comes from Debian's own package.
# The image starts as root and its entrypoint hands over to the unprivileged
# farwing user before the server runs. That is why this file has no USER line:
# installing a package needs root, and commands from your rules still run as
# farwing.
#
# --no-install-recommends keeps out optional extras that a server does not
# need, so the image grows by as little as possible.
# Removing the package lists in the same step keeps them out of the image
# layer.
RUN apt-get update \
    && apt-get install -y --no-install-recommends ffmpeg \
    && rm -rf /var/lib/apt/lists/*

What each part does:

  • FROM ghcr.io/farwing-io/server:1 starts from the Farwing image you already run, so you add to it and replace nothing. Use the same tag as your compose file.
  • RUN apt-get update … installs ffmpeg from Debian's package list, which is what the Farwing image is built on. It is one step so that the package lists are removed before the layer is saved.
  • --no-install-recommends installs ffmpeg and what it needs, not optional extras.
  • There is no USER line on purpose. The image starts as root and its entrypoint hands over to the unprivileged farwing user before the server starts. A USER line would stop the entrypoint from preparing your mounted folders.

To add a different tool, change ffmpeg to the name of any Debian package, or list several names. The rest stays the same.

Build and run it

With Docker Compose, give the farwing service a build section in place of the image line:

services:
  farwing:
    build:
      context: .
      dockerfile: Dockerfile.ffmpeg
    image: farwing-ffmpeg:1
    container_name: farwing
    network_mode: host
    command: ["serve"]
    restart: unless-stopped
    volumes:
      - /data:/data
      - /srv/files:/files
      - /srv/scripts:/scripts

The /srv/scripts line is the folder where you keep scripts for command steps. It appears inside the container as /scripts. Then build the image and start it:

docker compose build --pull
docker compose up -d

Without Compose, build the image and run it with the same options as before:

docker build -f Dockerfile.ffmpeg -t farwing-ffmpeg:1 .
docker run -d --name farwing --network host --restart unless-stopped \
  -v /data:/data -v /srv/files:/files -v /srv/scripts:/scripts \
  farwing-ffmpeg:1 serve

--pull fetches the newest Farwing image of your tag before it builds. Run the build again whenever you upgrade Farwing, so your image has the new version.

Check that the tool is reachable

Rules run commands as the farwing user, so check as that user. From the folder that holds compose.yml:

docker compose exec --user farwing farwing ffmpeg -version

You should see ffmpeg's version. If Docker says the command was not found, the container is still running the old image. Run the build again and restart it.

What this unlocks: preview copies

The ready-made rule Convert new videos to small H.264 preview copies needs ffmpeg. With the image above, it works. You can also write your own script. This one makes a small preview next to each video that a rule hands to it:

#!/bin/sh
# /scripts/make-preview.sh
# Makes a small H.264 preview next to each video a rule hands to it.
set -eu
in="$FARWING_FILE_PATH"
out="${in%.*}-preview.mp4"
# -nostdin stops ffmpeg from reading the event JSON that arrives on standard input.
ffmpeg -nostdin -y -i "$in" -c:v libx264 -preset fast -crf 28 -vf "scale=-2:540" -c:a aac -b:a 96k "$out"

Save it as /srv/scripts/make-preview.sh on the host and make it executable with chmod +x. Use /scripts/make-preview.sh as the command of a Run a command step. Only an administrator can save a rule with a command step.

If the rule watches the folder the script writes to, add a condition that leaves the preview files out, so the rule does not start on its own output. Run a dry run first, as Event rules describes.