Fix: robust PUID/PGID handling; optional ownership normalization (closes #43)

This commit is contained in:
Ryan
2025-10-04 02:25:16 -04:00
committed by GitHub
parent 680c82638f
commit ad72ef74d1
4 changed files with 141 additions and 68 deletions

View File

@@ -1,5 +1,13 @@
# Changelog
## Changes 10/4/2025 v1.3.12
Fix: robust PUID/PGID handling; optional ownership normalization (closes #43)
- Remap www-data to PUID/PGID when running as root; skip with helpful log if non-root
- Added CHOWN_ON_START env to control recursive chown (default true; turn off after first run)
- SCAN_ON_START unchanged, with non-root fallback
## Changes 10/4/2025 v1.3.11
Chore: keep BASE_URL fallback, prefer env SHARE_URL; fix HTTPS auto-detect

130
README.md
View File

@@ -52,38 +52,61 @@ Curious about the UI? **Check out the live demo:** <https://demo.filerise.net> (
You can deploy FileRise either by running the **Docker container** (quickest way) or by a **manual installation** on a PHP web server. Both methods are outlined below.
### 1. Running with Docker (Recommended)
---
If you have Docker installed, you can get FileRise up and running in minutes:
### 1) Running with Docker (Recommended)
- **Pull the image from Docker Hub:**
#### Pull the image
``` bash
```bash
docker pull error311/filerise-docker:latest
```
- **Run a container:**
#### Run a container
``` bash
```bash
docker run -d \
--name filerise \
-p 8080:80 \
-e TIMEZONE="America/New_York" \
-e DATE_TIME_FORMAT="m/d/y h:iA" \
-e TOTAL_UPLOAD_SIZE="5G" \
-e SECURE="false" \
-e PERSISTENT_TOKENS_KEY="please_change_this_@@" \
-e PUID="1000" \
-e PGID="1000" \
-e CHOWN_ON_START="true" \
-e SCAN_ON_START="true" \
-e SHARE_URL="" \
-v ~/filerise/uploads:/var/www/uploads \
-v ~/filerise/users:/var/www/users \
-v ~/filerise/metadata:/var/www/metadata \
--name filerise \
error311/filerise-docker:latest
```
```
This will start FileRise on port 8080. Visit `http://your-server-ip:8080` to access it. Environment variables shown above are optional for instance, set `SECURE="true"` to enforce HTTPS (assuming you have SSL at proxy level) and adjust `TIMEZONE` as needed. The volume mounts ensure your files and user data persist outside the container.
This starts FileRise on port **8080** → visit `http://your-server-ip:8080`.
- **Using Docker Compose:**
Alternatively, use **docker-compose**. Save the snippet below as docker-compose.yml and run `docker-compose up -d`:
**Notes**
``` yaml
version: '3'
- **Do not use** Docker `--user`. Use **PUID/PGID** to map on-disk ownership (e.g., `1000:1000`; on Unraid typically `99:100`).
- `CHOWN_ON_START=true` is recommended on **first run** to normalize ownership of existing trees. Set to **false** later for faster restarts.
- `SCAN_ON_START=true` runs a one-time index of files added outside the UI so their metadata appears.
- `SHARE_URL` is optional; leave blank to auto-detect from the current host/scheme. You can set it to your site root (e.g., `https://files.example.com`) or directly to the full endpoint.
- Set `SECURE="true"` if you serve via HTTPS at your proxy layer.
**Verify ownership mapping (optional)**
```bash
docker exec -it filerise id www-data
# expect: uid=1000 gid=1000 (or 99/100 on Unraid)
```
#### Using Docker Compose
Save as `docker-compose.yml`, then `docker-compose up -d`:
```yaml
version: "3"
services:
filerise:
image: error311/filerise-docker:latest
@@ -91,61 +114,88 @@ services:
- "8080:80"
environment:
TIMEZONE: "UTC"
DATE_TIME_FORMAT: "m/d/y h:iA"
TOTAL_UPLOAD_SIZE: "10G"
SECURE: "false"
PERSISTENT_TOKENS_KEY: "please_change_this_@@"
SCAN_ON_START: "true"
CHOWN_ON_START: "true"
# Ownership & indexing
PUID: "1000" # Unraid users often use 99
PGID: "1000" # Unraid users often use 100
CHOWN_ON_START: "true" # first run; set to "false" afterwards
SCAN_ON_START: "true" # index files added outside the UI at boot
# Sharing URL (optional): leave blank to auto-detect from host/scheme
SHARE_URL: ""
volumes:
- ./uploads:/var/www/uploads
- ./users:/var/www/users
- ./metadata:/var/www/metadata
```
FileRise will be accessible at `http://localhost:8080` (or your servers IP). The above example also sets a custom `PERSISTENT_TOKENS_KEY` (used to encrypt “remember me” tokens) be sure to change it to a random string for security.
FileRise will be accessible at `http://localhost:8080` (or your servers IP).
The example also sets a custom `PERSISTENT_TOKENS_KEY` (used to encrypt “Remember Me” tokens)—change it to a strong random string.
**First-time Setup:** On first launch, FileRise will detect no users and prompt you to create an **Admin account**. Choose your admin username & password, and youre in! You can then head to the **User Management** section to add additional users if needed.
**First-time Setup**
On first launch, if no users exist, youll be prompted to create an **Admin account**. After logging in, use **User Management** to add more users.
### 2. Manual Installation (PHP/Apache)
---
### 2) Manual Installation (PHP/Apache)
If you prefer to run FileRise on a traditional web server (LAMP stack or similar):
- **Requirements:** PHP 8.3 or higher, Apache (with mod_php) or another web server configured for PHP. Ensure PHP extensions json, curl, and zip are enabled. No database needed.
- **Download Files:** Clone this repo or download the [latest release archive](https://github.com/error311/FileRise/releases).
**Requirements**
``` bash
git clone https://github.com/error311/FileRise.git
- PHP **8.3+**
- Apache (mod_php) or another web server configured for PHP
- PHP extensions: `json`, `curl`, `zip` (and typical defaults). No database required.
**Download Files**
```bash
git clone https://github.com/error311/FileRise.git
```
Place the files into your web servers directory (e.g., `/var/www/`). It can be in a subfolder (just adjust the `BASE_URL` in config as below).
Place the files in your web root (e.g., `/var/www/`). Subfolder installs are fine.
- **Composer Dependencies:** Install Composer and run `composer install` in the FileRise directory. (This pulls in a couple of PHP libraries like jumbojett/openid-connect for OAuth support.)
**Composer (if applicable)**
If you use optional features requiring Composer libraries, run:
- **Folder Permissions:** Ensure the server can write to the following directories (create them if they dont exist):
```bash
composer install
```
``` bash
**Folders & Permissions**
```bash
mkdir -p uploads users metadata
chown -R www-data:www-data uploads users metadata # www-data is Apache user; use appropriate user
chown -R www-data:www-data uploads users metadata # use your web user
chmod -R 775 uploads users metadata
```
The uploads/ folder is where files go, users/ stores the user credentials file, and metadata/ holds metadata like tags and share links.
- `uploads/`: actual files
- `users/`: credentials & token storage
- `metadata/`: file metadata (tags, share links, etc.)
- **Configuration:** Open the `config.php` file in a text editor. You may want to adjust:
**Configuration**
- `BASE_URL` the URL where you will access FileRise (e.g., `“https://files.mydomain.com/”`). This is used for generating share links.
- `TIMEZONE` and `DATE_TIME_FORMAT` match your locale (for correct timestamps).
- `TOTAL_UPLOAD_SIZE` max aggregate upload size (default 5G). Also adjust PHPs `upload_max_filesize` and `post_max_size` to at least this value (the Docker start script auto-adjusts PHP limits).
- `PERSISTENT_TOKENS_KEY` set a unique secret if you use “Remember Me” logins, to encrypt the tokens.
- Other settings like `UPLOAD_DIR`, `USERS_FILE` etc. generally dont need changes unless you move those folders. Defaults are set for the directories mentioned above.
Open `config.php` and consider:
- **Web Server Config:** If using Apache, ensure `.htaccess` files are allowed or manually add the rules from `.htaccess` to your Apache config these disable directory listings and prevent access to certain files. For Nginx or others, youll need to replicate those protections (see Wiki: [Nginx Setup for examples](https://github.com/error311/FileRise/wiki/Nginx-Setup)). Also enable mod_rewrite if not already, as FileRise may use pretty URLs for share links.
- `TIMEZONE`, `DATE_TIME_FORMAT` for your locale.
- `TOTAL_UPLOAD_SIZE` (also ensure your PHP `upload_max_filesize` & `post_max_size` meet/exceed this).
- `PERSISTENT_TOKENS_KEY` set to a unique secret if using “Remember Me”.
Now navigate to the FileRise URL in your browser. On first load, youll be prompted to create the Admin user (same as Docker setup). After that, the application is ready to use!
**Share links base URL**
- You can set **`SHARE_URL`** via your web server environment variables (preferred),
**or** keep using `BASE_URL` in `config.php` as a fallback for manual installs.
- If neither is set, FileRise auto-detects from the current host/scheme.
**Web Server Config**
- Apache: allow `.htaccess` or merge its rules; ensure `mod_rewrite` is enabled.
- Nginx/other: replicate the basic protections (no directory listing, deny sensitive files). See Wiki for examples.
Now browse to your FileRise URL; youll be prompted to create the Admin user on first load.
---

View File

@@ -3,7 +3,7 @@ import { loadAdminConfigFunc } from './auth.js';
import { showToast, toggleVisibility, attachEnterKeyListener } from './domUtils.js';
import { sendRequest } from './networkUtils.js';
const version = "v1.3.11";
const version = "v1.3.12";
const adminTitle = `${t("admin_panel")} <small style="font-size:12px;color:gray;">${version}</small>`;
// ————— Inject updated styles —————

View File

@@ -3,21 +3,37 @@ set -euo pipefail
umask 002
echo "🚀 Running start.sh..."
# Remap www-data to match provided PUID/PGID (e.g., Unraid 99:100)
if [ -n "${PGID:-}" ]; then
current_gid="$(getent group www-data | cut -d: -f3 || true)"
if [ "${current_gid}" != "${PGID}" ]; then
groupmod -o -g "${PGID}" www-data || true
# ──────────────────────────────────────────────────────────────
# 0) If NOT root, we can't remap/chown. Log a hint and skip those parts.
# If root, remap www-data to PUID/PGID and (optionally) chown data dirs.
if [ "$(id -u)" -ne 0 ]; then
echo "[startup] Running as non-root. Skipping PUID/PGID remap and chown."
echo "[startup] Tip: remove '--user' and set PUID/PGID env vars instead."
else
# Remap www-data to match provided PUID/PGID (e.g., Unraid 99:100 or 1000:1000)
if [ -n "${PGID:-}" ]; then
current_gid="$(getent group www-data | cut -d: -f3 || true)"
if [ "${current_gid}" != "${PGID}" ]; then
groupmod -o -g "${PGID}" www-data || true
fi
fi
fi
if [ -n "${PUID:-}" ]; then
current_uid="$(id -u www-data 2>/dev/null || echo '')"
target_gid="${PGID:-$(getent group www-data | cut -d: -f3)}"
if [ "${current_uid}" != "${PUID}" ]; then
usermod -o -u "${PUID}" -g "${target_gid}" www-data || true
if [ -n "${PUID:-}" ]; then
current_uid="$(id -u www-data 2>/dev/null || echo '')"
target_gid="${PGID:-$(getent group www-data | cut -d: -f3)}"
if [ "${current_uid}" != "${PUID}" ]; then
usermod -o -u "${PUID}" -g "${target_gid}" www-data || true
fi
fi
# Optional: normalize ownership on data dirs (good for first run on existing shares)
if [ "${CHOWN_ON_START:-true}" = "true" ]; then
echo "[startup] Normalizing ownership on uploads/metadata..."
chown -R www-data:www-data /var/www/metadata /var/www/uploads || echo "[startup] chown failed (continuing)"
chmod -R u+rwX /var/www/metadata /var/www/uploads || echo "[startup] chmod failed (continuing)"
fi
fi
# ──────────────────────────────────────────────────────────────
# 1) Tokenkey warning (guarded for -u)
if [ "${PERSISTENT_TOKENS_KEY:-}" = "default_please_change_this_key" ] || [ -z "${PERSISTENT_TOKENS_KEY:-}" ]; then
echo "⚠️ WARNING: Using default/empty persistent tokens key—override for production."
@@ -27,12 +43,13 @@ fi
CONFIG_FILE="/var/www/config/config.php"
if [ -f "${CONFIG_FILE}" ]; then
echo "🔄 Updating config.php from env vars..."
[ -n "${TIMEZONE:-}" ] && sed -i "s|define('TIMEZONE',[[:space:]]*'[^']*');|define('TIMEZONE', '${TIMEZONE}');|" "${CONFIG_FILE}"
[ -n "${DATE_TIME_FORMAT:-}" ] && sed -i "s|define('DATE_TIME_FORMAT',[[:space:]]*'[^']*');|define('DATE_TIME_FORMAT', '${DATE_TIME_FORMAT}');|" "${CONFIG_FILE}"
[ -n "${TIMEZONE:-}" ] && sed -i "s|define('TIMEZONE',[[:space:]]*'[^']*');|define('TIMEZONE', '${TIMEZONE}');|" "${CONFIG_FILE}"
[ -n "${DATE_TIME_FORMAT:-}" ] && sed -i "s|define('DATE_TIME_FORMAT',[[:space:]]*'[^']*');|define('DATE_TIME_FORMAT', '${DATE_TIME_FORMAT}');|" "${CONFIG_FILE}"
if [ -n "${TOTAL_UPLOAD_SIZE:-}" ]; then
sed -i "s|define('TOTAL_UPLOAD_SIZE',[[:space:]]*'[^']*');|define('TOTAL_UPLOAD_SIZE', '${TOTAL_UPLOAD_SIZE}');|" "${CONFIG_FILE}"
fi
[ -n "${SECURE:-}" ] && sed -i "s|\$envSecure = getenv('SECURE');|\$envSecure = '${SECURE}';|" "${CONFIG_FILE}"
[ -n "${SECURE:-}" ] && sed -i "s|\$envSecure = getenv('SECURE');|\$envSecure = '${SECURE}';|" "${CONFIG_FILE}"
# NOTE: SHARE_URL is read from getenv in PHP; no sed needed.
fi
# 2.1) Prepare metadata/log & sessions
@@ -64,7 +81,7 @@ fi
# 4) Adjust Apache LimitRequestBody
if [ -n "${TOTAL_UPLOAD_SIZE:-}" ]; then
size_str=$(echo "${TOTAL_UPLOAD_SIZE}" | tr '[:upper:]' '[:lower:]')
size_str="$(echo "${TOTAL_UPLOAD_SIZE}" | tr '[:upper:]' '[:lower:]')"
case "${size_str: -1}" in
g) factor=$((1024*1024*1024)); num=${size_str%g} ;;
m) factor=$((1024*1024)); num=${size_str%m} ;;
@@ -115,8 +132,8 @@ if [ ! -f /var/www/metadata/createdTags.json ]; then
chmod 664 /var/www/metadata/createdTags.json
fi
# 8.5) Harden scan script perms (before running it)
if [ -f /var/www/scripts/scan_uploads.php ]; then
# 8.5) Harden scan script perms (only if root)
if [ -f /var/www/scripts/scan_uploads.php ] && [ "$(id -u)" -eq 0 ]; then
chown root:root /var/www/scripts/scan_uploads.php
chmod 0644 /var/www/scripts/scan_uploads.php
fi
@@ -124,19 +141,17 @@ fi
# 9) One-shot scan when the container starts (opt-in via SCAN_ON_START)
if [ "${SCAN_ON_START:-}" = "true" ]; then
echo "[startup] Scanning uploads directory to build metadata..."
if command -v runuser >/dev/null 2>&1; then
runuser -u www-data -- /usr/bin/php /var/www/scripts/scan_uploads.php || echo "[startup] Scan failed (continuing)"
if [ "$(id -u)" -eq 0 ]; then
if command -v runuser >/dev/null 2>&1; then
runuser -u www-data -- /usr/bin/php /var/www/scripts/scan_uploads.php || echo "[startup] Scan failed (continuing)"
else
su -s /bin/sh -c "/usr/bin/php /var/www/scripts/scan_uploads.php" www-data || echo "[startup] Scan failed (continuing)"
fi
else
su -s /bin/sh -c "/usr/bin/php /var/www/scripts/scan_uploads.php" www-data || echo "[startup] Scan failed (continuing)"
# Non-root fallback: run as current user (permissions may limit writes)
/usr/bin/php /var/www/scripts/scan_uploads.php || echo "[startup] Scan failed (continuing)"
fi
fi
# 10) Final ownership sanity for data dirs (optional; default true)
if [ "${CHOWN_ON_START:-true}" = "true" ]; then
echo "[startup] Normalizing ownership on uploads/metadata..."
chown -R www-data:www-data /var/www/metadata /var/www/uploads
chmod -R u+rwX /var/www/metadata /var/www/uploads
fi
echo "🔥 Starting Apache..."
exec apachectl -D FOREGROUND