Sửa lỗi AWS Elastic Beanstalk Deploy Failed: WSGIPath Không Tồn Tại & Health Check Severe

intermediate☁️ AWS2026-04-21| AWS Elastic Beanstalk, Python (Django/Flask), Amazon Linux 2 / Amazon Linux 2023, EB CLI 3.x

Error Message

ERROR: Your WSGIPath refers to a file that does not exist. / Instance deployment failed. For details, see 'eb-engine.log'. / Environment health has transitioned from Ok to Severe
#aws#elastic-beanstalk#health-check#deploy#eb-engine#wsgi

Lỗi Gặp Phải

Bạn vừa đẩy một phiên bản mới lên Elastic Beanstalk và quá trình triển khai bị thất bại. Bảng điều khiển EB chuyển sang trạng thái Severe, và nhật ký sự kiện hiển thị thông báo tương tự như sau:

ERROR: Your WSGIPath refers to a file that does not exist.
Instance deployment failed. For details, see 'eb-engine.log'.
Environment health has transitioned from Ok to Severe

Thường thì lỗi này đi kèm với các sự cố health check của load balancer — LB liên tục gửi request đến các instance, nhận lại toàn lỗi, và EB đánh dấu chúng là không khỏe mạnh. Môi trường sẽ trượt dần từ Ok → Warning → Severe trong chưa đầy hai phút.

Đây là hai vấn đề riêng biệt nhưng có liên quan đến nhau. Hãy sửa lỗi cấu hình WSGI trước. Các lỗi health check hầu như sẽ tự giải quyết khi ứng dụng khởi động được.

Nguyên Nhân

EB cần biết WSGI callable của bạn nằm ở đâu. Nó tìm kiếm thông tin này qua .ebextensions, một Procfile, hoặc namespace aws:elasticbeanstalk:container:python. Nếu đường dẫn đó không khớp với những gì có trong file zip triển khai, app server — Apache + mod_wsgi trên Amazon Linux 2, hoặc gunicorn trên AL2023 — sẽ không bao giờ khởi động được.

Các nguyên nhân thường gặp:

  • WSGIPath vẫn trỏ đến application.py, nhưng bạn đã đổi tên hoặc tái cấu trúc project
  • Project Django được triển khai mà không đặt đường dẫn đến myproject/wsgi.py
  • .ebignore hoặc .gitignore đang âm thầm loại trừ file wsgi khỏi bundle
  • Lỗi đóng gói trong CI/CD — file zip tải lên S3 bị thiếu file hoàn toàn
  • Đường dẫn health check trả về redirect (301/302) hoặc trang xác thực thay vì 200

Bước 1 — Đọc Log Trước Khi Làm Bất Cứ Điều Gì

Phỏng đoán chỉ tốn thêm lần deploy. Hãy kéo log về trước:

# Via EB CLI
eb logs

# Hoặc xem trực tiếp theo thời gian thực
eb logs --stream

Tập trung vào hai file: eb-engine.log cho biết chính xác đường dẫn nào EB đã cố tải. web.stdout.log cho biết điều gì xảy ra khi app server thực sự cố khởi động — lỗi import, thiếu biến môi trường, và các vấn đề tương tự.

Thích giao diện đồ họa? Vào Environment → Logs → Request Logs → Last 100 Lines trong console.

Bước 2 — Sửa WSGIPath

Kiểm tra đường dẫn mà EB đang được cấu hình để sử dụng:

eb config

Lệnh này sẽ mở cấu hình môi trường trong một trình soạn thảo. Tìm phần này:

aws:elasticbeanstalk:container:python:
  WSGIPath: application:application

Định dạng là module_path:callable cho một đối tượng Python, hoặc đường dẫn file đơn giản cho wsgi.py của Django. Đây là giá trị đúng cho các thiết lập phổ biến:

Flask (file đơn)

# application.py chứa: app = Flask(__name__)
aws:elasticbeanstalk:container:python:
  WSGIPath: application:app

Django

aws:elasticbeanstalk:container:python:
  WSGIPath: myproject/wsgi.py

Thay myproject bằng tên thư mục project Django thực tế của bạn — thư mục chứa settings.py, không phải thư mục gốc của repo.

Cách quản lý gọn nhất là đưa vào version control trong .ebextensions/python.config:

option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: myproject/wsgi.py
    NumProcesses: 1
    NumThreads: 15

Như vậy đường dẫn đúng sẽ được đóng gói trong mỗi lần deploy, và bạn không phải phụ thuộc vào cấu hình môi trường mà ai đó có thể vô tình ghi đè.

Với Django, hãy đảm bảo module settings cũng được thiết lập:

eb setenv DJANGO_SETTINGS_MODULE=myproject.settings

Bước 3 — Xác Nhận File Thực Sự Có Trong Bundle Triển Khai

Khi bạn chạy eb deploy, EB sẽ nén project của bạn bằng git — nghĩa là nó tuân theo .gitignore. Nếu file wsgi không được theo dõi, nó sẽ không được đóng gói.

# Kiểm tra những gì EB thực sự đưa vào
git ls-files | grep wsgi

Không có kết quả? File chưa được theo dõi. Hãy commit nó, hoặc ghi đè phần loại trừ bằng .ebignore:

# .ebignore — buộc đưa vào dù .gitignore có loại trừ
!myproject/wsgi.py

Đóng gói zip thủ công trong CI/CD? Hãy xác minh nội dung trực tiếp:

unzip -l deploy.zip | grep wsgi

Lệnh này phát hiện được một lỗi CI khá phổ biến khi bước đóng gói chạy từ sai thư mục và tạo ra một file zip với cấu trúc bên trong không đúng.

Bước 4 — Sửa Đường Dẫn Health Check

Ứng dụng có thể đang chạy bình thường, nhưng load balancer vẫn đánh dấu các instance là không khỏe mạnh. Mặc định, EB gửi request đến / mỗi 30 giây. Nếu đường dẫn đó redirect (chẳng hạn đến trang đăng nhập) hoặc trả về bất cứ thứ gì khác ngoài 2xx, health check sẽ thất bại.

Thêm một endpoint health check đơn giản luôn trả về 200:

# Flask
@app.route('/health')
def health():
    return 'OK', 200
# Django (urls.py)
from django.http import HttpResponse

urlpatterns = [
    path('health/', lambda request: HttpResponse('OK')),
    # ... phần còn lại của urls
]

Sau đó trỏ EB vào đó. Trong console: Configuration → Load Balancer → Processes → Health check path → /health.

Hoặc trong .ebextensions:

option_settings:
  aws:elasticbeanstalk:application:
    Application Healthcheck URL: /health

Bước 5 — Triển Khai Lại và Theo Dõi

eb deploy --staged

Xem các sự kiện khi quá trình chạy:

eb events -f

Triển khai thành công nhưng health vẫn còn Severe? Hãy chờ — EB yêu cầu một số lần health check thành công liên tiếp (thường là 3 lần, cách nhau khoảng 90 giây) trước khi chuyển lại về Ok.

Xác Nhận Thành Công

Bạn đã hoàn thành khi cả ba điều kiện này đều đúng:

  • Console hiển thị Health: Ok (màu xanh)
  • eb status báo cáo Health: Green
  • URL ứng dụng phản hồi đúng
eb status
# Kết quả mong đợi:
# Environment details for: your-env-name
#   Status: Ready
#   Health: Green
curl -I https://your-env.elasticbeanstalk.com/health
# Kết quả mong đợi: HTTP/1.1 200 OK

Tham Khảo Nhanh — Các Giá Trị WSGIPath Thường Gặp

  • Flask (application.py → app): application:app
  • Flask (application.py → application): application:application
  • Django: myproject/wsgi.py
  • FastAPI với Mangum: main:handler (dù FastAPI thường chạy trên Lambda hơn là EB)

Vẫn Thất Bại? SSH Vào Instance

Nếu tất cả những bước trên đã kiểm tra xong mà deploy vẫn chết, hãy vào thẳng instance:

eb ssh

# Kiểm tra tiến trình app server
sudo systemctl status web

# Đọc trực tiếp log của engine
sudo tail -50 /var/log/eb-engine.log

Chín trên mười lần, những gì bạn sẽ tìm thấy là một biến môi trường bị thiếu — SECRET_KEY trong Django là ví dụ điển hình nhất. Ứng dụng bị crash khi khởi động, không phục vụ được một request nào, và EB báo cáo toàn bộ sự việc như là lỗi health check. Lỗi thực sự bị chôn vùi trong web.stdout.log, không phải trong các sự kiện health check.

Related Error Notes