mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
@@ -1,46 +1,78 @@
|
||||
# Managing File Permissions for NetAlertX on Nginx with Docker
|
||||
# Managing File Permissions for NetAlertX on a Read-Only Container
|
||||
|
||||
> [!TIP]
|
||||
> If you are facing permission issues, try to start the container without mapping your volumes. If that works, then the issue is permission related. You can try e.g., the following command:
|
||||
> ```
|
||||
> docker run -d --rm --network=host \
|
||||
> -e TZ=Europe/Berlin \
|
||||
> -e PUID=200 -e PGID=200 \
|
||||
> -e PORT=20211 \
|
||||
> ghcr.io/jokob-sk/netalertx:latest
|
||||
> ```
|
||||
NetAlertX runs on an Nginx web server. On Alpine Linux, Nginx operates as the `nginx` user (if PUID and GID environment variables are not specified, nginx user UID will be set to 102, and its supplementary group `www-data` ID to 82). Consequently, files accessed or written by the NetAlertX application are owned by `nginx:www-data`.
|
||||
> NetAlertX runs in a **secure, read-only Alpine-based container** under a dedicated `netalertx` user (UID 20211, GID 20211). All writable paths are either mounted as **persistent volumes** or **`tmpfs` filesystems**. This ensures consistent file ownership and prevents privilege escalation.
|
||||
|
||||
Upon starting, NetAlertX changes nginx user UID and www-data GID to specified values (or defaults), and the ownership of files on the host system mapped to `/app/config` and `/app/db` in the container to `nginx:www-data`. This ensures that Nginx can access and write to these files. Since the user in the Docker container is mapped to a user on the host system by ID:GID, the files in `/app/config` and `/app/db` on the host system are owned by a user with the same ID and GID (defaults are ID 102 and GID 82). On different systems, this ID:GID may belong to different users, or there may not be a group with ID 82 at all.
|
||||
---
|
||||
|
||||
Option to set specific user UID and GID can be useful for host system users needing to access these files (e.g., backup scripts).
|
||||
## Writable Paths
|
||||
|
||||
### Permissions Table for Individual Folders
|
||||
NetAlertX requires certain paths to be writable at runtime. These paths should be mounted either as **host volumes** or **`tmpfs`** in your `docker-compose.yml` or `docker run` command:
|
||||
|
||||
| Folder | User | User ID | Group | Group ID | Permissions | Notes |
|
||||
|----------------|--------|---------|-----------|----------|-------------|---------------------------------------------------------------------|
|
||||
| `/app/config` | nginx | PUID (default 102) | www-data | PGID (default 82) | rwxr-xr-x | Ensure `nginx` can read/write; other users can read if in `www-data` |
|
||||
| `/app/db` | nginx | PUID (default 102) | www-data | PGID (default 82) | rwxr-xr-x | Same as above |
|
||||
| Path | Purpose | Notes |
|
||||
| ------------------------------------ | ----------------------------------- | ------------------------------------------------------ |
|
||||
| `/app/config` | Application configuration | Persistent volume recommended |
|
||||
| `/app/db` | Database files | Persistent volume recommended |
|
||||
| `/app/log` | Logs | Can be `tmpfs` for speed or host volume to retain logs |
|
||||
| `/app/api` | API cache | Use `tmpfs` for faster access |
|
||||
| `/services/config/nginx/conf.active` | Active nginx configuration override | `tmpfs` recommended or customiozed file mounted |
|
||||
| `/services/run` | Runtime directories for nginx & PHP | `tmpfs` required |
|
||||
| `/tmp` | PHP session save directory | `tmpfs` required |
|
||||
|
||||
> All these paths will have **UID 20211 / GID 20211** inside the container. Files on the host will appear owned by `20211:20211`.
|
||||
|
||||
### Fixing Permission Problems
|
||||
---
|
||||
|
||||
The container fails to start with "Permission Denied" errors. This typically happens when your data volumes (`netalertx_config`, `netalertx_db`) are "owned" by the `root` user (UID 0) from a previous install, but the secure container must run as the `netalertx` user (UID 20211).
|
||||
## Fixing Permission Problems
|
||||
|
||||
Sometimes, permission issues arise if your existing host directories were created by a previous container running as root or another UID. The container will fail to start with "Permission Denied" errors.
|
||||
|
||||
### Solution
|
||||
|
||||
1. Run the container **once** as the `root` user (`--user "0"`) to trigger the built-in fix-it mode:
|
||||
1. **Run the container once as root** (`--user "0"`) to allow it to correct permissions automatically:
|
||||
|
||||
```bash
|
||||
docker run -it --rm --name netalertx-fix --user "0" \
|
||||
-v netalertx_config:/app/config \
|
||||
-v netalertx_db:/app/db \
|
||||
netalertx:latest
|
||||
```
|
||||
2. Wait for the logs to show a **magenta warning** and confirm permissions are being fixed. The container will then hang (this is intentional).
|
||||
3. Press **Ctrl+C** to stop the fix-it container.
|
||||
4. Start your container normally (e.g., with `docker-compose up -d` or your standard `docker run` command).
|
||||
```bash
|
||||
docker run -it --rm --name netalertx --user "0" \
|
||||
-v local/path/config:/app/config \
|
||||
-v local/path/db:/app/db \
|
||||
ghcr.io/jokob-sk/netalertx:latest
|
||||
```
|
||||
|
||||
2. Wait for logs showing **permissions being fixed**. The container will then **hang intentionally**.
|
||||
3. Press **Ctrl+C** to stop the container.
|
||||
4. Start the container normally with your `docker-compose.yml` or `docker run` command.
|
||||
|
||||
> The container startup script detects `root` and runs `chown -R 20211:20211` on all volumes, fixing ownership for the secure `netalertx` user.
|
||||
|
||||
---
|
||||
|
||||
## Example: docker-compose.yml with `tmpfs`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
netalertx:
|
||||
container_name: netalertx
|
||||
image: "ghcr.io/jokob-sk/netalertx"
|
||||
network_mode: "host"
|
||||
cap_add:
|
||||
- NET_RAW
|
||||
- NET_ADMIN
|
||||
- NET_BIND_SERVICE
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
tmpfs:
|
||||
- "/app/log:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
- "/app/api:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,sync,noatime,nodiratime"
|
||||
- "/services/config/nginx/conf.active:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
- "/services/run:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
- "/tmp:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
```
|
||||
|
||||
> This setup ensures all writable paths are either in `tmpfs` or host-mounted, and the container never writes outside of controlled volumes.
|
||||
|
||||
### About This Method
|
||||
|
||||
The container’s startup script detects it is running as `root` (UID 0). It automatically runs the `chown` command to fix the permissions on your volume files, setting them to the correct `20211` user. It then hangs (`sleep infinity`) to prevent you from *ever* running the application as `root`, forcing you to restart securely.
|
||||
Reference in New Issue
Block a user