Strange folder permissions for docker containers that use databases

  • DietPi version |
    G_DIETPI_VERSION_CORE=9
    G_DIETPI_VERSION_SUB=3
    G_DIETPI_VERSION_RC=0
    G_GITBRANCH=‘master’
    G_GITOWNER=‘MichaIng’

  • Distro version
    bookworm

  • Kernel version
    Linux DietPi-Proxmox 6.1.0-20-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.85-1 (2024-04-11) x86_64 GNU/Linux

  • Architecture
    amd64

  • SBC model
    Virtual Machine (x86_64)

  • Software title: Photoprism, Miniflux, probably anything that uses a database in a Docker container.

  • Was the software title installed freshly or updated/migrated?
    Freshly installed on main VM, and also a testing VM

  • Can this issue be replicated on a fresh installation of DietPi?
    Yes

Steps to reproduce

Started a new Photoprism or Miniflux container via docker-compose.yml, nothing special in it, I don’t have anything like UIDs or IDs defined. Then sudo docker compose up -d. I did later try uncommenting the UIDs in photoprism’s docker compose (e.g. UID:1000) but this had no effect.

Most folders get created with the dietpi:dietpi permissions, that’s fine, but the database folder and the contents of it are all using a permission of pihole:systemd-journal on my main VM, in the test VM it is jackett:systemd-journal

total 185M
drwxr-xr-x 6 jackett systemd-journal 4.0K May  5 12:07 .
drwxr-xr-x 6 dietpi  dietpi          4.0K May  5 12:07 ..
-rw------- 1 jackett systemd-journal  131 May  5 12:07 .my-healthcheck.cnf
-rw-rw---- 1 jackett systemd-journal 416K May  5 12:07 aria_log.00000001
-rw-rw---- 1 jackett systemd-journal   52 May  5 12:07 aria_log_control
-rw-rw---- 1 jackett systemd-journal  16K May  5 12:07 ddl_recovery.log
-rw-rw---- 1 jackett systemd-journal  828 May  5 12:07 ib_buffer_pool
-rw-rw---- 1 jackett systemd-journal  96M May  5 12:22 ib_logfile0
-rw-rw---- 1 jackett systemd-journal  76M May  5 12:07 ibdata1
-rw-rw---- 1 jackett systemd-journal  12M May  5 12:07 ibtmp1
-rw-rw---- 1 jackett systemd-journal    0 May  5 12:07 multi-master.info
drwx------ 2 jackett systemd-journal 4.0K May  5 12:07 mysql
-rw-r--r-- 1 jackett systemd-journal   15 May  5 12:07 mysql_upgrade_info
drwx------ 2 jackett systemd-journal 4.0K May  5 12:07 performance_schema
drwx------ 2 jackett systemd-journal 4.0K May  5 12:07 photoprism
drwx------ 2 jackett systemd-journal  12K May  5 12:07 sys

Expected behaviour

I’m unsure if this is normal, shouldn’t they be root:root? What would happen if pihole or jackett was uninstalled - would it break the docker containers that are running?

Which folder is this? Can you share the path? And your docker compose file?

I keep all docker-compose.yml files and their bind mounts in individual folders at /home/dietpi/docker/
The database folder in /home/dietpi/docker/pp/ gets the strange permissions.
This is my docker-compose.yml in /home/dietpi/docker/pp:

services:
  photoprism:
    ## Use photoprism/photoprism:preview for testing preview builds:
    image: photoprism/photoprism:latest # https://hub.docker.com/r/photoprism/photoprism/tags
    container_name: photoprism
    depends_on:
      - mariadb
    ## Don't enable automatic restarts until PhotoPrism has been properly configured and tested!
    ## If the service gets stuck in a restart loop, this points to a memory, filesystem, network, or database issue:
    ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
    restart: unless-stopped
    stop_grace_period: 10s
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    ports:
      - "2342:2342" # HTTP port (host:container)
    environment:
      PHOTOPRISM_ADMIN_USER: "admin"                 # superadmin username
      PHOTOPRISM_ADMIN_PASSWORD: "insecure"          # initial superadmin password (minimum 8 characters)
      PHOTOPRISM_AUTH_MODE: "password"               # authentication mode (public, password)
      PHOTOPRISM_WORKERS: 2
      PHOTOPRISM_SITE_URL: "https://removed"  # server URL in the format "http(s)://domain.name(:port)/(path)"
      PHOTOPRISM_ORIGINALS_LIMIT: 5000               # file size limit for originals in MB (increase for high-res video)
      PHOTOPRISM_HTTP_COMPRESSION: "gzip"            # improves transfer speed and bandwidth utilization (none or gzip)
      PHOTOPRISM_LOG_LEVEL: "info"                   # log level: trace, debug, info, warning, error, fatal, or panic
      PHOTOPRISM_READONLY: "false"                   # do not modify originals directory (reduced functionality)
      PHOTOPRISM_EXPERIMENTAL: "false"               # enables experimental features
      PHOTOPRISM_DISABLE_CHOWN: "false"              # disables updating storage permissions via chmod and chown on startup
      PHOTOPRISM_DISABLE_WEBDAV: "false"             # disables built-in WebDAV server
      PHOTOPRISM_DISABLE_SETTINGS: "false"           # disables settings UI and API
      PHOTOPRISM_DISABLE_TENSORFLOW: "false"         # disables all features depending on TensorFlow
      PHOTOPRISM_DISABLE_FACES: "false"              # disables face detection and recognition (requires TensorFlow)
      PHOTOPRISM_DISABLE_CLASSIFICATION: "false"     # disables image classification (requires TensorFlow)
      PHOTOPRISM_DISABLE_VECTORS: "false"            # disables vector graphics support
      PHOTOPRISM_DISABLE_RAW: "false"                # disables indexing and conversion of RAW files
      PHOTOPRISM_DISABLE_TLS: "true"                 # Manually added by me. Recommended if running PP behind reverse proxy.
      PHOTOPRISM_RAW_PRESETS: "false"                # enables applying user presets when converting RAW files (reduces performance)
      PHOTOPRISM_JPEG_QUALITY: 85                    # a higher value increases the quality and file size of JPEG images and thumbnails (25-100)
      PHOTOPRISM_DETECT_NSFW: "false"                # automatically flags photos as private that MAY be offensive (requires TensorFlow)
      PHOTOPRISM_UPLOAD_NSFW: "true"                 # allows uploads that MAY be offensive (no effect without TensorFlow)
      # PHOTOPRISM_DATABASE_DRIVER: "sqlite"         # SQLite is an embedded database that doesn't require a server
      PHOTOPRISM_DATABASE_DRIVER: "mysql"            # use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
      PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"     # MariaDB or MySQL database server (hostname:port)
      PHOTOPRISM_DATABASE_NAME: "photoprism"         # MariaDB or MySQL database schema name
      PHOTOPRISM_DATABASE_USER: "photoprism"         # MariaDB or MySQL database user name
      PHOTOPRISM_DATABASE_PASSWORD: "insecure"       # MariaDB or MySQL database user password
      PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
      PHOTOPRISM_SITE_DESCRIPTION: ""                # meta site description
      PHOTOPRISM_SITE_AUTHOR: ""                     # meta site author
      ## Run/install on first startup (options: update https gpu tensorflow davfs clitools clean):
      # PHOTOPRISM_INIT: "https gpu tensorflow"
      ## Hardware Video Transcoding:
      # PHOTOPRISM_FFMPEG_ENCODER: "software"        # FFmpeg encoder ("software", "intel", "nvidia", "apple", "raspberry")
      # PHOTOPRISM_FFMPEG_BITRATE: "32"              # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
      ## Run as a non-root user after initialization (supported: 0, 33, 50-99, 500-600, and 900-1200):
      # PHOTOPRISM_UID: 1000
      # PHOTOPRISM_GID: 1000
      # PHOTOPRISM_UMASK: 0000
    ## Start as non-root user before initialization (supported: 0, 33, 50-99, 500-600, and 900-1200):
      # user: "1000:1000"
    ## Share hardware devices with FFmpeg and TensorFlow (optional):
    # devices:
    #  - "/dev/dri:/dev/dri"                         # Intel QSV
    #  - "/dev/nvidia0:/dev/nvidia0"                 # Nvidia CUDA
    #  - "/dev/nvidiactl:/dev/nvidiactl"
    #  - "/dev/nvidia-modeset:/dev/nvidia-modeset"
    #  - "/dev/nvidia-nvswitchctl:/dev/nvidia-nvswitchctl"
    #  - "/dev/nvidia-uvm:/dev/nvidia-uvm"
    #  - "/dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools"
    #  - "/dev/video11:/dev/video11"                 # Video4Linux Video Encode Device (h264_v4l2m2m)
    working_dir: "/photoprism" # do not change or remove
    ## Storage Folders: "~" is a shortcut for your home directory, "." for the current directory
    volumes:
      # "/host/folder:/photoprism/folder"                # Example
      # "~/Pictures:/photoprism/originals"               # Original media files (DO NOT REMOVE)
      # - "/example/family:/photoprism/originals/family" # *Additional* media folders can be mounted like this
      # - "~/Import:/photoprism/import"                  # *Optional* base folder from which files can be imported to originals
      # "./storage:/photoprism/storage"                  # *Writable* storage folder for cache, database, and sidecar files (DO NOT REMOVE)
      - "./storage:/photoprism/storage"                  # *writable* storage folder for cache, database, and sidecar files (never remove)
      - "./originals:/photoprism/originals"
      - "./import:/photoprism/import"
  ## Database Server (recommended)
  ## see https://docs.photoprism.app/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
  mariadb:
    ## If MariaDB gets stuck in a restart loop, this points to a memory or filesystem issue:
    ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
    restart: unless-stopped
    stop_grace_period: 5s
    image: mariadb:10.10 #or try 10.11
    container_name: photoprism-db
    security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239
      - seccomp:unconfined
      - apparmor:unconfined
    command: mysqld --innodb-buffer-pool-size=512M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
    ## Never store database files on an unreliable device such as a USB flash drive, an SD card, or a shared network folder:
    volumes:
      - "./database:/var/lib/mysql" # DO NOT REMOVE
    environment:
      MARIADB_AUTO_UPGRADE: "1"
      MARIADB_INITDB_SKIP_TZINFO: "1"
      MARIADB_DATABASE: "photoprism"
      MARIADB_USER: "photoprism"
      MARIADB_PASSWORD: "insecure"
      MARIADB_ROOT_PASSWORD: "insecure"

Or Miniflux for something simpler?:

services:
  miniflux:
    image: miniflux/miniflux:2.1.3 # https://hub.docker.com/r/miniflux/miniflux/tags
    container_name: miniflux
    ports:
      - "9401:8080"
    restart: unless-stopped
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgres://miniflux:secret@db/miniflux?sslmode=disable
      - RUN_MIGRATIONS=1
      - CREATE_ADMIN=1
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=test123

  db:
    image: postgres:15
    container_name: miniflux-db
    environment:
      - POSTGRES_USER=miniflux
      - POSTGRES_PASSWORD=secret
    volumes:
      - /home/dietpi/docker/miniflux/miniflux-db:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "miniflux"]
      interval: 10s
      start_period: 30s

What does

grep systemd-journal /etc/group
grep jacket /etc/passwd

say?

systemd-journal:x:999:
jackett:x:999:996::/opt/jackett:/usr/sbin/nologin

it shows as
pihole:x:999:1001::/home/pihole:/usr/sbin/nologin
on the other VM

It’s user ID 999 in both case. Maybe a behaviour of the container to use user ID 999 if non is set. Something that could be verified with the maintainer of the container

I guess this is normal to happen, found a thread about this after using 999 as one of my search terms: https://www.reddit.com/r/docker/comments/nxbwbc/wordpress_installing_question_about_uid_999_on/

Probably you can specify a user ID within your Docker configuration file

This topic was automatically closed 178 days after the last reply. New replies are no longer allowed.