Django ` [ERROR] Worker (pid:7) was sent SIGKILL! Perhaps out of memory?` message when uploading large files

My dockerized Django app allows users to upload files(uploaded directly to my DigitalOcean Spaces). When testing it on my local device(and on my Heroku deployment) I can successfully upload small files without issue. However when uploading large files, e.g. 200+MB, I can get these error logs:

 [2024-09-29 19:00:51 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:7)
web-1     | [2024-09-29 19:00:52 +0000] [1] [ERROR] Worker (pid:7) was sent SIGKILL! Perhaps out of memory?
web-1     | [2024-09-29 19:00:52 +0000] [29] [INFO] Booting worker with pid: 29

The error occurs about 30 seconds after I've tried uploading so I suspect it's gunicorn causing the timeout after not getting a response. I'm not sure what to do to resolve it. other than increasing the timeout period which I've been told is not recommended. Here is my code handling file upload:

views.py:

@csrf_protect
def transcribe_submit(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            uploaded_file = request.FILES['file']

            request.session['uploaded_file_name'] = uploaded_file.name
            request.session['uploaded_file_size'] = uploaded_file.size

            session_id = str(uuid.uuid4())
            request.session['session_id'] = session_id

            try:
                transcribed_doc, created = TranscribedDocument.objects.get_or_create(id=session_id)
                transcribed_doc.audio_file = uploaded_file
                transcribed_doc.save()
          ...

            except Exception as e:
                # Log the error and respond with a server error status
                print(f"Error occurred: {str(e)}")
                return HttpResponse(status=500)

          ...
        else:
            return HttpResponse(status=500)
    else:
        form = UploadFileForm()
        
    return render(request, 'transcribe/transcribe-en.html', {"form": form})

forms.py:

def validate_audio_language(value):
    #code to validate audio language
    if value not in allowed_languages:
        raise ValidationError("Error")

def validate_output_file_type(value):
    #code to validate file type
    if value not in output_file_type:
        raise ValidationError("Error")
    
class UploadFileForm(forms.Form):
    file = forms.FileField(validators=[validate_file])

docker-compose.yml:

#version: "3.9"
services:
  web:
    build: .
    #command: python /code/manage.py runserver  0.0.0.0:8000
    command: gunicorn mysite.wsgi -b 0.0.0.0:8000 --reload
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db
      - redis
      - celery
    environment:
      -  "DJANGO_SECRET_KEY="
      
    user: user-me
  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"
  redis:
    image: redis:6
    ports:
      - 6379:6379
  celery:
    build: .
    command: celery -A mysite worker --loglevel=info 
    volumes:
      - .:/code
    depends_on:
      - redis
      - db
    environment:
      -  "DJANGO_SECRET_KEY="

    user: user-me
volumes:
  postgres_data:
Back to Top