cmc-sales/scripts/VAULT_PERMISSIONS_FIX.md

251 lines
7.3 KiB
Markdown
Raw Permalink Normal View History

# 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 `--emaildir` flag)
- Host directory: `/home/cmc/files/emails`
- Running as: `root` user (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-data` user (UID 33 or 82)
### Two Issues Identified
1. **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**!
2. **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!
## Solution Implemented
### Changes Made
**1. Updated Docker Compose ([docker-compose.prod.yml](../docker-compose.prod.yml))**
Added the `attachments_files` mount to the Go container:
```yaml
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](vault-cron-prod.sh))**
Changed the `--emaildir` flag to point to the correct directory:
```bash
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](VAULT_QUICKSTART.md) - Updated all examples
- [VAULT_DEPLOYMENT.md](VAULT_DEPLOYMENT.md) - Updated deployment instructions
## Verification Steps
After deploying the fix, verify it works:
### Step 1: Rebuild and Restart Containers
```bash
cd ~/src/cmc-sales
docker compose -f docker-compose.prod.yml up -d cmc-prod-go
```
### Step 2: Verify Mount Points
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
1. **Files are world-readable** (`r--` in other bits)
2. **Directories are world-executable** (`x` in other bits)
3. Even though owner is `root:root`, the "other" permissions allow `www-data` to 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:
```sql
-- email_attachments table
name: "11-2025/abc123-filename.pdf"
```
The PHP application prepends the base path:
```php
$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_files` directory
- ✅ 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