-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Problem
When deploying containerized applications (like Laravel), bind-mounted storage directories can have permission mismatches between the host and container users, causing runtime errors like:
file_put_contents(/var/www/html/storage/framework/views/xxx.php): Failed to open stream: Permission denied
Root Cause
- Agent creates top-level mount directories as 0777 (
discovery.go:281-286), but framework-specific subdirectories are created by containers at runtime - Container users (e.g., www-data UID 82) don't match host users, so subdirectories created inside containers may have incorrect ownership
- Framework subdirectories are not pre-created - Laravel expects
storage/framework/views/,storage/framework/cache/,storage/logs/,bootstrap/cache/to exist
Current Behavior
// discovery.go:281-286
fullPath := filepath.Join(deploymentPath, hostPath)
if err := os.MkdirAll(fullPath, 0777); err != nil {
return err
}Only the top-level mount path is created. Subdirectories must be created by the container, which may fail due to permission issues.
Proposed Solution
Option 1: Pre-create framework-specific subdirectories
Add framework detection to createBindMountDirs() and pre-create known subdirectories:
// For Laravel deployments
laravelStorageDirs := []string{
"framework/cache",
"framework/sessions",
"framework/views",
"logs",
}
if isLaravelMount(hostPath) {
for _, subdir := range laravelStorageDirs {
subdirPath := filepath.Join(fullPath, subdir)
if err := os.MkdirAll(subdirPath, 0777); err != nil {
return err
}
}
}Option 2: Add init container support
Allow templates to specify an init script that runs before the main container:
# metadata.yml
init:
- mkdir -p /var/www/html/storage/framework/{cache,sessions,views}
- mkdir -p /var/www/html/storage/logs
- chown -R www-data:www-data /var/www/html/storageOption 3: Template-level mount configuration
Extend metadata.yml mount definitions to include subdirectories:
mounts:
- id: storage
container_path: /app/storage
subdirectories:
- framework/cache
- framework/sessions
- framework/views
- logs
permissions: "0777"
owner: "www-data"Additional Issues Found
- Permission mode inconsistency:
discovery.gouses 0777,files/manager.gouses 0755 - Named volumes in templates: WordPress template uses named volumes instead of bind mounts, violating flat-file principle
- No UID/GID mapping: Container user UIDs are not mapped to host users
Workaround (Current)
Users must manually fix permissions on the host after deployment:
# Find container user UID
docker compose exec app id www-data
# uid=82(www-data) gid=82(www-data)
# Fix permissions on host
chown -R 82:82 storage
chmod -R 775 storageAffected Files
internal/docker/discovery.go- Volume creation logicinternal/files/manager.go- Directory creation utilitiestemplates/laravel/metadata.yml- Laravel template mountstemplates/wordpress/metadata.yml- WordPress template (uses named volumes)
Metadata
Metadata
Assignees
Labels
No labels