How to Running celeryd as a daemon in ubuntu? - python

i am trying to install an init.d script, to run celery for scheduling tasks. when i tried to start it by sudo /etc/init.d/celeryd start, it throws error "User does not exist: 'celery'"
my celery configuration file (/etc/default/celeryd) contains these:
# Workers should run as an unprivileged user.
CELERYD_USER="celery"
CELERYD_GROUP="celery"
i know that these are wrong that is why it throws error.
The documentation just says this:
CELERYD_USER
User to run celeryd as. Default is current user.
nothing more about it.
Any help will be appreciated.

I am adding a proper answer in order to be clearly visible:
Workers are unix processes that will run the various celery tasks. As you can see in the documentation, the CELERYD_USER and CELERYD_GROUP determine the name of user and group these workers will be run in your Unix environment.
So, what happened initially in your case is that celery tried to start the worker with a user named "celery" which did not exist in your system. When you commented out these two options, then celery started the workers with the user that issued the command sudo /etc/init.d/celeryd start which in this case is the root (administrator) user (default is the current user).
However, it is recommended to run the workers as unpriviledged users and not as root for obvious reasons. So I recommend to actually add the celery user and group using the small tutorial found here http://www.cyberciti.biz/faq/unix-create-user-account/ and uncomment again the
CELERYD_USER="celery"
CELERYD_GROUP="celery"
options.

Related

Django: Celery worker in production, Ubuntu 18+

I'm learning Celery and I'd like to ask:
Which is the absolute simplest way to get Celery to automatically run when Django starts in Ubuntu?. Now I manually start celery -A {prj name} worker -l INFO via the terminal.
Can I make any type of configuration so Celery catches the changes in tasks.py code without the need to restart Celery? Now I ctrl+c and type celery -A {prj name} worker -l INFO every time I change something in the tasks.py code. I can foresee a problem in such approach in production if I can get Celery start automatically ==> need to restart Ubuntu instead?.
(setup: VPS, Django, Ubuntu 18.10 (no docker), no external resources, using Redis (that starts automatically)
I am aware it is a similar question to Django-Celery in production and How to ... but still it is a bit unclear as it refers to amazon and also using shell scripts, crontabs. It seems a bit peculiar that these things wouldn't work out of the box.
I give benefit to the doubt that I have misunderstood the setup of Celery.
I have a deploy script that launch Celery in production.
In production it's better to launch worker :
celery multi stop 5
celery multi start 5 -A {prj name} -Q:1 default -Q:2,3 QUEUE1 -Q:4,5 QUEUE2 --pidfile="%n.pid"
this will stop and launch 5 worker for different Queue
Celery at launch will get the wsgi file that will use this instance of your code, it's mean you need to relaunch it to apply modification, you cannot add a watcher in production (memory cost)

Can I have multiple commands run in a manifest.yml file?

I have a question about manifest.yml files, and the command argument. I am trying to run multiple python scripts, and I was wondering if there was a better way that I can accomplish this?
command: python3 CD_Subject_Area.py python3 CD_SA_URLS.py
Please let me know how I could call more than one script at a time. Thanks!
To run a couple of short-term (ie. run and eventually exit) commands you would want to use Cloud Foundry tasks. The reason to use tasks over adding a custom command into manifest.yml or a Procfile is because the tasks will only run once.
If you add the commands above, as you have them, they may run many times. This is because an application on Cloud Foundry will run and should execute forever. If it exits, the platform considers it to have crashed and will restart it. Thus when your task ends, even if it is successful (i.e. exit 0), the platfrom still thinks it's a crash and will run it again, and again, and again. Until you stop your app.
With a task, you'd do the following instead:
cf push your application. This will start and stage the application. You can simply leave the command/-c argument as empty and do not include a Procfile[1][2]. The push will execute, the buildpack will run and stage your app, and then it will fail to start because there is no command. That is OK.
Run cf stop to put your app into the stopped state. This will tell the platform to stop trying to restart it.
Run cf run-task <app-name> <command>. For example, cf run-task my-cool-app "python3 CD_Subject_Area.py". This will execute the task in it's own container. The task will run to completion. Looking at cf tasks <app-name> will show you the result. Using cf logs <app-name> --recent will show you the output.
You can then repeat this to run any number of other tasks commands. You don't need to wait for the original one to run. They will all execute in separate containers so one task is totally separated from another task.
[1] - An alternative is to set the command to sleep 99999 or something like that, don't map a route, and set the health check type to process. The app should then start successfully. You'll still stop it, but this just avoids an unseemly error.
[2] - If you've already set a command and want to back that out, remove it from your manifest.yml and run cf push -c null, or simply cf delete your app and cf push it again. Otherwise, the command will be retained in Cloud Controller, which isn't what you'd want.

Allow user other than root to restart supervisorctl process?

I have supervisord run a program as user stavros, and I would like to give the same user permission to restart it using supervisorctl. Unfortunately, I can only do it with sudo, otherwise I get a permission denied error in socket.py. How can I give myself permission to restart supervisord processes?
Personally, I think it is a bad idea to run supervisord as root, but if you want to do this, while allowing a full restart by other users, here is how I would do it.
1/ Create a supervisor group on your system which will have restart rights on supervisord
2/ Put the relevant users in group supervisor
3/ In the supervisord configuration, use the following lines in the [unix_http_server] section:
chmod=0770 ; socket file mode (default 0700)
chown=root:supervisor ; socket file uid:gid owner
It will guarantee that the admin socket is accessible from the selected users.
4/ Add supervisord in the init mechanism of your system in respawn mode (init, systemd, upstart, etc ...). It depends on your system. Respawn mode means the process will be automatically relaunched if it crashes or stops.
5/ From one of the selected users, you should be able to use supervisorctl to run commands, including a complete shutdown which will trigger a full restart of supervisord.
Maybe you should try restarting your superviord process using user stavros.

Celeryd time constraint error

While running the status command I get the following error:-
Am using rabbitmq as the messaging broker
I am following this blog
sudo /etc/init.d/celeryd status
Error: No nodes replied within time constraint
How can I Debug this error?
I have also checked this question. The answer there did not help.
django/celery - celery status: Error: No nodes replied within time constraint
Edit:-
After checking the logs of celery beat I found the following error
celerybeat raised exception <class 'gdbm.error'>: error(13, 'Permission denied')
Perhaps this is caused by celery not having write permissions for the celerybeat-schedule file. The docs you linked to show celery configured to use /var/run/celerybeat-schedule as the celery beat schedule file.
Does your process have write permissions to that file? If that directory is owned by root (as it should be) and your process is running as anything other than the root user, that could cause the permission denied errors.
Check that your permissions are correct and then try deleting that file then restarting everything.
Use the following command to find the problem :
C_FAKEFORK=1 sh -x /etc/init.d/celeryd start
This usually happens because there are problems in your source project(permission issues, syntax error etc.)
As mentioned in celery docs:-
If the worker starts with “OK” but exits almost immediately afterwards
and there is nothing in the log file, then there is probably an error
but as the daemons standard outputs are already closed you’ll not be
able to see them anywhere. For this situation you can use the
C_FAKEFORK environment variable to skip the daemonization step
Good Luck
Source: Celery Docs
I'm having the same problem.
Restarting rabbitmq fixed it:
sudo systemctl restart rabbitmq-server
and the strange thing is that I needed to wait at least 100 seconds.
For me, I think there is a disk problem.

Django Apache - Run script as Root

My django project calls a python file at a scheduled time using "at" scheduler. This is executed within my models.py
command = 'echo "python /path/to/script.py params" | /usr/bin/at -t [time] &> path/to/at.log'
status = os.system(command)
Where [time] is schedule time.
It works perfectly when I run it within Django Dev server (I usually run as root but it also works with other users as well)
But when I deployed my application on Apache using mod_wsgi, it doesn't work. at logs shows that the job was schedule but it doesn't execute it.
I tried everything from changing the ownership to www-data, permissions, made it into executable to all users, to setuid to root (Huge Security Issue)
The last thing I want to do is run apache as root user.
Use cron or celery for scheduled tasks. If you need to run something as root, it'd make sense to re-write your script as a simple daemon and run that as root, you can pass commands to it pretty easily with zeromq.

Categories