Docker project for Python3, Django and Apache2 setup

I was working on a Django project and it took me some time to make Django work with Apache2. So I thought I would create a Docker project for this setup. You can find the project at https://github.com/ramkulkarni1/django-apache2-docker. It sets up Python3, Django, Apache2 and a sample Django site too.

All configurations for making Django work with Apache2 are created when you create a Docker container using this project. Simply run following command from the project folder.

$ docker-compose up

(See my post Docker Notes on information about setting up Docker and docker commands). One the container is up, browse to http://localhost:8005.

Here is a quick summary of what Dockerfile does –

  • Installs apache2 and utils on the base image of Ubuntu
  • Installs python3 and mod-wsgi. A simlink is created for python3 as python so that you could run python scripts just by typing python at the command line, instead of python3
  • Installs pip for Python3 and creates pip simlink for pip3
  • Installs django and ptvsd (remote debugging server for Visual Studio Code). I will explain how to remote debug Djajgo application using Visual Studio Code in my next post.
  • Copies demo_site.config from the project folder as/etc/apache2/sites-available/000-default.conf in the container. The configuration file has setting for apache2 virtual host to run Django site. It is configured to run on port 80, which is exposed as 8005 outside the container (see docker-compose.yml). Note following mod-wsgi settings in demo_site.config (see docs for more details)
    • WSGIPythonPath /var/www/html/django_demo_app/demo_site.
      This tell mod-wsgi to looks for python files in this folder. /var/www/html is the document root for apache2. We are going to map folder (mount volume) <project_folder>/www to /var/www/html in the container.<project_folder>/www contains folder django_demo_app. This is a the main project folder. Within this project there is the demo Django site called demo_site. So the folder structure on the host machine is as follows<project_folder>
      – www
      – django_demo_app
      – demo_site
      – demo_site.conf
      – docker-compose.yml
      – Dockerfile
    • DocumentRoot /var/www/html/django_demo_app
      Sets document root for this virtual host.
    • Alias /static “/var/www/html/django_demo_app/demo_site/static”
      Sets alias for accessing static files. Django docs recommends serving static files from a separate server and suggests executing

      $ python manage.py collectstatic
      

      to collect all static files (like static html, css, javascript and image files). However I have kept this simple and using the same server (apache) to serve static files. I am also using the same folder for serving static files by apache and Django dev server.  So there is not need to run collectstatic command above in this set-up.

      See docs for handling static files in django.

    • WSGIScriptAlias / /var/www/html/django_demo_app/demo_site/demo_site/wsgi.py
      Sets path to wsgi.py for the site.

docker-compose-yml is very simple – it maps ports and mounts www folder as volume /var/www/html in the container.

If you want to create your own Django site, say my_new_site, then follow these steps –

  1. Open a bash shell in the container
    $ docker exec -it django-apache2
    
  2. Go to folder /var/www/html/django_demo_app folder and execute command
    $ django-admin startproject my_new_site
    

    Replace my_new_site with the name of site you want to create.

  3. Edit demo_site.conf and change references to demo_site withmy_new_site (or name of the site you entered in the above command).
    • WSGIPythonPath /var/www/html/django_demo_app/my_new_site
    • Alias /static “/var/www/html/django_demo_app/my_new_site/static”
    • WSGIScriptAlias / /var/www/html/django_demo_app/my_new_site/my_new_site/wsgi.pyMake sure you create static folder under /var/www/html/my_new_site to store your site specific static filesSet STATICFILES_DIRS variable in my_new_site/my_new_site/settings.py file
      STATICFILES_DIRS = [
          os.path.abspath(os.path.join(BASE_DIR, "static")),
      ]
      

      If you are creating a new app (for example by running command – python manage.py startapp app1) then don’t forget to add the name of the app to INSTALLED_APPS array in settings.py. Also configure paths for the new app.

  4. Stop docker-compose (CTRL+C) and run
    $ docker-compose build
    

    to rebuild the image. This is very important. Make sure you rebuild the image after you make any changes to the Docker configuration. Only restarting container is not enough in such cases.

  5. Then start the container
    $ docker-compose up
    

I will write about debugging Django application running in Docker container in my next post.

-Ram Kulkarni

PS: My video of how to setup Django and Apache in Docker

6 Replies to “Docker project for Python3, Django and Apache2 setup”

  1. Pingback: click here

Leave a Reply

Social