Docker ortamında Celery tabanlı bir uygulama dağıttığınızda, şu hata ile karşılaşabilirsiniz:

_gdbm.error: [Errno 13] Permission denied: 'celerybeat-schedule'

Bu sorun, her şeyin yerel geliştirme ortamınızda sorunsuz çalışmasına rağmen ortaya çıkabilir. Bu makale, bu sorunun temel nedenini açıklar ve onu çözmek için sistematik bir yaklaşım sunar.


Sorunun Tanımı

Celery Beat, periyodik görevleri zamanlamaktan sorumlu olup, zamanlama bilgilerini saklamak için dosya tabanlı bir veritabanı kullanır. Varsayılan olarak bu veritabanı, celerybeat-schedule adlı bir dosyada saklanır. Celery Beat, Docker ortamında bu dosyayı oluşturmayı veya güncellemeyi denerken izin reddedildi hatasıyla başarısız olabilir.

Bu sorun genellikle şu nedenlerden kaynaklanır:

  1. Volume Bağlama Sorunları: celerybeat-schedule dosyasının saklandığı Docker volume doğru yazma izinlerine sahip değildir.
  2. Kullanıcı Uyuşmazlığı: Konteyner içinde Celery'yi çalıştıran kullanıcı, bağlanan volume dizinine yazma iznine sahip değildir.
  3. Kalıntı Dosyalar: Önceki bir çalışmadan kalan hatalı bir celerybeat-schedule dosyası yanlış izinlerle bırakılmış olabilir.
  4. Ana Makine Seviyesi Kısıtlamaları: Bağlanan dizin üzerindeki ana makine izinleri sınırlayıcı olabilir.

Çözüm

Bu sorunu teşhis etmek ve çözmek için aşağıdaki adımları izleyin.

1. Docker Volume İzinlerini Kontrol Edin

Öncelikle ana makinedeki volume bağlama noktasını bulun:

docker volume inspect <volume_name>

Örneğin:

"Mountpoint": "/var/lib/docker/volumes/<volume_name>/_data"

Ana makine dizininde uygun izinlere sahip olduğunuzdan emin olun:

sudo chmod -R 777 /var/lib/docker/volumes/<volume_name>/_data

Bu komut, tüm kullanıcıların dizindeki dosyaları okuma, yazma ve çalıştırma iznine sahip olmasını sağlar.

2. Kalıntı Dosyaları Temizleyin

Yanlış izinlerle oluşturulmuş olabilecek mevcut celerybeat-schedule dosyasını kaldırın:

docker exec -it <container_name> bash
rm -f /path/to/celerybeat-schedule

Çoğu yapılandırmada, bu dosya /celery_data dizininde veya CELERYBEAT_SCHEDULE_FILENAME ortam değişkeni ile belirtilen başka bir yerde bulunur.

3. Konteyner İçindeki Sahiplik ve İzinleri Kontrol Edin

Konteyner içindeki dizin sahipliğini ve izinlerini doğrulayın:

ls -la /path/to/celery_data

Dizin Celery'yi çalıştıran kullanıcıya (ör. celery) ait değilse, sahipliği ayarlayın:

chown -R celery:celery /path/to/celery_data
chmod -R 777 /path/to/celery_data

4. Dockerfile'ı Güncelleyin

İzinlerin görüntü oluşturma sırasında ayarlandığından emin olmak için Dockerfile dosyasını şu satırları içerecek şekilde güncelleyin:

Dockerfile.celery Örneği

FROM python:3.12.8-slim-bookworm

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    gcc \
    python3-dev \
    libpq-dev \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Create celery user and group
RUN groupadd -r celery && useradd -r -g celery celery

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Set working directory
WORKDIR /app

# Copy requirements and install dependencies
COPY app/requirements.txt .
RUN pip install -r requirements.txt watchdog

# Copy all app files to /app
COPY app/ .

# Create and set permissions for /celery_data
RUN mkdir -p /celery_data \
    && chmod -R 777 /celery_data \
    && chown -R celery:celery /celery_data

# Set permissions for /app
RUN chown -R celery:celery /app

# Switch to celery user
USER celery

# Command to run Celery worker with beat
CMD ["sh", "-c", "watchmedo auto-restart --directory=./ --pattern='*.py' --recursive -- celery -A config.celery_config worker --beat -s /celery_data/celerybeat-schedule --loglevel=info --concurrency=1"]

Bu yapılandırma, celery_data dizinini oluşturur, gerekli izinleri verir ve doğru kullanıcıya (celery) ait olmasını sağlar.

5. docker-compose.yml Dosyasını Güncelleyin

Konteyner yapılandırmasını doğru şekilde yapmak için docker-compose.yml dosyanızı şu şekilde yapılandırın:

docker-compose.yml Örneği

version: '3.8'

services:
  celery_worker:
    build:
      context: .
      dockerfile: docker/Dockerfile.celery
    container_name: celery_worker
    environment:
      - CELERYBEAT_SCHEDULE_FILENAME=/celery_data/celerybeat-schedule
    volumes:
      - celery_data:/celery_data
    depends_on:
      - redis
    networks:
      - my_network

  redis:
    image: redis:latest
    container_name: redis
    ports:
      - "6379:6379"
    networks:
      - my_network

volumes:
  celery_data:

networks:
  my_network:
    driver: bridge

6. Konteynerleri Yeniden Başlatın

Tüm değişiklikleri uyguladıktan sonra sistemi yeniden başlatın:

docker-compose down
docker-compose up -d

7. Çözümü Doğrulayın

Hatanın çözülüp çözülmediğini doğrulamak için günlükleri izleyin:

docker logs <container_name>

Celery Beat'in herhangi bir izin hatası olmadan başarıyla başlatıldığını görmelisiniz.


Sonuç

Docker ortamlarında celerybeat-schedule ile ilgili izin reddedildi sorunu, genellikle ana makine ile konteyner arasındaki izin uyuşmazlıklarından kaynaklanır. Volume izinlerini, konteyner kullanıcı sahipliğini ve kalıntı dosyaları düzenli bir şekilde ele alarak bu sorunu çözebilirsiniz. Bu kılavuz, sorunu teşhis etmek ve çözmek için kapsamlı bir yol haritası sunar, böylece Celery Beat sorunsuz bir şekilde çalışır.