In this tutorial we will implement “Hello, World” with Django first locally and then with Docker. Let’s get to it!

The first step is to install Django within a local virtual environment. There are multiple ways to do this but I prefer Pipenv. If you need help installing Pipenv or more instructions on this first step, see more details here.

Make sure you are in a new directory for this code. If you are on a Mac, an easy-to-find location is the Desktop. Open a new command line prompt (see here if the command line is new to you) we can navigate to it and create a hello directory for this code.

$ cd ~/Desktop
$ mkdir hello && cd hello

Next install Django with Pipenv, enter a virtual environment “shell”, create a project called hello_project, migrate our initial database, and start the local web server.

$ pipenv install django==2.1
$ pipenv shell
(hello) $ django-admin startproject hello_project .
(hello) $ python manage.py migrate
(hello) $ python manage.py runserver

Assuming everything worked correctly, you should now be able to navigate to http://127.0.0.1:8000/ and see the Django Welcome page in your web browser.

Django Welcome Page

Hello, World Message

Now we can create a basic “Hello, World” application. More thorough instructions can be found here. In this tutorial I’m going to just give you the commands.

We need to create a pages app. From the command line, quit the server with Control+c and use the startapp command.

(hello) $ python manage.py startapp pages

Add the app to our INSTALLED_APPS config within the hello_project/settings.py file.

# hello_project/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'pages.apps.PagesConfig', # new
]

We specify that the pages app should not have any URL prefix so we use the empty string '' along with importing include to add the app.

# hello_project/urls.py
from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('pages.urls')), # new
]

Now update our pages/views.py file to simply say “Hello, World!”.

# pages/views.py
from django.http import HttpResponse


def homePageView(request):
    return HttpResponse('Hello, World!')

Create a pages/urls.py file for our app-specific URL path.

(hello) $ touch pages/urls.py

And fill it with the following code.

# pages/urls.py
from django.urls import path

from .views import homePageView

urlpatterns = [
    path('', homePageView, name='home')
]

Ok, we’re done! Start the local server up again.

(hello) $ python manage.py runserver

Django Hello World

We can exit the virtual environment now since we no longer need it. Type exit which will remove the parentheses from the command line prompt.

(hello) $ exit
$

Perfect. We’re ready to switch over to Docker now.

Docker

Now install the Docker desktop app.

The initial download of Docker might take some time to download. It’s a big file. Feel free to stretch your legs at this point!

Docker Compose is an additional tool that is automatically included with Mac and Windows downloads of Docker. However if you are on Linux, you will need to add it manually. You can do this by running the command sudo pip install docker-compose after your Docker installation is complete.

To confirm Docker installed correctly we can run our first command docker run hello-world. This will download an official image and then run the container.

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image whi
ch runs the executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client,
which sent it to your terminal.

To try something more ambitious, you can run an Ubuntu container
with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Ok, lovely. We can now move on to creating our own Dockerfile for a custom image and a docker-compose.yml file for running the container.

$ touch Dockerfile
$ touch docker-compose.yml

The code for our Dockerfile is like so:

# Dockerfile

# Pull base image
FROM python:3.7-slim

# Set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /code

# Install dependencies
RUN pip install pipenv
COPY ./Pipfile /code/Pipfile
RUN pipenv install --system --skip-lock

# Copy project
COPY . /code/

And our docker-compose.yml file looks like this:

# docker-compose.yml
version: '3.7'

services:
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - 8000:8000

Now to put it all together. We can both build our image and run the container with one command:

$ docker-compose up --build

Head back to your web browser at http://127.0.0.1:8000/ and we can see the Django “Hello, World” homepage now running purely within Docker!

Django Hello World

Next Steps

This was intentionally a very bare bones introduction to using Django and Docker. For more on Django, check out Django for Beginners. For Docker I’ve written a separate Beginner’s Guide to Docker and a tutorial on Django, PostgreSQL, and Docker.

Finally, if you’re looking to learn more about Docker itself–which is a very deep subject–a fantastic resource is the Dive into Docker video course.