카테고리 없음

daemonize celery with systemd

seul chan 2020. 3. 3. 21:46

Daemonize celery with systemd

Accoring to celery official documentation, you can deamonize celery with either init-script or systemd.
For using init-script, you can see here

Create celery.service

  • Add celery.service in /etc/systemd/system (It may vary for other os)
  • Update WorkingDirectory. (Same as CELERYD_CHDIR)
  • Update with your user to execute celery. I usally use celery after create celery user (adduser celery)
  • Can customize EnvironmentFile path wherever you want
[Unit]
Description=Celery Service
After=network.target

[Service]
Type=forking
User=<your_user>
Group=<your_user>
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=<your_path_to_execute_celery>
ExecStart=/bin/sh -c '${CELERY_BIN} multi start ${CELERYD_NODES} \
  -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
  --logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'
ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait ${CELERYD_NODES} \
  --pidfile=${CELERYD_PID_FILE}'
ExecReload=/bin/sh -c '${CELERY_BIN} multi restart ${CELERYD_NODES} \
  -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
  --logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'

[Install]
WantedBy=multi-user.target

Create /etc/conf.d/celery

  • Update DJANGO_SETTINGS_MODULE with your settings.
  • Update CELERY_BIN for your virtualenv celery path. (Below is path of virtualenv)
  • If wanted, you can change log, pid directory
# Name of nodes to start
# here we have a single node
#CELERYD_NODES="w1"
# or we could have three nodes:
CELERYD_NODES="w1 w2 w3"

# Absolute or relative path to the 'celery' command:
DJANGO_SETTINGS_MODULE="your_django_settings_module"
CELERY_BIN="/home/users/.cache/pypoetry/virtualenvs/my-project-7_nFoQGT-py3.7/bin/celery"

# App instance to use
# comment out this line if you don't use an app
# or fully qualified:
CELERY_APP="proj.tasks:app"

# How to call manage.py
CELERYD_MULTI="multi"

# Extra command-line arguments to the worker
CELERYD_OPTS="--time-limit=300 --concurrency=8"

# - %n will be replaced with the first part of the nodename.
# - %I will be replaced with the current child process index
#   and is important when using the prefork pool to avoid race conditions.
CELERYD_PID_FILE="/var/run/celery/%n.pid"
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_LOG_LEVEL="INFO"

# you may wish to add these options for Celery Beat
CELERYBEAT_PID_FILE="/var/run/celery/beat.pid"
CELERYBEAT_LOG_FILE="/var/log/celery/beat.log"

Give permission to log, pid directory

  • If you don't (and probably) use root user, you have to give permission for log and pid directory above (CELERYD_PID_FILE, CELERYD_LOG_FILE)
  • You can make /etc/temp.d/celery and add below
d /var/run/celery 0755 celery celery -
d /var/log/celery 0755 celery celery -
  • Or you can manually give permission using setfacl
sudo setfacl -m user:celery:rwx /var/run/celery
sudo setfacl -m user:celery:rwx /var/log/celery

Create celerybeat.service

  • Add /etc/systemd/system/celerybeat.service
Description=Celery Beat Service
After=network.target

[Service]
Type=simple
User=celery
Group=celery
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=<yyour_path_to_execute_celery>
ExecStart=/bin/sh -c '${CELERY_BIN} beat  \
  -A ${CELERY_APP} --pidfile=${CELERYBEAT_PID_FILE} \
  --logfile=${CELERYBEAT_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL}'

[Install]
WantedBy=multi-user.target

Start service

# start celery, celerybeat
sudo systemctl start celery
sudo systemctl start celerybeat

# See status that celery is running
sudo systemctl status celery
sudo systemctl status celerybeat

Troubleshooting

  • systemd not show error message well. You can use journalctl -xe for more information
  • you should run systemctl daemon-reload after changing files
  • If daemon not running, go to celery user and execute the same command like
sudo su - celery
# in celery user

/home/username/.cache/pypoetry/virtualenvs/face-crawler-7_nFoQGT-py3.7/bin/celery multi start w1 w2 w3 -A face_crawler --pidfile=/var/run/celery/%n.pid --logfile=/var/log/celery/%n.log --loglevel=INFO

kill all backgound celery manually; ps auxww | grep 'celery worker' | awk '{print $2}' | xargs kill -9