rootless init

This commit is contained in:
Anthony Stirling
2025-05-20 21:37:03 +01:00
parent 70349fb7e3
commit 9753221e31
5 changed files with 301 additions and 27 deletions

View File

@@ -3,38 +3,85 @@
export JAVA_TOOL_OPTIONS="${JAVA_BASE_OPTS} ${JAVA_CUSTOM_OPTS}"
echo "running with JAVA_TOOL_OPTIONS ${JAVA_BASE_OPTS} ${JAVA_CUSTOM_OPTS}"
# Update the user and group IDs as per environment variables
if [ ! -z "$PUID" ] && [ "$PUID" != "$(id -u stirlingpdfuser)" ]; then
usermod -o -u "$PUID" stirlingpdfuser || true
# Detect if we're running as root (UID 0)
RUNNING_AS_ROOT=false
if [ "$(id -u)" -eq 0 ]; then
RUNNING_AS_ROOT=true
echo "Running container as root, will attempt to drop privileges"
fi
# Only attempt user/group modifications if running as root
if [ "$RUNNING_AS_ROOT" = true ]; then
# Update the user and group IDs as per environment variables
if [ ! -z "$PUID" ] && [ "$PUID" != "$(id -u stirlingpdfuser)" ]; then
usermod -o -u "$PUID" stirlingpdfuser || echo "[WARN] Failed to update UID for stirlingpdfuser"
fi
if [ ! -z "$PGID" ] && [ "$PGID" != "$(getent group stirlingpdfgroup | cut -d: -f3)" ]; then
groupmod -o -g "$PGID" stirlingpdfgroup || true
if [ ! -z "$PGID" ] && [ "$PGID" != "$(getent group stirlingpdfgroup | cut -d: -f3)" ]; then
groupmod -o -g "$PGID" stirlingpdfgroup || echo "[WARN] Failed to update GID for stirlingpdfgroup"
fi
fi
# Apply umask in either case
umask "$UMASK" || true
if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" && "$FAT_DOCKER" != "true" ]]; then
echo "issue with calibre in current version, feature currently disabled on Stirling-PDF"
#apk add --no-cache calibre@testing
# Skip download for fat Docker (already has security jar)
if [[ "$FAT_DOCKER" != "true" && "$RUNNING_AS_ROOT" = true ]]; then
echo "Downloading security JAR (not necessary in fat Docker image)..."
/scripts/download-security-jar.sh
elif [[ "$FAT_DOCKER" != "true" && "$RUNNING_AS_ROOT" != true ]]; then
echo "[INFO] Skipping security JAR download in rootless mode"
fi
if [[ "$FAT_DOCKER" != "true" ]]; then
/scripts/download-security-jar.sh
fi
if [[ -n "$LANGS" ]]; then
# Handle font installation
if [[ -n "$LANGS" && "$RUNNING_AS_ROOT" = true ]]; then
echo "Installing fonts for languages: $LANGS"
/scripts/installFonts.sh $LANGS
elif [[ -n "$LANGS" && "$RUNNING_AS_ROOT" != true ]]; then
echo "[INFO] Skipping font installation in rootless mode"
fi
echo "Setting permissions and ownership for necessary directories..."
# Attempt to change ownership of directories and files
if chown -R stirlingpdfuser:stirlingpdfgroup $HOME /logs /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /app.jar; then
chmod -R 755 /logs /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /app.jar || true
# If chown succeeds, execute the command as stirlingpdfuser
exec su-exec stirlingpdfuser "$@"
# Directory list we need to ensure are accessible
DIRS_TO_CHECK="$HOME /logs /scripts /usr/share/fonts/opentype/noto /configs /customFiles /customFiles/signatures /customFiles/templates /pipeline /pipeline/watchedFolders /pipeline/finishedFolders /usr/share/tessdata /tmp /tmp/stirling-pdf"
FILES_TO_CHECK="/app.jar"
# Skip copying tessdata files in rootless mode to avoid the error message
if [ "$RUNNING_AS_ROOT" = true ]; then
# We're running as root, so try to copy tessdata files if they exist
if [ -d "/usr/share/tessdata-original" ]; then
echo "Copying original files without overwriting existing files"
cp -n /usr/share/tessdata-original/* /usr/share/tessdata/ 2>/dev/null || true
fi
echo "Setting permissions and ownership for necessary directories..."
# Attempt to change ownership of directories and files if running as root
if chown -R stirlingpdfuser:stirlingpdfgroup $DIRS_TO_CHECK $FILES_TO_CHECK; then
chmod -R 755 $DIRS_TO_CHECK $FILES_TO_CHECK || echo "[WARN] Failed to set directory permissions, but continuing"
# If chown succeeds, execute the command as stirlingpdfuser
echo "Running as stirlingpdfuser"
exec su-exec stirlingpdfuser "$@"
else
# If chown fails, still try to make files accessible
echo "[WARN] Chown failed, but will attempt to make files world-accessible"
chmod -R 1777 /logs /configs /customFiles /pipeline || true
echo "[WARN] Running as root user - could not drop privileges"
exec "$@"
fi
else
# If chown fails, execute the command without changing the user context
echo "[WARN] Chown failed, running as host user"
# Already running as non-root (rootless mode)
echo "Running in rootless mode"
# In rootless mode, we'll only check critical paths that must be writable
CRITICAL_DIRS="/configs /logs /customFiles /customFiles/signatures /customFiles/templates /pipeline/watchedFolders /pipeline/finishedFolders"
for DIR in $CRITICAL_DIRS; do
if [ -d "$DIR" ] && [ ! -w "$DIR" ]; then
echo "[WARN] Cannot write to $DIR in rootless mode. Some functionality may be limited."
fi
done
# Just execute the command as the current user
echo "Executing as current user (UID: $(id -u))"
exec "$@"
fi

View File

@@ -0,0 +1,160 @@
#!/bin/bash
# This script helps prepare your host environment for running Stirling-PDF in rootless mode
# It creates the necessary directories with appropriate permissions
# Set text colors
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# Usage information
print_usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -d, --base-dir DIR Base directory for Stirling-PDF data (default: /stirling/rootless)"
echo " -u, --uid UID User ID to set as owner (default: current user ID)"
echo " -g, --gid GID Group ID to set as owner (default: current group ID)"
echo " -h, --help Show this help message"
echo ""
echo "Example:"
echo " $0 --base-dir ~/stirling-data --uid 1000 --gid 1000"
}
# Default values
BASE_DIR="/stirling/rootless"
UID_VAL=$(id -u)
GID_VAL=$(id -g)
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-d|--base-dir)
BASE_DIR="$2"
shift 2
;;
-u|--uid)
UID_VAL="$2"
shift 2
;;
-g|--gid)
GID_VAL="$2"
shift 2
;;
-h|--help)
print_usage
exit 0
;;
*)
echo "Error: Unknown option: $1"
print_usage
exit 1
;;
esac
done
# Validate inputs
if [[ ! "$UID_VAL" =~ ^[0-9]+$ ]]; then
echo "Error: UID must be a number"
exit 1
fi
if [[ ! "$GID_VAL" =~ ^[0-9]+$ ]]; then
echo "Error: GID must be a number"
exit 1
fi
echo -e "${YELLOW}Setting up directories for Stirling-PDF rootless mode${NC}"
echo "==============================================="
echo "UID: $UID_VAL"
echo "GID: $GID_VAL"
echo "Base directory: $BASE_DIR"
echo
# Create base directory if it doesn't exist
if [ ! -d "$BASE_DIR" ]; then
echo "Creating base directory: $BASE_DIR"
mkdir -p "$BASE_DIR" || { echo "Failed to create base directory"; exit 1; }
fi
# Create necessary subdirectories
DIRS=(
"data"
"config"
"logs"
"customFiles"
"customFiles/signatures"
"customFiles/templates"
"pipeline/watchedFolders"
"pipeline/finishedFolders"
)
for DIR in "${DIRS[@]}"; do
FULL_PATH="$BASE_DIR/$DIR"
echo "Creating directory: $FULL_PATH"
mkdir -p "$FULL_PATH" || { echo "Failed to create directory: $FULL_PATH"; exit 1; }
echo "Setting ownership to $UID_VAL:$GID_VAL for $FULL_PATH"
chown -R "$UID_VAL:$GID_VAL" "$FULL_PATH" || { echo "Warning: Failed to change ownership for $FULL_PATH"; }
echo "Setting permissions for $FULL_PATH"
chmod -R 1777 "$FULL_PATH" || { echo "Warning: Failed to set permissions for $FULL_PATH"; }
done
# Create a Docker Compose file for rootless mode if it doesn't exist
COMPOSE_FILE="$BASE_DIR/docker-compose-rootless.yml"
if [ ! -f "$COMPOSE_FILE" ]; then
echo "Creating Docker Compose file for rootless mode: $COMPOSE_FILE"
cat > "$COMPOSE_FILE" << EOL
services:
stirling-pdf:
container_name: Stirling-PDF-Rootless
# Use the fat version for rootless operation as it includes all dependencies
image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-fat
user: "$UID_VAL:$GID_VAL"
ports:
- "8080:8080"
volumes:
- $BASE_DIR/data:/usr/share/tessdata:rw
- $BASE_DIR/config:/configs:rw
- $BASE_DIR/logs:/logs:rw
- $BASE_DIR/customFiles:/customFiles:rw
- $BASE_DIR/pipeline:/pipeline:rw
environment:
DOCKER_ENABLE_SECURITY: "false"
SECURITY_ENABLELOGIN: "false"
SYSTEM_DEFAULTLOCALE: en-US
UI_APPNAME: Stirling-PDF
UI_HOMEDESCRIPTION: Stirling-PDF Rootless
UI_APPNAMENAVBAR: Stirling-PDF Rootless
restart: unless-stopped
EOL
echo "Docker Compose file created"
fi
echo -e "${GREEN}"
echo "==============================================="
echo "Preparation complete!"
echo "===============================================${NC}"
echo ""
echo "To run Stirling-PDF in rootless mode:"
echo ""
echo -e "${YELLOW}Option 1: Using the generated docker-compose file:${NC}"
echo "cd $BASE_DIR"
echo "docker-compose -f docker-compose-rootless.yml up -d"
echo ""
echo -e "${YELLOW}Option 2: Manual docker run command:${NC}"
echo "docker run -d \\"
echo " --name stirling-pdf-rootless \\"
echo " --user \"$UID_VAL:$GID_VAL\" \\"
echo " -p 8080:8080 \\"
echo " -v $BASE_DIR/data:/usr/share/tessdata:rw \\"
echo " -v $BASE_DIR/config:/configs:rw \\"
echo " -v $BASE_DIR/logs:/logs:rw \\"
echo " -v $BASE_DIR/customFiles:/customFiles:rw \\"
echo " -v $BASE_DIR/pipeline:/pipeline:rw \\"
echo " docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-fat"
echo ""
echo -e "${YELLOW}IMPORTANT:${NC} For rootless mode, always use the ${YELLOW}:latest-fat${NC} image tag"
echo "which includes all dependencies pre-installed."