docs: add deployment troubleshooting guide with known issues

This commit is contained in:
2026-05-31 16:19:11 +08:00
parent 3ff384cbeb
commit 8140efb72b
+93
View File
@@ -0,0 +1,93 @@
# Deployment Troubleshooting Guide
## Known Issues & Solutions
### 1. Database Password with Special Characters in DATABASE_URL
**Problem**: When the database password contains special characters (especially `%`), the backend container fails to connect with:
```
sqlalchemy.exc.OperationalError: (psycopg.OperationalError) connection failed:
FATAL: password authentication failed for user "postgres"
```
**Root Cause**: The `DATABASE_URL` uses URL encoding. When the password contains `%`, the URL parser interprets it as a URL-encoded character. For example, `%81` gets decoded as a single byte instead of the literal characters `%81`.
**Example**:
- Original password: `zmfCSR%816709301`
- In docker-compose.yml `POSTGRES_PASSWORD`: use **exact** password: `zmfCSR%816709301`
- In `DATABASE_URL`: must URL-encode the `%` as `%25`: `zmfCSR%25816709301`
**Solution**:
```yaml
# docker-compose.server.yml
environment:
POSTGRES_PASSWORD: zmfCSR%816709301 # Exact password for postgres
DATABASE_URL: postgresql+psycopg://postgres:zmfCSR%25816709301@postgres:5432/ai_contract_platform
```
**Rule of thumb**: Any `%` in a URL must be written as `%25`. This applies to `DATABASE_URL`, `REDIS_URL`, and any other URL-based configuration.
**Quick fix command** (on server):
```bash
cd /opt/ai-contract-platform
# Stop backend
docker compose -f docker-compose.server.yml stop backend
# Fix DATABASE_URL: replace % with %25 in docker-compose.server.yml
sed -i 's|zmfCSR%816709301|zmfCSR%25816709301|g' docker-compose.server.yml
# Verify
grep DATABASE_URL docker-compose.server.yml
# Restart
docker compose -f docker-compose.server.yml up -d backend
```
### 2. Missing Template Files at Startup
**Problem**: Backend crashes on startup with:
```
FileNotFoundError: [Errno 2] No such file or directory:
'/project-docs/phase13-legal-knowledge-template-library/contract-templates/...'
```
**Root Cause**: Docker build doesn't include `project-docs/` directory. The `template_service.py` tries to load template markdown files at import time.
**Solution**: Fixed in commit `323e7cf`. The `_load_phase13_template_asset` function now:
1. Returns `None` if source files are missing
2. Filters out `None` entries from `DEFAULT_TEMPLATES` at module load time
### 3. Missing `_context` Method in RemoteSharedAIPlatformClient
**Problem**: Chat API returns 500 error:
```
AttributeError: 'RemoteSharedAIPlatformClient' object has no attribute '_context'
```
**Root Cause**: The `RemoteSharedAIPlatformClient` class uses `self._context(current_user)` in many methods, but the method was never defined.
**Solution**: Fixed in commit `3ff384c`. Added the `_context` method:
```python
def _context(self, current_user: Dict[str, Any]) -> SharedAIRequestContext:
return SharedAIRequestContext(
tenant_id=current_user.get("tenant_id", ""),
user_id=current_user.get("id", ""),
user_role=current_user.get("role", "admin"),
)
```
## Deployment Checklist
1. **Verify password encoding**: Check `DATABASE_URL` in `docker-compose.server.yml` has `%` encoded as `%25`
2. **Pull latest code**: `git pull origin main`
3. **Clean rebuild**: `docker compose -f docker-compose.server.yml down && docker compose -f docker-compose.server.yml up -d --build`
4. **Wait for postgres**: The `backend` container depends on `postgres` health check (up to 20 retries)
5. **Verify**: `curl -s http://localhost:8001/health` should return `{"status":"ok"}`
## Server Information
- **Server**: 192.168.3.90
- **Project directory**: `/opt/ai-contract-platform`
- **SSH key**: `~/.ssh/water_audit_ed25519`
- **SSH user**: `root`
- **Gitea**: http://192.168.3.90:3000
- **Frontend**: http://192.168.3.90:3003
- **Backend API**: http://192.168.3.90:8001
- **Database password**: `zmfCSR%816709301` (use `%25` in URLs)