6

I am having difficulty running Django on my Ubuntu server. I am able to run Django but I don't know how to run it as a service.

Distributor ID:    Ubuntu
Description:       Ubuntu 10.10
Release:           10.10
Codename:          maverick

Here is what I am doing:

  1. I log onto my Ubuntu server
  2. Start my Django process: sudo ./manage.py runserver 0.0.0.0:80 &
  3. Test: Traffic passes and the app displays the right page.
  4. Now I close my terminal window and it all stops. I think I need to run it as a service somehow, but I can't figure out how to do that.

How do I keep my Django process running on port 80 even when I'm not logged in?

Also, I get that I should be linking it through Apache, but I'm not ready for that yet.

Nick T
  • 25,754
  • 12
  • 83
  • 121
codingJoe
  • 4,713
  • 9
  • 47
  • 61

5 Answers5

14

Don't use manage.py runserver to run your server on port 80. Not even for development. If you need that for your development environment, it's still better to redirect traffic from 8000 to 80 through iptables than running your django application as root.

In django documentation (or in other answers to this post) you can find out how to run it with a real webserver.

If, for any other reason you need a process to keep running in background after you close your terminal, you can't just run the process with & because it will be run in background but keep your session's session id, and will be closed when the session leader (your terminal) is terminated.

You can circunvent this behaviour by running the process through the setsid utility. See your manpage for setsid for more details.

Miguel Ventura
  • 10,344
  • 2
  • 31
  • 41
  • 2
    Even for development? If you can't trust your own application on your own machine, you have much bigger issues... – Cerin Oct 30 '13 at 16:50
  • @Cerin it's just generally a bad idea, and it's easier to avoid than to think of all the details, especially for dev where things are expected to break. Say you run the dev server on your machine as root on port 80. You just saved some code that doesn't work yet so suddenly the werkzeug debugger pops out. If for some reason your port 80 is accessible to the internet, you just accidentally opened a root shell in your machine to the world. That, and the fact that I don't trust especially my own code :-) – Miguel Ventura Oct 31 '13 at 16:37
  • I respectfully disagree. Yes, this should be avoided if feasible, but there are times when this could come in useful. I stumbled across this post because I needed to do exactly this, because I needed to test some external Javascript widgets that were triggered on my production domain and port, so testing using on localhost:8000 wasn't an option. And just because you're using port 80 doesn't mean it has to be externally accessible. Giving blanket advice like "never do X" that ignores the details of the user's problem is rarely helpful. – Cerin Oct 31 '13 at 21:30
  • Also what if it's in a VM or a container? – Chris Martin Sep 17 '15 at 05:22
  • 2
    The problem isn't the *run in port 80* but rather the *run code as root*. However you don't need one to have the other. You can either redirect port 80 to some other (>1024) port or give the process just CAP_NET_BIND_SERVICE instead of whole root privileges. See http://stackoverflow.com/a/414258/19401 for how to do that. – Miguel Ventura Sep 20 '15 at 12:59
10

Anyway, if after reading other comments, you still want to use the process with manage.py, just add "nohup" before your command line:

sudo nohup /home/ubuntu/django_projects/myproject/manage.py runserver 0.0.0.0:80 &
fylb
  • 679
  • 4
  • 10
4

For this kind of job, since you're on Ubuntu, you should use the awesome Ubuntu upstart.

Just specify a file, e.g. django-fcgi, in case you're going to deploy Django with FastCGI:

/etc/init/django-fcgi.conf

and put the required upstart syntax instructions.

Then you can you would be able to start and stop your runserver command simply with:

start runserver

and

stop runserver

Examples of managing the deployment of Django processes with Upstart: here and here. I found those two links helpful when setting up this deployment structure myself.

Community
  • 1
  • 1
Joseph Victor Zammit
  • 14,760
  • 10
  • 76
  • 102
  • When i upstart that I get this message: ubuntu@ip-10-202-94-157:/etc/init$ start django start: Rejected send message, 1 matched rules; type="method_call", sender=":1.22" (uid=1000 pid=6758 comm="start) interface="com.ubuntu.Upstart0_6.Job" member="Start" error name="(unset)" requested_reply=0 destination="com.ubuntu.Upstart" (uid=0 pid=1 comm="/sbin/init")) What does that mean? – codingJoe May 04 '12 at 18:42
  • @codingJoe Ehh not a clue :/ also read the other answers. I hadn't figured you were trying to run stuff locally on port 80! – Joseph Victor Zammit May 04 '12 at 18:45
  • Update: nowadays I use `supervisor` to manage processes as uWSGI or gunicorn that run Django: http://supervisord.org/index.html – Joseph Victor Zammit Apr 28 '20 at 19:50
1

The problem is that & runs a program in the background but does not separate it from the spawning process. However, an additional issue is that you are running the development server, which is only for testing purposes and should not be used for a production environment.

Use gunicorn or apache with mod_wsgi. Documentation for django and these projects should make it explicit how to serve it properly.

If you just want a really quick-and-dirty way to run your django dev server on port 80 and leave it there -- which is not something I recommend -- you could potentially run it in a screen. screen will create a terminal that will not close even if you close your connection. You can even run it in the foreground of a screen terminal and disconnect, leaving it to run until reboot.

Andrew Gorcester
  • 19,595
  • 7
  • 57
  • 73
0

If you are using virtualenv,the sudo command will execute the manage.py runserver command outside of the virtual enviorment context, and you'll get all kind of errors.

To fix that, I did the following:

while working on the virtual env type:

which python

outputs: /home/oleg/.virtualenvs/openmuni/bin/python

then type:

sudo !!

outputs: /usr/bin/python

Then all what's left to do is create a symbolic link between the global python and the python at the virtualenv that you currently use, and would like to run on 0.0.0.0:80

first move the global python folder to a backup location:

mv /usr/bin/python /usr/bin/python.old

/usr/bin/python

that should do it:

ln -s /usr/bin/python /home/oleg/.virtualenvs/openmuni/bin/python

that's it! now you can run sudo python manage.py runserver 0.0.0.0:80 in virtaulenv context!

Keep in mind that if you are using postgres DB on your developement local setup, you'll probably need a root role.

Credit to @ydaniv

Oleg Belousov
  • 9,981
  • 14
  • 72
  • 127