-
-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathdocker-entrypoint.sh
More file actions
165 lines (138 loc) · 5.04 KB
/
Copy pathdocker-entrypoint.sh
File metadata and controls
165 lines (138 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/bin/bash
set -e
# Default values
PUID=${PUID:-99}
PGID=${PGID:-100}
UMASK=${UMASK:-}
is_numeric() {
[[ "$1" =~ ^[0-9]+$ ]]
}
is_umask() {
[[ "$1" =~ ^0?[0-7]{3}$ ]]
}
if ! is_numeric "$PUID"; then
echo "Error: PUID must be numeric (got: '$PUID')"
exit 1
fi
if ! is_numeric "$PGID"; then
echo "Error: PGID must be numeric (got: '$PGID')"
exit 1
fi
if [ -n "$UMASK" ]; then
if ! is_umask "$UMASK"; then
echo "Error: UMASK must be an octal mask like 022, 002, or 0002 (got: '$UMASK')"
exit 1
fi
umask "$UMASK"
fi
DATA_DIR="/config"
for arg in "$@"; do
case "$arg" in
-data=*|/data=*|--data=*)
DATA_DIR="${arg#*=}"
;;
esac
done
echo "================================"
echo "Chaptarr Docker Entrypoint"
echo "PUID: $PUID"
echo "PGID: $PGID"
echo "UMASK: $(umask)"
echo "DATA_DIR: $DATA_DIR"
echo "================================"
# Function to safely change ownership
safe_chown() {
local path="$1"
local uid="$2"
local gid="$3"
# Check if path exists
if [ ! -e "$path" ]; then
return 0
fi
# Get current ownership
local current_uid=$(stat -c "%u" "$path" 2>/dev/null || echo "-1")
local current_gid=$(stat -c "%g" "$path" 2>/dev/null || echo "-1")
# Only chown if needed
if [ "$current_uid" != "$uid" ] || [ "$current_gid" != "$gid" ]; then
# Try to change ownership, but don't fail if it doesn't work
if chown "$uid:$gid" "$path" 2>/dev/null; then
echo "Changed ownership of $path to $uid:$gid"
else
echo "Warning: Could not change ownership of $path (may be read-only or permission denied)"
fi
fi
}
# Only run user management if we're root
if [ "$EUID" -eq 0 ]; then
echo "Running as root, setting up user..."
# Handle special case: root user requested
if [ "$PUID" -eq 0 ] || [ "$PGID" -eq 0 ]; then
echo "Warning: Running as root (UID 0) is not recommended for security reasons"
exec "$@"
fi
# Create or modify group
if getent group "$PGID" >/dev/null 2>&1; then
echo "Group with GID $PGID already exists"
groupname=$(getent group "$PGID" | cut -d: -f1)
else
echo "Creating group 'abc' with GID $PGID"
groupadd -g "$PGID" abc
groupname="abc"
fi
# Create or modify user
if getent passwd "$PUID" >/dev/null 2>&1; then
echo "User with UID $PUID already exists"
username=$(getent passwd "$PUID" | cut -d: -f1)
# Update group if needed
if [ "$(id -g "$username")" != "$PGID" ]; then
usermod -g "$PGID" "$username" 2>/dev/null || true
fi
else
echo "Creating user 'abc' with UID $PUID and GID $PGID"
useradd -u "$PUID" -g "$PGID" -d /config -s /bin/bash abc
username="abc"
fi
# Ensure config directory exists
mkdir -p "$DATA_DIR"
# Smart ownership management - only change what's needed
echo "Checking $DATA_DIR ownership..."
# First, check if we can even write to the parent directory
if touch "$DATA_DIR"/.write_test 2>/dev/null; then
rm -f "$DATA_DIR"/.write_test
# Only fix ownership of key files/directories that Chaptarr creates
for item in "$DATA_DIR" "$DATA_DIR"/*.db "$DATA_DIR"/logs "$DATA_DIR"/MediaCover "$DATA_DIR"/Backups; do
safe_chown "$item" "$PUID" "$PGID"
done
# Don't recursively chown everything - that's too aggressive
# Users can manually fix other files if needed
else
echo "Warning: $DATA_DIR appears to be read-only or access denied"
echo "Chaptarr may not be able to write configuration files"
fi
echo "Starting Chaptarr as user $username (UID=$PUID, GID=$PGID)"
gosu "$username" sh -c 'echo "Effective runtime user: $(id)"; echo "Effective runtime umask: $(umask)"'
# Use gosu to properly drop privileges and run the command
# This ensures signals are properly forwarded and the process runs as expected
exec gosu "$username" "$@"
else
# Not running as root
echo "Not running as root, executing directly"
echo "Warning: Unable to change file ownership. Ensure your files have correct permissions."
echo "Effective runtime user: $(id)"
echo "Effective runtime umask: $(umask)"
if [ ! -d "$DATA_DIR" ]; then
if ! mkdir -p "$DATA_DIR" 2>/dev/null; then
echo "Error: Data directory '$DATA_DIR' does not exist and cannot be created."
echo "Mount a writable volume to '$DATA_DIR' or run the container as root with PUID/PGID so it can create/chown it."
exit 1
fi
fi
if touch "$DATA_DIR"/.write_test 2>/dev/null; then
rm -f "$DATA_DIR"/.write_test
else
echo "Error: Data directory '$DATA_DIR' is not writable by UID=$(id -u) GID=$(id -g)."
echo "If you're using a bind mount and the host folder didn't exist, Docker created it as root:root; create it manually (or fix ownership) and try again."
exit 1
fi
exec "$@"
fi