Skip to content

Deploy drf, celecry worker and beat into aws lightsail container

0

I deployed my Django Rest Framework (DRF) project to AWS Lightsail Containers, and everything works well with the DRF application. The DRF container is public, and I opened port 8000 for it. I do receive occasional warnings about adding some IPs to the ALLOWED_HOSTS, but otherwise, no health check issues are reported for this container.

I also created two additional containers—one for the Celery worker and another for Celery beat. Neither of these containers have exposed ports because they do not serve web traffic, but I keep receiving the following message for both:

[deployment:50] Health checks failed: port 8000 is unhealthy

I believe this message is related to the fact that there is no port opened for the Celery containers for the load balancer to check for health. I’ve enabled peering between my containers for internal communication with Redis, and I also allowed the Lightsail CIDR block in my VPC security groups.

What should I do to avoid these health check failures for the Celery worker and beat containers, which don't expose any ports?

I also cannot create 2 lightsail containers because I can connect both to the same image in ecr.

Thank you in advance!

1 Answer
0

Hi Bruno,

Let's dive into your issue.

Clarifying the Issue

You've deployed a Django Rest Framework (DRF) project into AWS Lightsail Containers, and it’s working fine with a public container exposing port 8000. However:

  1. Additional containers for Celery Worker and Celery Beat are failing health checks.
  2. These containers don’t expose any ports since they handle background tasks, not web traffic.
  3. Lightsail’s health check system reports “port 8000 is unhealthy” because no port is listening.

Key Terms

  • AWS Lightsail: A simplified AWS platform for deploying servers, containers, and databases quickly without managing complex infrastructure.

  • Celery: An open-source task queue for Python, enabling asynchronous execution of background tasks like sending emails or processing data.

  • Celery Worker: A Celery component that executes background tasks by continuously pulling jobs from a queue.

  • Celery Beat: A scheduler that sends periodic tasks to Celery Workers. Think of it as a timer that triggers jobs at scheduled intervals.

  • Sidecar: A containerized helper process that runs alongside the main container to handle auxiliary tasks, such as logging, monitoring, or health checks. Named after motorcycle sidecars, which carry extra cargo or passengers.


Our Proposed Solution (The Recipe)

To resolve the health check failures for Celery Worker and Beat containers that don’t expose ports, we’ll introduce a lightweight health check endpoint. This endpoint will respond to Lightsail’s health checks without interfering with Celery’s operations.


Recipe for Fixing Health Check Failures

1. Add a Simple Health Check Endpoint

Since Lightsail relies on HTTP-based health checks, we’ll expose a minimal HTTP server alongside the Celery process. This ensures Lightsail can confirm the container is alive.

Here’s an example of using Python’s built-in HTTP server:

python3 -m http.server 8000 --bind 0.0.0.0

This command starts a lightweight server on port 8000, which responds to health checks.


2. Combine Celery and the Health Check in a Single Container

Modify your Dockerfile to start both the Celery process and the health check server:

FROM python:3.9

# Install dependencies
RUN pip install celery

# Copy application code
COPY . /app
WORKDIR /app

# Start Celery Worker and a health check server
CMD celery -A my_project worker & python3 -m http.server 8000 --bind 0.0.0.0
  • celery -A my_project worker: Starts the Celery Worker process.
  • python3 -m http.server: Provides a minimal health check endpoint.

For Celery Beat, replace the worker command with:

celery -A my_project beat

3. Use a Sidecar Container (Optional)

If you prefer cleaner separation, run the health check endpoint in a sidecar container alongside Celery. This container will handle the health check independently.

  • Main container: Runs Celery Worker or Beat.
  • Sidecar container: Exposes the HTTP server for health checks.

Example docker-compose.yml setup:

version: '3'
services:
  celery-worker:
    image: my-celery-worker-image
    command: celery -A my_project worker
  health-check:
    image: python:3.9
    command: python3 -m http.server 8000 --bind 0.0.0.0

4. Configure Lightsail Health Checks

In AWS Lightsail:

  • Set the health check port to 8000 (the HTTP server port).
  • Lightsail will send requests to the exposed endpoint and receive a 200 OK response, marking the container healthy.

5. Deploy the Updated Containers

Rebuild and push your updated Docker images to Elastic Container Registry (ECR):

docker build -t my-celery-container .
docker push <aws_account_id>.dkr.ecr.<region>.amazonaws.com/my-celery-container

Update your Lightsail container service to use the new image.


Why This Works

  • Lightsail gets a valid health check response without requiring Celery to expose unnecessary ports.
  • Adding a lightweight HTTP server ensures minimal overhead and no impact on Celery tasks.
  • The sidecar approach provides clean separation if preferred.

If you need some additional troubleshooting, please feel free to reach out.

Cheers, Aaron 🚀✨

answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.