1

Admin page can get access to the image file saved in database but Celery task can't get access to that image file and shows error FileNotFoundError(2, 'No such file or directory'). docker-compose.yml

version: "3"

services: 
    app: &app
        build: 
            context: .
        ports: 
            - "8000:8000"
        volumes: 
            - ./backend:/backend
        command: >
            sh -c "python manage.py wait_for_db &&
                    python manage.py migrate &&
                    python manage.py runserver 0.0.0.0:8000"
        environment: 
            - SECRET_KEY=mysecretkey
            - DB_HOST=db
            - DB_NAME=election
            - DB_USER=postgres
            - DB_PASS=supersecretpassword
        depends_on: 
            - db
            - redis
    db:
        image: postgres:12-alpine
        environment: 
            - POSTGRES_DB=election
            - POSTGRES_USER=postgres
            - POSTGRES_PASSWORD=supersecretpassword
        volumes:
            - postgresql_data:/var/lib/postgresql/data
        ports:
            - 5432:5432
    redis:
        image: redis:6-alpine
    celery:
        <<: *app
        command: celery -A app worker -l INFO
        ports: []
        volumes: 
            - ./backend:/backend
        depends_on:
            - app
            - redis
            - db
volumes: 
    postgresql_data:

Dockerfile

FROM python:3.8 

ENV PYTHONUNBUFFERED 1


# Face-recognition model
RUN apt-get -y update
RUN apt-get install -y --fix-missing \
    build-essential \
    cmake \
    gfortran \
    git \
    wget \
    curl \
    graphicsmagick \
    libgraphicsmagick1-dev \
    libatlas-base-dev \
    libavcodec-dev \
    libavformat-dev \
    libgtk2.0-dev \
    libjpeg-dev \
    liblapack-dev \
    libswscale-dev \
    pkg-config \
    python3-dev \
    python3-numpy \
    software-properties-common \
    zip \
    # web3
    libssl-dev \
    # QR code
    zbar-tools \
    libzbar-dev \
    && apt-get autoremove \
    && apt-get clean && rm -rf /tmp/* /var/tmp/*
        
COPY ./requirements.txt /requirements.txt
RUN pip install -r requirements.txt

RUN mkdir /backend
WORKDIR /backend
COPY ./backend /backend

RUN mkdir -p /vol/web/media
RUN mkdir -p /vol/web/static

RUN useradd -ms /bin/bash user
RUN chown -R user:user /vol/
RUN chmod -R 755 /vol/web
USER user

Celery task

from celery import shared_task
from django.contrib.auth import get_user_model
from django.core.mail import send_mail
from django.core.mail import EmailMessage
from email.mime.image import MIMEImage

from django.core.mail import message

from core.models import Profile
from django.template.loader import render_to_string

from time import sleep
import os

@shared_task
def id_generated(profile_id):
    """
    Task to send an e-mail with ID image attached.
    """
    profile = Profile.objects.get(id=profile_id)
    print(profile.id_card)
    subject = 'ID card.'
    print(profile.id_card.path)
    message = render_to_string('mails/id_card_html.html')
    email = EmailMessage(subject,
                         message,
                         'admin@myshop.com',
                         [profile.user.email])
    image = profile.id_card.open().read()
    email.attach(image)
    email.add_header('Content-ID', '<embed_image>')
    email.send()

And Error is

celery_1  | [2020-09-28 11:35:28,604: ERROR/ForkPoolWorker-1] Task core.tasks.id_generated[b11d5f6d-0b7c-4e97-a548-1787ac49c80a] raised unexpected: FileNotFoundError(2, 'No such file or directory')
celery_1  | Traceback (most recent call last):
celery_1  |   File "/usr/local/lib/python3.8/site-packages/celery/app/trace.py", line 409, in trace_task
celery_1  |     R = retval = fun(*args, **kwargs)
celery_1  |   File "/usr/local/lib/python3.8/site-packages/celery/app/trace.py", line 701, in __protected_call__
celery_1  |     return self.run(*args, **kwargs)
celery_1  |   File "/backend/core/tasks.py", line 33, in id_generated
celery_1  |     image = profile.id_card.open().read()
celery_1  |   File "/usr/local/lib/python3.8/site-packages/django/db/models/fields/files.py", line 74, in open
celery_1  |     self.file = self.storage.open(self.name, mode)
celery_1  |   File "/usr/local/lib/python3.8/site-packages/django/core/files/storage.py", line 36, in open
celery_1  |     return self._open(name, mode)
celery_1  |   File "/usr/local/lib/python3.8/site-packages/django/core/files/storage.py", line 231, in _open
celery_1  |     return File(open(self.path(name), mode))
celery_1  | FileNotFoundError: [Errno 2] No such file or directory: '/vol/web/media/uploads/user/2/card/2f6552ec-d86c-4a4b-886e-923bf9d21742.jpg'

Image file can be read anywhere except from celery task, Any solution?

1 Answers1

1

In Docker compose you need to share the volume between both containers ie. celery and app. Refer to this https://stackoverflow.com/a/44284993/2138792

Sayok88
  • 2,038
  • 1
  • 14
  • 22