7.3 KiB
Vault Permissions Fix - Attachment Directory Issue
Problem
The PHP container (cmc-prod-php) could not read attachments written by the Go vault because they were being written to different directories.
Root Cause Analysis
Go Vault Container (cmc-prod-go):
- Was writing attachments to:
/var/www/emails/(default--emaildirflag) - Host directory:
/home/cmc/files/emails - Running as:
rootuser (UID 0)
PHP Application Container (cmc-prod-php):
- Reads attachments from:
/var/www/cmc-sales/app/webroot/attachments_files/ - Host directory:
/home/cmc/files/attachments_files - Running as:
www-datauser (UID 33 or 82)
Two Issues Identified
-
Different Directory Paths (Primary Issue) ❌
- Go wrote to
/var/www/emails→ Host:/home/cmc/files/emails - PHP read from
/var/www/cmc-sales/app/webroot/attachments_files→ Host:/home/cmc/files/attachments_files - These are completely separate directories on the host!
- Go wrote to
-
File Permissions (Secondary) ⚠️
- Files:
0644(-rw-r--r--) - World readable ✅ - Directories:
0755(drwxr-xr-x) - World readable/executable ✅ - Owner:
root:root(from Go container) - Reader:
www-data(from PHP container) - Verdict: Permissions were actually OK (world-readable), but wrong directory!
- Files:
Solution Implemented
Changes Made
1. Updated Docker Compose (docker-compose.prod.yml)
Added the attachments_files mount to the Go container:
cmc-prod-go:
volumes:
- /home/cmc/files/attachments_files:/var/www/attachments_files # ← ADDED
- /home/cmc/files/emails:/var/www/emails
- /home/cmc/files/vault:/var/www/vault
- /home/cmc/files/vaultmsgs:/var/www/vaultmsgs
2. Updated Vault Cron Script (scripts/vault-cron-prod.sh)
Changed the --emaildir flag to point to the correct directory:
docker exec -t "$CONTAINER_NAME" ./vault --mode=local \
--vaultdir=/var/www/vaultmsgs/new \
--processeddir=/var/www/vaultmsgs/cur \
--emaildir=/var/www/attachments_files \ # ← CHANGED from /var/www/emails
--dbhost=cmc-prod-db \
--dbuser=cmc \
--dbpass="xVRQI&cA?7AU=hqJ!%au" \
--dbname=cmc
3. Updated Documentation
- VAULT_QUICKSTART.md - Updated all examples
- VAULT_DEPLOYMENT.md - Updated deployment instructions
Verification Steps
After deploying the fix, verify it works:
Step 1: Rebuild and Restart Containers
cd ~/src/cmc-sales
docker compose -f docker-compose.prod.yml up -d cmc-prod-go
Step 2: Verify Mount Points
# Check Go container can see the directory
docker exec -it cmc-prod-go ls -la /var/www/attachments_files
# Check PHP container can see the directory
docker exec -it cmc-prod-php ls -la /var/www/cmc-sales/app/webroot/attachments_files
Both should show the same files (same inode on host).
Step 3: Test Vault Processing
# Run vault manually
~/scripts/vault-cron-prod.sh
# Check if files were written
ls -la /home/cmc/files/attachments_files/$(date +%m-%Y)/
# Check file permissions
ls -l /home/cmc/files/attachments_files/$(date +%m-%Y)/ | head -5
Expected output:
-rw-r--r-- 1 root root 1234 Nov 23 10:00 abc123-texthtml
-rw-r--r-- 1 root root 5678 Nov 23 10:00 abc123-document.pdf
Step 4: Verify PHP Can Read Files
# Enter PHP container as www-data user
docker exec -it -u www-data cmc-prod-php sh
# Try to read an attachment file
cd /var/www/cmc-sales/app/webroot/attachments_files/$(date +%m-%Y)
ls -la
cat abc123-texthtml # Should display content
exit
Step 5: Check Database
# Verify attachments are in database with correct paths
docker exec -it cmc-prod-db mariadb -u cmc -p cmc -e "
SELECT id, email_id, filename, name, size
FROM email_attachments
ORDER BY created DESC
LIMIT 5;
"
The name column should contain paths like: 11-2025/abc123-filename.pdf
File Permissions Breakdown
The current permissions (0644 for files, 0755 for dirs) are correct:
File Permissions: 0644
-rw-r--r--
│││││││││
│││└─┴─┴─── Other (everyone): read (r--)
││└─┬─┴───── Group: read (r--)
│└─┬┴─────── Owner: read + write (rw-)
└─────────── Regular file (-)
Result: ✅ All users (including www-data) can read the files
Directory Permissions: 0755
drwxr-xr-x
││││││││││
│││└─┴─┴─── Other: read + execute (r-x) - can list & access
││└─┬─┴───── Group: read + execute (r-x)
│└─┬┴─────── Owner: read + write + execute (rwx)
└─────────── Directory (d)
Result: ✅ All users can navigate into and list the directories
Why This Works
- Files are world-readable (
r--in other bits) - Directories are world-executable (
xin other bits) - Even though owner is
root:root, the "other" permissions allowwww-datato read
When You'd Need to Change Permissions
You would only need different permissions if:
| Scenario | Change To | Reason |
|---|---|---|
| Only owner should read | 0600 / 0700 |
Security/privacy |
| Group needs write access | 0664 / 0775 |
Collaborative editing |
| Everyone needs write | 0666 / 0777 |
⚠️ NOT recommended - security risk |
For your use case: Keep 0644 / 0755 ✅
Database Path Storage
The vault stores relative paths in the database:
-- email_attachments table
name: "11-2025/abc123-filename.pdf"
The PHP application prepends the base path:
$fullPath = "/var/www/cmc-sales/app/webroot/attachments_files/" . $attachment['name'];
// Results in: /var/www/cmc-sales/app/webroot/attachments_files/11-2025/abc123-filename.pdf
This is why the directory mount must be correct!
Alternative Solutions (Not Implemented)
Alternative 1: Symlink (Not Needed)
Could create a symlink from /var/www/emails → /var/www/attachments_files, but this adds complexity.
Alternative 2: Change User ID (Overkill)
Could run Go container as www-data user, but:
- Requires rebuilding the Dockerfile
- Adds unnecessary complexity
- Current permissions already work
Alternative 3: Set Group Permissions (Unnecessary)
Could use 0664 / 0775 and shared group, but:
- World-readable permissions already work
- No need for write access
- Simpler is better
Summary
What was fixed:
- ✅ Go vault now writes to
/var/www/attachments_files(same as PHP reads from) - ✅ Added volume mount for
attachments_filesdirectory - ✅ Updated all scripts and documentation
What didn't need fixing:
- ✅ File permissions (
0644) are already world-readable - ✅ Directory permissions (
0755) are already world-accessible - ✅ No user/group changes needed
Root cause:
- Wrong directory path, NOT permissions issue
Deployment Checklist
- Pull latest code with fixes
- Restart Go container (
docker compose up -d cmc-prod-go) - Verify mount points in both containers
- Run vault manually to test
- Check files appear in
/home/cmc/files/attachments_files/ - Verify PHP can read the files
- Check database paths are correct
- Enable cron job
- Monitor logs for 24 hours