Monitoring System Health
To monitor the status of the application services and ensure the backend API is responsive, you can use the built-in health check endpoint and the corresponding frontend SDK methods.
Infrastructure Monitoring with Docker
The primary way to monitor the backend service health is through the Docker Compose health check configuration. This ensures that the container orchestration layer knows when the service is ready to receive traffic.
In compose.yml, the backend service is configured to perform a health check every 10 seconds:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/utils/health-check/"]
interval: 10s
timeout: 5s
retries: 5
This configuration uses curl to hit the /api/v1/utils/health-check/ endpoint. If the endpoint returns a successful response (HTTP 200), the container is marked as healthy.
Programmatic Health Checks
You can check the API connectivity programmatically from the frontend using the UtilsService class. This is useful for displaying connection status indicators in the UI.
import { UtilsService } from './client/sdk.gen';
async function checkSystemStatus() {
try {
const isHealthy = await UtilsService.healthCheck();
if (isHealthy) {
console.log("Backend API is reachable and healthy.");
}
} catch (error) {
console.error("Backend API is unreachable:", error);
}
}
The healthCheck method in frontend/src/client/sdk.gen.ts performs a simple GET request:
public static healthCheck(): CancelablePromise<UtilsHealthCheckResponse> {
return __request(OpenAPI, {
method: 'GET',
url: '/api/v1/utils/health-check/'
});
}
Verifying Email Configuration
Beyond basic connectivity, you can verify that the system's email integration is correctly configured using the testEmail method. This is restricted to superusers.
import { UtilsService } from './client/sdk.gen';
async function verifyEmailSetup(testRecipient: string) {
try {
const response = await UtilsService.testEmail({
emailTo: testRecipient
});
console.log(response.message); // "Test email sent"
} catch (error) {
console.error("Email test failed. Check SMTP settings in .env");
}
}
Backend Implementation
The health check logic is implemented in backend/app/api/routes/utils.py. It is designed to be lightweight to minimize overhead during frequent polling.
@router.get("/health-check/")
async def health_check() -> bool:
return True
The email test route in the same file validates the configuration by attempting to send a real email using the configured SMTP settings:
@router.post(
"/test-email/",
dependencies=[Depends(get_current_active_superuser)],
status_code=201,
)
def test_email(email_to: EmailStr) -> Message:
"""
Test emails.
"""
email_data = generate_test_email(email_to=email_to)
send_email(
email_to=email_to,
subject=email_data.subject,
html_content=email_data.html_content,
)
return Message(message="Test email sent")
Troubleshooting
Shallow Health Checks
The /api/v1/utils/health-check/ endpoint currently returns a hardcoded True. While this confirms the FastAPI application is running and the routing is functional, it does not perform deep checks on downstream dependencies like the PostgreSQL database. For database readiness, the project relies on Docker-level dependencies and the prestart.sh script which runs backend/app/backend_pre_start.py to verify the DB connection before the API starts.
Email Test Permissions
If the testEmail call fails with a 403 Forbidden error, ensure the authenticated user has superuser privileges. The backend enforces this via the get_current_active_superuser dependency.
Connection Timeouts
If the Docker health check fails consistently:
- Verify the backend container is running:
docker compose ps. - Check the backend logs for startup errors:
docker compose logs backend. - Ensure the
curlcommand is available inside the backend container image.