251 lines
7.3 KiB
Markdown
251 lines
7.3 KiB
Markdown
# 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
|