Skip to content

Commit fcf6b72

Browse files
djdubdCopilotCopilotpSpitzner
authored
Added ability to define more groups to take care of ACLs. New EXTRA_GROUPS env var (#239)
- Add EXTRA_GROUPS support for beetle user permissions - Update docker/entrypoints/entrypoint_fix_permissions.sh - Add group name validation - Warn user if named group exists with different gid - Add explicit check for user having existing group membership. - Added changelog entry - Separated group_add into its own entrypoint script (called by fix_permissions one) - Split group_add logic into two functions - Removed old Testing parts from Dockerfile and entrypoint - Improved chown performance on macos closes #234 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: djdubd <2773193+djdubd@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: pSpitzner <github@makeitso.one>
1 parent c67cc86 commit fcf6b72

File tree

8 files changed

+143
-49
lines changed

8 files changed

+143
-49
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2626

2727
### Added
2828

29+
- 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)
2930
- The inbox info button now has a description of all actions [#145](https://github.com/pSpitzner/beets-flask/issues/145)
3031
- 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)
3132
- 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)
32-
- 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.
33+
- 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.
3334

3435
### Other (dev)
3536

docker/Dockerfile

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,10 @@ WORKDIR /repo
103103
USER root
104104
ENTRYPOINT [ \
105105
"/bin/sh", "-c", \
106-
"./docker/entrypoints/entrypoint_fix_permissions.sh && \
106+
"./docker/entrypoints/entrypoint_fix_permissions.sh && \
107107
su beetle -c ./docker/entrypoints/entrypoint_dev.sh" \
108108
]
109109

110-
# ------------------------------------------------------------------------------------ #
111-
# Testing #
112-
# ------------------------------------------------------------------------------------ #
113-
114-
FROM deps AS test
115-
116-
WORKDIR /repo
117-
COPY --from=deps --chown=beetle:beetle /repo /repo
118-
COPY entrypoint_test.sh .
119-
ENV IB_SERVER_CONFIG="test"
120-
USER root
121-
ENTRYPOINT ["./entrypoint_test.sh"]
122-
123110
# ------------------------------------------------------------------------------------ #
124111
# Build #
125112
# ------------------------------------------------------------------------------------ #
@@ -163,10 +150,7 @@ ENV IB_SERVER_CONFIG="prod"
163150
WORKDIR /repo
164151
COPY --from=build /repo/frontend/dist /repo/frontend/dist
165152
COPY --from=build /version /version
166-
COPY docker/entrypoints/entrypoint.sh .
167-
COPY docker/entrypoints/entrypoint_user_scripts.sh .
168-
COPY docker/entrypoints/entrypoint_fix_permissions.sh .
169-
COPY docker/entrypoints/common.sh .
153+
COPY docker/entrypoints .
170154
RUN chown -R beetle:beetle /repo
171155

172156
USER root

docker/docker-compose.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ services:
1010
# 502 is default on macos, 1000 on linux
1111
USER_ID: 1000
1212
GROUP_ID: 1000
13+
# Optional: Add extra groups to the beetle user for file permissions
14+
# Format: "group_name1:gid1,group_name2:gid2"
15+
# Example: EXTRA_GROUPS: "nas_shares:1001,media:1002"
1316
volumes:
1417
- /wherever/config/:/config
1518
# for music folders, match paths inside and out of container!

docker/entrypoints/common.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ log_error() {
88
echo -e "\033[0;31m[Entrypoint] $1\033[0m"
99
}
1010

11+
log_warning() {
12+
echo -e "\033[0;33m[Entrypoint] $1\033[0m"
13+
}
14+
1115
log_current_user() {
1216
log "Running as '$(whoami)' with UID $(id -u) and GID $(id -g)"
1317
log "Current working directory: $(pwd)"
@@ -26,7 +30,7 @@ get_version_info() {
2630
else
2731
export BACKEND_VERSION="unk"
2832
fi
29-
33+
3034
if [ -f /version/frontend.txt ]; then
3135
export FRONTEND_VERSION=$(cat /version/frontend.txt)
3236
else
@@ -35,4 +39,4 @@ get_version_info() {
3539
}
3640

3741
# Populate the environment variables for the version info
38-
get_version_info
42+
get_version_info
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
# this script runs both, in dev and in prod, so we have to check where we
3+
# can source common.sh from.
4+
if [ -f ./common.sh ]; then
5+
source ./common.sh
6+
elif [ -f ./docker/entrypoints/common.sh ]; then
7+
source ./docker/entrypoints/common.sh
8+
fi
9+
10+
11+
# ---------------------------------- Helper ---------------------------------- #
12+
13+
validate_and_add_groups() {
14+
local group_specs
15+
IFS=',' read -ra group_specs <<< "$1"
16+
17+
for spec in "${group_specs[@]}"; do
18+
if [[ "$spec" =~ ^([a-z][a-z0-9_-]*):([0-9]+)$ ]]; then
19+
local group_name="${BASH_REMATCH[1]}"
20+
local gid="${BASH_REMATCH[2]}"
21+
22+
process_group "$group_name" "$gid" || continue
23+
else
24+
log_warning "Invalid group specification '$spec', skipping. Format should be 'group_name:gid' where group_name starts with lowercase letter"
25+
fi
26+
done
27+
}
28+
29+
process_group() {
30+
local group_name="$1"
31+
local gid="$2"
32+
33+
# Handle existing group
34+
if existing_group=$(getent group "$group_name" 2>/dev/null); then
35+
local existing_gid=$(cut -d: -f3 <<< "$existing_group")
36+
[[ "$existing_gid" != "$gid" ]] && \
37+
log_warning "Group '$group_name' exists with GID $existing_gid (expected $gid). Using existing group."
38+
log "Group '$group_name' already exists, skipping creation"
39+
else
40+
addgroup -g "$gid" "$group_name" 2>/dev/null || {
41+
log_warning "Failed to create group '$group_name' with gid $gid"
42+
return 1
43+
}
44+
log "Created group '$group_name' with gid $gid"
45+
fi
46+
47+
# Add user to group
48+
if id -nG beetle 2>/dev/null | grep -qw "$group_name"; then
49+
log "User beetle is already a member of group '$group_name'"
50+
else
51+
adduser beetle "$group_name" 2>/dev/null || {
52+
log_warning "Failed to add beetle user to group '$group_name'"
53+
return 1
54+
}
55+
log "Added beetle user to group '$group_name'"
56+
fi
57+
}
58+
59+
# --------------------------------- Main Loop -------------------------------- #
60+
61+
if [[ -n "$EXTRA_GROUPS" ]]; then
62+
log "Adding extra groups to beetle user: $EXTRA_GROUPS"
63+
validate_and_add_groups "$EXTRA_GROUPS"
64+
fi
65+
Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
1-
#!/bin/sh
1+
#!/bin/bash
2+
3+
# this script runs both, in dev and in prod, so we have to check where we
4+
# can source common.sh from.
5+
if [ -f ./common.sh ]; then
6+
source ./common.sh
7+
elif [ -f ./docker/entrypoints/common.sh ]; then
8+
source ./docker/entrypoints/common.sh
9+
fi
210

311
if [ ! -z "$USER_ID" ] && [ ! -z "$GROUP_ID" ]; then
12+
log "Fixing permissions as '$(whoami)' with UID $(id -u) and GID $(id -g)"
13+
log "Setting beetle user to $USER_ID:$GROUP_ID"
414
groupmod -g $GROUP_ID beetle
515
usermod -u $USER_ID -g $GROUP_ID beetle > /dev/null 2>&1
6-
chown -R beetle:beetle /home/beetle
7-
chown -R beetle:beetle /repo
8-
chown -R beetle:beetle /logs
16+
log "User beetle now has $(id beetle)"
17+
find /home/beetle ! -user beetle -exec chown beetle:beetle {} +
18+
find /logs ! -user beetle -exec chown beetle:beetle {} +
19+
find /repo ! -user beetle -exec chown beetle:beetle {} +
20+
log "Done fixing permissions"
21+
else
22+
log "No USER_ID and GROUP_ID set, skipping permission updates"
23+
fi
24+
25+
# add groups
26+
if [ -f ./entrypoint_add_groups.sh ]; then
27+
source ./entrypoint_add_groups.sh
28+
elif [ -f ./docker/entrypoints/entrypoint_add_groups.sh ]; then
29+
source ./docker/entrypoints/entrypoint_add_groups.sh
930
fi

docker/entrypoints/entrypoint_test.sh

Lines changed: 0 additions & 24 deletions
This file was deleted.

docs/configuration.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,43 @@ You can use multiple workers to fetch candidates before importing (previewing).
154154
However, the import itself is always done sequentially.
155155
This is to ensure that the import process is not interrupted by other operations.
156156
```
157+
158+
## Docker Environment Variables
159+
160+
These environment variables are set in the `docker-compose.yaml` file and control the container's behavior.
161+
162+
### `USER_ID` and `GROUP_ID`
163+
164+
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.
165+
166+
```yaml
167+
environment:
168+
USER_ID: 1000
169+
GROUP_ID: 1000
170+
```
171+
172+
### `EXTRA_GROUPS`
173+
174+
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.
175+
176+
The format is a comma-separated list of `group_name:gid` pairs:
177+
178+
```yaml
179+
environment:
180+
EXTRA_GROUPS: "nas_shares:1001,media:1002"
181+
```
182+
183+
This is particularly useful in scenarios where:
184+
- Files in the inbox are created by external services running as different users/groups
185+
- You're using ACL-based permissions with specific group access
186+
- You're running in environments like LXC/Proxmox with mapped group IDs
187+
- You need the container to manage files from network shares with specific group ownership
188+
189+
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:
190+
191+
```yaml
192+
environment:
193+
EXTRA_GROUPS: "nas_shares:1001"
194+
```
195+
196+
This will allow the beets-flask container to delete and manage those files via the web UI.

0 commit comments

Comments
 (0)