Inicio » Resuelto: Error de permisos (Permission Denied) en volúmenes de Docker Compose
Sistemas y Servidores

Resuelto: Error de permisos (Permission Denied) en volúmenes de Docker Compose

✨ Respuesta Rápida

El fallo recurrente EACCES: permission denied, touch: cannot touch '/data/...': Permission denied o failed to open stream: Permission denied en aplicaciones desplegadas con Dockge o Docker Compose ocurre cuando el usuario interno del contenedor (como node UID 1000, www-data UID 33 o nobody UID 65534) no posee permisos de escritura sobre el directorio montado en el sistema anfitrión.

El Diagnóstico Rápido

Causa
El UID/GID del usuario dentro del contenedor no coincide con el propietario de la carpeta en el host
Solución
Cambiar el propietario de la carpeta con sudo chown -R 1000:1000 /ruta/volumen o usar variable user: "1000:1000"
Causa
Bloqueo de seguridad por contexto SELinux o AppArmor
Solución
Añadir el flag de volumen :z o :Z al mapear volúmenes en docker-compose.yml

El fallo recurrente EACCES: permission denied, touch: cannot touch '/data/...': Permission denied o failed to open stream: Permission denied en aplicaciones desplegadas con Dockge o Docker Compose ocurre cuando el usuario interno del contenedor (como node UID 1000, www-data UID 33 o nobody UID 65534) no posee permisos de escritura sobre el directorio montado en el sistema anfitrión.

La Solución Paso a Paso

  1. 1

    Paso 1: Averiguar el UID y GID del usuario del contenedor

    Revisa qué usuario ejecuta el proceso dentro de la imagen de Docker:

    BASH
    # Ejecutar un comando id temporal dentro de la imagen del contenedor
    docker run --rm <nombre_imagen> id
    

    Ejemplos comunes de UIDs según la imagen:

    • Node.js: UID 1000, GID 1000 (usuario node).
    • Nginx / PHP-FPM: UID 33, GID 33 (usuario www-data).
    • PostgreSQL: UID 999 o 70 (usuario postgres).
    • Uptime Kuma / Dockge: UID 1000 o 0 (root).
  2. 2

    Paso 2: Corregir el propietario y permisos de la carpeta en el host

    Asigna la propiedad del directorio en el servidor anfitrión al usuario correspondiente del contenedor:

    BASH
    # Para contenedores que corren como usuario 1000 (estándar en Node/Dockge):
    sudo chown -R 1000:1000 /opt/dockge/stacks/mi-stack/data
    
    # Asegurar permisos de lectura, escritura y ejecución de directorios
    sudo chmod -R 775 /opt/dockge/stacks/mi-stack/data
    
  3. 3

    Paso 3: Especificar el usuario explícitamente en docker-compose.yml

    En tu archivo compose.yaml, puedes forzar a Docker a ejecutar el contenedor con el ID de tu usuario actual en Linux (id -u e id -g):

    YAML
    services:
      mi-app:
        image: mi-app:latest
        user: "${UID:-1000}:${GID:-1000}"
        volumes:
          - ./data:/app/data:z
        restart: unless-stopped
    

    Nota: El sufijo :z (o :Z para aislamiento exclusivo) reetiqueta el contexto de seguridad SELinux en distribuciones como Fedora, Red Hat, CentOS y Rocky Linux.

  4. 4

    Paso 4: Reiniciar el contenedor y verificar la persistencia

    Reinicia el servicio para validar que la aplicación puede crear y modificar archivos:

    BASH
    # Reiniciar el contenedor en Dockge o mediante CLI
    docker compose down && docker compose up -d
    
    # Verificar los logs para confirmar que no hay errores EACCES
    docker compose logs -f
    

❓ Preguntas Frecuentes (FAQ)

¿Qué diferencia hay entre :z y :Z en los volúmenes de Docker?

El modificador :z comparte el contexto SELinux entre múltiples contenedores, mientras que :Z asigna una etiqueta privada exclusiva solo para ese contenedor específico.

¿Cómo sé qué UID tiene mi usuario en Linux?

Ejecuta id -u para el identificador de usuario y id -g para el grupo.

Consejo de Prevención

Prácticas de seguridad recomendadas:

  • Evita chmod 777 como solución definitiva: Aunque chmod 777 resuelve el bloqueo de inmediato, concede permisos totales a cualquier proceso local en el servidor, creando una brecha de seguridad. Utiliza siempre chown con el UID específico.
  • Estandariza los entornos PUID/PGID: Muchas imágenes comunitarias (como las de LinuxServer.io) admiten variables de entorno PUID=1000 y PGID=1000 para auto-ajustar permisos en el arranque.