Skip to content
Merged
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added ability to define more groups to take care of ACLs, so that our non-root user can delete files on host systems, if desired. New environment variable `EXTRA_GROUPS` [#234](https://github.com/pSpitzner/beets-flask/issues/234)
- The inbox info button now has a description of all actions [#145](https://github.com/pSpitzner/beets-flask/issues/145)
- Subpage for version information and configs. You can access it via the version number in the navbar. [#205](https://github.com/pSpitzner/beets-flask/issues/205)
- New config option `gui.inbox.debounce_before_autotag` to configure how many seconds to wait after the last filesystem event before starting autotagging. Same debounce applies to all inboxes. [#222](https://github.com/pSpitzner/beets-flask/issues/222)
- The library view on mobile now has a button to collapse the overview (above the tabs). This allows for more space when browsing the library on small screens.
- The library view on mobile now has a button to collapse the overview (above the tabs). This allows for more space when browsing the library on small screens.

### Other (dev)

Expand Down
20 changes: 2 additions & 18 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,10 @@ WORKDIR /repo
USER root
ENTRYPOINT [ \
"/bin/sh", "-c", \
"./docker/entrypoints/entrypoint_fix_permissions.sh && \
"./docker/entrypoints/entrypoint_fix_permissions.sh && \
su beetle -c ./docker/entrypoints/entrypoint_dev.sh" \
]

# ------------------------------------------------------------------------------------ #
# Testing #
# ------------------------------------------------------------------------------------ #

FROM deps AS test

WORKDIR /repo
COPY --from=deps --chown=beetle:beetle /repo /repo
COPY entrypoint_test.sh .
ENV IB_SERVER_CONFIG="test"
USER root
ENTRYPOINT ["./entrypoint_test.sh"]

# ------------------------------------------------------------------------------------ #
# Build #
# ------------------------------------------------------------------------------------ #
Expand Down Expand Up @@ -163,10 +150,7 @@ ENV IB_SERVER_CONFIG="prod"
WORKDIR /repo
COPY --from=build /repo/frontend/dist /repo/frontend/dist
COPY --from=build /version /version
COPY docker/entrypoints/entrypoint.sh .
COPY docker/entrypoints/entrypoint_user_scripts.sh .
COPY docker/entrypoints/entrypoint_fix_permissions.sh .
COPY docker/entrypoints/common.sh .
COPY docker/entrypoints .
RUN chown -R beetle:beetle /repo

USER root
Expand Down
3 changes: 3 additions & 0 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ services:
# 502 is default on macos, 1000 on linux
USER_ID: 1000
GROUP_ID: 1000
# Optional: Add extra groups to the beetle user for file permissions
# Format: "group_name1:gid1,group_name2:gid2"
# Example: EXTRA_GROUPS: "nas_shares:1001,media:1002"
volumes:
- /wherever/config/:/config
# for music folders, match paths inside and out of container!
Expand Down
8 changes: 6 additions & 2 deletions docker/entrypoints/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ log_error() {
echo -e "\033[0;31m[Entrypoint] $1\033[0m"
}

log_warning() {
echo -e "\033[0;33m[Entrypoint] $1\033[0m"
}

log_current_user() {
log "Running as '$(whoami)' with UID $(id -u) and GID $(id -g)"
log "Current working directory: $(pwd)"
Expand All @@ -26,7 +30,7 @@ get_version_info() {
else
export BACKEND_VERSION="unk"
fi

if [ -f /version/frontend.txt ]; then
export FRONTEND_VERSION=$(cat /version/frontend.txt)
else
Expand All @@ -35,4 +39,4 @@ get_version_info() {
}

# Populate the environment variables for the version info
get_version_info
get_version_info
65 changes: 65 additions & 0 deletions docker/entrypoints/entrypoint_add_groups.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

# this script runs both, in dev and in prod, so we have to check where we
# can source common.sh from.
if [ -f ./common.sh ]; then
source ./common.sh
elif [ -f ./docker/entrypoints/common.sh ]; then
source ./docker/entrypoints/common.sh
fi


# ---------------------------------- Helper ---------------------------------- #

validate_and_add_groups() {
local group_specs
IFS=',' read -ra group_specs <<< "$1"

for spec in "${group_specs[@]}"; do
if [[ "$spec" =~ ^([a-z][a-z0-9_-]*):([0-9]+)$ ]]; then
local group_name="${BASH_REMATCH[1]}"
local gid="${BASH_REMATCH[2]}"

process_group "$group_name" "$gid" || continue
else
log_warning "Invalid group specification '$spec', skipping. Format should be 'group_name:gid' where group_name starts with lowercase letter"
fi
done
}

process_group() {
local group_name="$1"
local gid="$2"

# Handle existing group
if existing_group=$(getent group "$group_name" 2>/dev/null); then
local existing_gid=$(cut -d: -f3 <<< "$existing_group")
[[ "$existing_gid" != "$gid" ]] && \
log_warning "Group '$group_name' exists with GID $existing_gid (expected $gid). Using existing group."
log "Group '$group_name' already exists, skipping creation"
else
addgroup -g "$gid" "$group_name" 2>/dev/null || {
log_warning "Failed to create group '$group_name' with gid $gid"
return 1
}
log "Created group '$group_name' with gid $gid"
fi

# Add user to group
if id -nG beetle 2>/dev/null | grep -qw "$group_name"; then
log "User beetle is already a member of group '$group_name'"
else
adduser beetle "$group_name" 2>/dev/null || {
log_warning "Failed to add beetle user to group '$group_name'"
return 1
}
log "Added beetle user to group '$group_name'"
fi
}

# --------------------------------- Main Loop -------------------------------- #

if [[ -n "$EXTRA_GROUPS" ]]; then
log "Adding extra groups to beetle user: $EXTRA_GROUPS"
validate_and_add_groups "$EXTRA_GROUPS"
fi

29 changes: 25 additions & 4 deletions docker/entrypoints/entrypoint_fix_permissions.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
#!/bin/sh
#!/bin/bash

# this script runs both, in dev and in prod, so we have to check where we
# can source common.sh from.
if [ -f ./common.sh ]; then
source ./common.sh
elif [ -f ./docker/entrypoints/common.sh ]; then
source ./docker/entrypoints/common.sh
fi

if [ ! -z "$USER_ID" ] && [ ! -z "$GROUP_ID" ]; then
log "Fixing permissions as '$(whoami)' with UID $(id -u) and GID $(id -g)"
log "Setting beetle user to $USER_ID:$GROUP_ID"
groupmod -g $GROUP_ID beetle
usermod -u $USER_ID -g $GROUP_ID beetle > /dev/null 2>&1
chown -R beetle:beetle /home/beetle
chown -R beetle:beetle /repo
chown -R beetle:beetle /logs
log "User beetle now has $(id beetle)"
find /home/beetle ! -user beetle -exec chown beetle:beetle {} +
find /logs ! -user beetle -exec chown beetle:beetle {} +
find /repo ! -user beetle -exec chown beetle:beetle {} +
log "Done fixing permissions"
else
log "No USER_ID and GROUP_ID set, skipping permission updates"
fi

# add groups
if [ -f ./entrypoint_add_groups.sh ]; then
source ./entrypoint_add_groups.sh
elif [ -f ./docker/entrypoints/entrypoint_add_groups.sh ]; then
source ./docker/entrypoints/entrypoint_add_groups.sh
fi
24 changes: 0 additions & 24 deletions docker/entrypoints/entrypoint_test.sh

This file was deleted.

40 changes: 40 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,43 @@ You can use multiple workers to fetch candidates before importing (previewing).
However, the import itself is always done sequentially.
This is to ensure that the import process is not interrupted by other operations.
```

## Docker Environment Variables

These environment variables are set in the `docker-compose.yaml` file and control the container's behavior.

### `USER_ID` and `GROUP_ID`

The `USER_ID` and `GROUP_ID` environment variables are used to set the UID and GID of the `beetle` user inside the container. This is useful to match the user and group IDs of the host system. The default value is `1000` for both.

```yaml
environment:
USER_ID: 1000
GROUP_ID: 1000
```

### `EXTRA_GROUPS`

The `EXTRA_GROUPS` environment variable allows you to add additional groups to the `beetle` user. This is useful when you need the container to have access to files owned by different groups on the host system.

The format is a comma-separated list of `group_name:gid` pairs:

```yaml
environment:
EXTRA_GROUPS: "nas_shares:1001,media:1002"
```

This is particularly useful in scenarios where:
- Files in the inbox are created by external services running as different users/groups
- You're using ACL-based permissions with specific group access
- You're running in environments like LXC/Proxmox with mapped group IDs
- You need the container to manage files from network shares with specific group ownership

Example: If your download client (e.g., slskd, transmission) creates files with group ownership `nas_shares` (gid 1001), you can add that group to the beetle user:

```yaml
environment:
EXTRA_GROUPS: "nas_shares:1001"
```

This will allow the beets-flask container to delete and manage those files via the web UI.