update the docker-compose

This commit is contained in:
Hossein 2025-08-11 22:24:37 +03:30
parent d8c349f4fb
commit 2026e0fbfb
3 changed files with 81 additions and 14 deletions

View File

@ -46,8 +46,8 @@ A FastAPI application with Docker and docker-compose support.
BOXAPI_LOG_DIR=/app/logs/boxapi
BOXAPI_LOG_LEVEL=all # or "error" for production
# Redis for pagination (optional but recommended)
REDIS_URL=redis://localhost:6379/0
# Redis for pagination (optional but recommended)
REDIS_URL=redis://redis:6379/0 # Use 'redis' hostname in Docker
```
2. **Build and start the application:**
@ -191,6 +191,7 @@ The application uses environment variables for configuration. Copy `env.example`
### Redis Configuration (for pagination)
- `REDIS_URL`: Redis connection URL (default: `redis://localhost:6379/0`)
- **Note**: Redis is optional but recommended for pagination. If Redis is not available, the system will work without pagination (posts may be duplicated on subsequent calls).
### Database Configuration
- `POSTGRES_DB`: Database name (default: `fastapi_db`)
@ -290,6 +291,13 @@ The application includes health checks that can be accessed at:
- Check if PostgreSQL container is running: `docker-compose ps`
- Check database logs: `docker-compose logs postgres`
5. **Redis connection issues:**
- Redis is optional - the system will work without it (posts may be duplicated)
- If you want Redis: `docker-compose up redis` to start Redis service
- Check Redis logs: `docker-compose logs redis`
- For Docker: use `REDIS_URL=redis://redis:6379/0`
- For local development: use `REDIS_URL=redis://localhost:6379/0`
## Contributing
1. Fork the repository

View File

@ -16,6 +16,8 @@ services:
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
@ -45,9 +47,24 @@ services:
networks:
- fastapi-network
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- fastapi-network
networks:
fastapi-network:
driver: bridge
volumes:
postgres_data:
redis_data:

View File

@ -1,22 +1,64 @@
# utils/seen_store.py
import os, redis
from typing import Iterable
from typing import Iterable, Optional
import logging
logger = logging.getLogger(__name__)
REDIS_URL = os.environ.get("REDIS_URL", "redis://localhost:6379/0")
r = redis.from_url(REDIS_URL, decode_responses=True)
_redis_client: Optional[redis.Redis] = None
def _get_redis_client() -> Optional[redis.Redis]:
"""Get Redis client with error handling"""
global _redis_client
if _redis_client is not None:
return _redis_client
try:
_redis_client = redis.from_url(REDIS_URL, decode_responses=True)
# Test the connection
_redis_client.ping()
logger.info("✅ Redis connection established")
return _redis_client
except Exception as e:
logger.warning(f"⚠️ Redis connection failed: {e}")
logger.warning("📝 Pagination will be disabled - posts may be duplicated")
_redis_client = None
return None
def seen_key(username: str) -> str:
return f"ig:seen:{username}"
def mark_seen(username: str, ids: Iterable[str]) -> None:
if not ids: return
r.sadd(seen_key(username), *ids)
"""Mark posts as seen (Redis optional)"""
if not ids:
return
r = _get_redis_client()
if r is None:
return # Skip if Redis is not available
try:
r.sadd(seen_key(username), *ids)
except Exception as e:
logger.warning(f"⚠️ Failed to mark posts as seen: {e}")
def filter_unseen(username: str, ids: Iterable[str]) -> list[str]:
# pipeline for speed
key = seen_key(username)
pipe = r.pipeline()
for i in ids:
pipe.sismember(key, i)
flags = pipe.execute()
return [i for i, seen in zip(ids, flags) if not seen]
"""Filter out already seen posts (Redis optional)"""
r = _get_redis_client()
if r is None:
# If Redis is not available, return all IDs (no filtering)
return list(ids)
try:
# pipeline for speed
key = seen_key(username)
pipe = r.pipeline()
for i in ids:
pipe.sismember(key, i)
flags = pipe.execute()
return [i for i, seen in zip(ids, flags) if not seen]
except Exception as e:
logger.warning(f"⚠️ Failed to filter unseen posts: {e}")
# Fallback: return all IDs if Redis fails
return list(ids)