dockerize gunicorn, nginx, django in single container - django

i am trying to dockerize my django project using gunicorn and nginx. The setup works on my machine, but i can't get nginx to work with the unix socket inside the image.
i followed this tutorial. Since i can't use systemctl inside the container, i tried to run gunicorn as a CMD. To start Nginx, i tried restarting the container, but then my CMD is not restarted (i think?) and the container shuts down.
How should i properly reload the nginx service inside the docker container using my dockerfile?

You can use systemctl inside a container. Either configuring a systemd daemon inside the container, or using the docker-systemctl-replacement to do without. I am using that regularly to run multiple service inside one container.

Related

Running Django Python Server in AWS

I have a django running in AWS Ubuntu machine. Through SSH, I start the server at 8000 port. But when i close the ssh window, server stops and I can't access it through URL. What I want is to run the server all the time once it is started. How to go about it? Thanks.
You can use either Apache or Nginx to deploy Django App. If you are planning to Use Nginx, first install Nginx in the server and add Django configurations to Nginx configuration. You can follow this as a good guide.
You can do it the hacky way: create a bash script that executes the app (just running the same command you execute to run it), and run the bash script with nohup, which detaches the process from the shell and will allow the application to continue running when you close your session:
nohup ./my_bash_script.sh &
If you want to do it properly, create a service file and execute the app as a service. You can create a simple service file like this:
[Unit]
Description=My Django app
After=network.target
[Service]
PIDFile=/run/DjangoApp/pid
User=<your user>
Group=<your group>
WorkingDirectory=<working directory of your Django app>
ExecStart=<path to your bash script>
PrivateTmp=True
[Install]
WantedBy=multi-user.target
Save the file under /etc/systemd/system/djangoService.service. You enable the service with this command:
sudo systemctl enable djangoService
And run it with this command:
sudo service start djangoService
That will keep the service running. Bear in mind, though, that to service a proper Django app you may want to use Gunicorn/wsgi to serve the responses, using Nginx to reverse proxy the requests.
In development mode, Django has a development server, which is sufficient for testing purposes. Once you complete a web application and it's ready for production, the process of setting up the application on a server might be overwhelming for some, especially if you're doing it for the first time. This article provides a step-by-step guide on how to deploy Django-based web applications using mod_wsgi.
You can follow this article for setting mod_wsgi with Apache server. enter link description here
If the one which you are setting up for development only then you need to run the server in daemon mode.
on Ubuntu
run:>./manage.py runserver 0.0.0.0:8000 > /dev/null 2>&1 &
>exit
Django runserver permanent
Hope this helps, it is the best way to create the screen so we can monitor what is happening and take the control back.

running nginx/postgres with supervisord - required?

In all standard django productions setup templates I've seen, gunicorn is run with supervisor, whereas nginx/postgres are not configured under supervisor.
Any reason? Is this required for a production system? If not, why not?
In this architecture, Gunicorn works as the application server which runs our Django code. Supervisor is just a process management utility which restarts the Gunicorn server if it crashes. The Gunicorn server may crash due to our bad code, but nginx and postgres remain intact. So in the basic config we only look after the gunicorn process through supervisor. Though we could do the same for nginx and postgres too.
You need supervisor for gunicorn because it's an simply server without any tools to restart it, run it at system startup, stop it at system shutdown or reload when it crashes.
Postgresql and nginx can take care of themselves in that aspect, so there is no need for them to be running under supervisor.
Actually, you can just use init.d, upstart or system.d to start, stop and restart gunicorn, supervisor is just easier way to handle such small servers like gunicorn.
Consider also that it is common to run multiple django apps on one system, and that requires multiple separated instances of gunicorn. Supervisor will handle them better than init, upstart or system.d
There is also uWSGI server that won't need supervisor, because it has built-in features to handle multiple instances, starting, stopping and also auto-reloading on code change. Look at uWSGI emperor system.

Shall I restart both nginx and gunicorn when production is updated?

What is the best practice when I have an update for my Django app pushed in my production? Shall I restart both gunicorn and nginx services, with
sudo service gunicorn restart
sudo service nginx restart
or restarting only gunicorn is enough? Finally does the order of the restarts makes any difference if I have to do both the restarts? Thanks!
It entirely depends on how you've configured your box.
To keep downtime to an absolute minimum, I actually load my new release into a different directory on the box while the old release is still running. I create a new virtual environment based on my new release's requirements.txt. Then I start a second instance of gunicorn with the new release running in it (done via supervisord with entries in supervisord.conf), and leave the old instance still running.
I then update my nginx vhost file to point the server to the new release's gunicorn socket, and finally reload nginx. I do a quick check that the new site is up and functioning, and then I stop the old gunicorn instance. If for some reason it's not responding, I switch my nginx config back to point to the old one again, and then go figure out what's wrong.
I do all this using an Ansible script, but here's a great article with some Fabric scripts to do something similar: https://medium.com/#healthchecks/deploying-a-django-app-with-no-downtime-f4e02738ab06
If, on the other hand, you just update your code in-place, then there should be no changes needed to your nginx config, so you shouldn't need to reload it. Just reload gunicorn and you're good to go.

dockerize django apache developer environment

I tried to dockerize my django/apache web application.
In the big picture the dockerization worked out.
For deployment Annot is running in 3 containers. The apache_annot container holds the apache server and the postgresql database The media_annot container serves as web application media folder. The annot container holds the django python related code.
For development only 2 containers are needed: the apache_annot container and media_annot container. The django and python related code is placed into a directory at the host machine. apache_annot then simply mounts this directory as a data volume under /var/www/annot/.
Here the link to the Docker files:
https://gitlab.com/biotransistor/dock/tree/master
Issue:
Even the dockerized version works, it seems not to be done the real docker way.
Most annoying issue: Every time apache is restarted (which happens a lot in development) the apache_annot container and as such the whole web application stops.
To continuer apache_annot have to be restarted:
docker exec -ti apache_annot /bin/bash
Then postgresql database have to be restarted:
/etc/init.d/postgresql start
And cd into /var/www/annot/ to execute django development specific python code like:
python3 manage.py makemigrations.
It is nearly not possible to do development with this solution.
I can not be the only one who like to use a dockerize django apache developer environment. What do I do wrong?
Is there a way to run apache_annot so that the apache daemon can be rebooted without shouting down the apache_annot docker container?

Deploying Django with Nginx as service

Currently I have a home server (Ubuntu) with nginx running where I use proxy pass in order to pass the requests to django. I am using gevent as my wsgi server.
It all works fine until the server shuts down either because I restart the server for whatever reason or something crashes (electricity). Since nginx is a service, when the server restarts, nginx starts up as well. However my django apps do not. So then I have to manually go to each of my django projects, activate their virtualenvs, and then fire up the gevent process. This is very annoying to say the least.
Is there a standard way of handling all of this automatically?
You need to set up a script for something like Upstart or Supervisor. Personally, I prefer using Supervisor. Here's the script I use to run my gunicorn instances:
[program:gunicorn]
command=/path/to/virtualenv/bin/python manage.py run_gunicorn -c /path/to/gunicorn.conf.py
directory=/path/to/django/project
user=www-data
autostart=true
autorestart=true
redirect_stderr=True
Consider using a process manager to handle this for you. I like supervisor
You tell it how to launch your various processes and then it runs in the background (just like nginx) and will automatically start up on restart and launch your various django backend processes.