Resolving: Permission Denied Error in Docker Compose Volumes
The recurring error EACCES: permission denied, touch: cannot touch '/data/...': Permission denied or failed to open stream: Permission denied in applications managed via Dockge or Docker Compose arises when the container internal runtime user (such as node UID 1000 or www-data UID 33) lacks write permissions on the mounted host filesystem path.
Quick Diagnostics
sudo chown -R 1000:1000 /path/data or set user: "1000:1000":z or :Z in docker-compose.ymlThe recurring error EACCES: permission denied, touch: cannot touch '/data/...': Permission denied or failed to open stream: Permission denied in applications managed via Dockge or Docker Compose arises when the container internal runtime user (such as node UID 1000 or www-data UID 33) lacks write permissions on the mounted host filesystem path.
Step-by-Step Solution
-
1
Step 1: Identify the Container Process UID/GID
Determine the exact user identity executing inside the container image:
BASH# Inspect container user identity docker run --rm <image_name> idCommon image user mappings:
- Node.js: UID
1000, GID1000(nodeuser). - Nginx / PHP-FPM: UID
33, GID33(www-datauser). - PostgreSQL: UID
999(postgresuser).
- Node.js: UID
-
2
Step 2: Adjust Host Directory Ownership and Permissions
Update directory ownership on the host machine to match the container process UID:
BASH# For containers running as UID 1000 (Dockge / Node): sudo chown -R 1000:1000 /opt/dockge/stacks/my-stack/data # Grant standard read/write/execute permissions sudo chmod -R 775 /opt/dockge/stacks/my-stack/data -
3
Step 3: Specify User Context in docker-compose.yml
Pass your host user IDs into the service configuration:
YAMLservices: my-app: image: my-app:latest user: "${UID:-1000}:${GID:-1000}" volumes: - ./data:/app/data:z restart: unless-stoppedNote: The
:zsuffix properly assigns SELinux labels on Fedora, RHEL, and Rocky Linux systems. -
4
Step 4: Recreate Container and Verify Logs
Apply changes and monitor execution:
BASH# Recreate container stack docker compose down && docker compose up -d # Check logs for write confirmation docker compose logs -f
❓ Frequently Asked Questions (FAQ)
What is the difference between :z and :Z volume flags?
The :z flag shares the SELinux label across containers, whereas :Z establishes a private label restricted to a single container instance.
How do I check my Linux user ID?
Run id -u for user ID and id -g for group ID in your terminal.
Prevention Advice
Recommended security practices:
- Avoid blanket chmod 777: While
chmod 777resolves permission blocks, it leaves directories world-writable. Prefer targetedchownalignment. - Utilize PUID/PGID parameters: For images supporting LinuxServer.io init scripts, define
PUID=1000andPGID=1000in service environment variables.