On a Linux Ubuntu 22.04 LTS server, this is the configuration of Celery and Celery Beat with systemd, following most of the instructions in the Daemonization guide of Celery.
- Note: this assumes that Redis is installed (
sudo apt install redis-server) and all the Python packages inrequirements.txt. It is possible to check if Redis is running withsudo systemctl is-enabled redis-server.
Configuring Celery as a system service. Preliminaries:
- The Django project is in
/home/bucr/realtime - The virtual environment is in
/home/bucr/realtime/realtimeenv/bin - The user is
bucrand belongs to the groupbucr
The environment variables are located in the file /etc/conf.d/celery, as shown below.
# Name of nodes to start
CELERYD_NODES="w1"
# Absolute or relative path to the 'celery' command:
CELERY_BIN="/home/bucr/realtime/realtimeenv/bin/celery"
# App instance to use
CELERY_APP="realtime"
# How to call manage.py
CELERYD_MULTI="multi"
# Extra command-line arguments to the worker
CELERYD_OPTS="--time-limit=300 --concurrency=1"
# - %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"
# Celery Beat
CELERYBEAT_SCHEDULER="django_celery_beat.schedulers:DatabaseScheduler"
CELERYBEAT_PID_FILE="/var/run/celery/beat.pid"
CELERYBEAT_LOG_FILE="/var/log/celery/beat.log"Notes:
- Concurrency is set to 1 because current servers have single CPU(s), thread(s) per core and core(s) per socket.
- The directories
/var/run/celery/and/var/log/celery/for the PID and LOG files, respectively, must first be created when configuring Celery. So:
sudo mkdir -p /var/run/celery/
sudo mkdir -p /var/log/celery/- Now the user and group
bucr:bucrneed permissions for those directories:
sudo chown bucr:bucr /var/run/celery/
sudo chown bucr:bucr /var/log/celery/- The PID file and log file must be created on each reboot with the following configuration, where
bucr bucris the user and group and0755are the permissions.
d /run/celery 0755 bucr bucr -
d /var/log/celery 0755 bucr bucr -This process is configured below.
[Unit]
Description=Celery Service
After=network.target
[Service]
Type=forking
User=bucr
Group=bucr
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=/home/bucr/realtime/
RuntimeDirectory=celery
ExecStart=/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi start $CELERYD_NODES \
--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} \
--logfile=${CELERYD_LOG_FILE} \
--loglevel="${CELERYD_LOG_LEVEL}"'
ExecReload=/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi restart $CELERYD_NODES \
--pidfile=${CELERYD_PID_FILE} \
--logfile=${CELERYD_LOG_FILE} \
--loglevel="${CELERYD_LOG_LEVEL}" \
$CELERYD_OPTS'
Restart=always
[Install]
WantedBy=multi-user.targetRelevant systemctl commands:
- On every change to this file:
sudo systemctl daemon-reload - To start:
sudo systemctl start celery - To stop:
sudo systemctl stop celery - To check status:
sudo systemctl status celery - To allow execution on reboot:
sudo systemctl enable celery - Others:
restart/reload/is-enabled/disable
This process is configured below.
- Note: the periodic tasks are configured in the Django admin panel, thanks to the package
django-celery-beat, and as configured here with--schedulerasdjango_celery_beat.schedulers:DatabaseScheduler.
[Unit]
Description=Celery Beat Service
After=network.target celery.service
[Service]
Type=simple
User=bucr
Group=bucr
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=/home/bucr/realtime/
ExecStart=/bin/sh -c '${CELERY_BIN} -A ${CELERY_APP} beat \
--pidfile=${CELERYBEAT_PID_FILE} \
--logfile=${CELERYBEAT_LOG_FILE} \
--loglevel=${CELERYD_LOG_LEVEL} \
--scheduler ${CELERYBEAT_SCHEDULER}'
Restart=always
[Install]
WantedBy=multi-user.targetRelevant systemctl commands:
- On every change to this file:
sudo systemctl daemon-reload - To start:
sudo systemctl start celerybeat - To stop:
sudo systemctl stop celerybeat - To check status:
sudo systemctl status celerybeat - To allow execution on reboot:
sudo systemctl enable celerybeat - Others:
restart/reload/is-enabled/disable
For using Channels and WebSockets, it is necessary to configure the Daphne server.
[Unit]
Description=WebSocket Daphne Service
After=network.target
[Service]
User=bucr
Group=www-data
WorkingDirectory=/home/bucr/realtime
ExecStart=/home/bucr/realtime/realtimeenv/bin/daphne -p 8001 realtime.asgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.target
Relevant systemctl commands:
- On every change to this file:
sudo systemctl daemon-reload - To start:
sudo systemctl start daphne - To stop:
sudo systemctl stop daphne - To check status:
sudo systemctl status daphne - To allow execution on reboot:
sudo systemctl enable daphne - Others:
restart/reload/is-enabled/disable
It is necessary to allow execution on reboot with sudo systemctl enable daphne.
Now, for Nginx to proxy pass to Daphne, the following is needed:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/bucr/realtime;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location /ws/ {
proxy_pass http://localhost:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo nano restart_services.shwhere
#!/bin/bash
sudo systemctl restart celery
sudo systemctl restart celerybeat
sudo systemctl restart daphne
sudo systemctl restart gunicorn
sudo systemctl restart nginxand make executable with
sudo chmod +x restart_services.shand then execute
./restart_services.sh