生产环境部署Read The Docs(Nginx+Gunicorn)遇构建失败求助
Hey there, let's figure out why your RTD builds are stuck on "Triggered version latest (html)" when using the production stack—since it works with python manage.py runserver, the core setup is solid, so the issue is almost certainly tied to how your production services are running or permissions. Here's how to debug step by step:
1. Double-Check Permissions
When you run runserver, you're using your local user account, but Supervisord typically runs apps under a dedicated system user (like www-data or a custom rtd user). Mismatched permissions are one of the most common culprits here:
- Ensure the supervisord user owns the RTD project directory, build cache, and log folders:
sudo chown -R rtd-user:rtd-group /path/to/your/rtd-project sudo chown -R rtd-user:rtd-group /var/lib/readthedocs/builds/ - Verify the user has access to your Python virtual environment (if you're using one) and any Git repositories linked to your RTD projects (check for SSH key access if using private repos).
2. Validate Gunicorn & Supervisord Configs
A misconfigured service can break RTD's ability to handle build triggers:
- Supervisord Gunicorn Config: Make sure your
rtd-gunicornprogram points to the correct virtual environment, working directory, and user. Example config snippet:[program:rtd-gunicorn] command=/path/to/venv/bin/gunicorn --workers 3 --bind unix:/tmp/rtd.sock readthedocs.wsgi:application directory=/path/to/your/rtd-project user=rtd-user autostart=true autorestart=true stderr_logfile=/var/log/rtd/gunicorn.err.log stdout_logfile=/var/log/rtd/gunicorn.out.log - Check Gunicorn Logs: Look for startup errors (like missing modules or incorrect settings) in the stderr log file you defined.
- Nginx & Socket Permissions: Ensure the Unix socket (e.g.,
/tmp/rtd.sock) has permissions that let Nginx access it. Either setchmod 775 /tmp/rtd.sockor add the Nginx user to yourrtd-group.
3. Don't Forget Celery (Critical for Builds!)
RTD uses Celery to handle asynchronous build tasks—if your Celery worker isn't running, build jobs will sit in the queue forever:
- Add a Celery worker to your Supervisord config:
[program:rtd-celery] command=/path/to/venv/bin/celery -A readthedocs worker --loglevel=info directory=/path/to/your/rtd-project user=rtd-user autostart=true autorestart=true stderr_logfile=/var/log/rtd/celery.err.log stdout_logfile=/var/log/rtd/celery.out.log - Restart Supervisord to load the new config:
sudo systemctl restart supervisord - Check the Celery logs for errors related to task queue connections (like Redis/RabbitMQ issues if you're using an external broker).
4. Inspect RTD Build & Environment Logs
Dig into RTD's own logs to find build-specific errors:
- Look for logs in
/var/log/readthedocs/or your project's locallogs/directory. - Compare your local environment variables with what Supervisord uses: When running
runserver, you might be loading a.envfile, but Supervisord won't do this automatically. Add critical env vars to your Supervisord config:environment=DJANGO_SETTINGS_MODULE="readthedocs.settings.production",SECRET_KEY="your-production-secret",DATABASE_URL="postgres://user:pass@localhost/rtd_db" - Ensure your production settings (
readthedocs.settings.production) have correct database, cache, and build directory paths.
5. Test Builds Manually as the Supervisord User
The fastest way to pinpoint errors is to run the build process directly as the user Supervisord uses:
sudo su - rtd-user cd /path/to/your/rtd-project source venv/bin/activate python manage.py build --project your-project-slug --version latest
If this fails, you'll get a direct error message (missing dependencies, permission denied, etc.) that will tell you exactly what's broken.
内容的提问来源于stack exchange,提问作者RLott

