Build a Django Container#

Django is a framework for writing web applications in Python. In this lab you’ll complete Parts 1 and 2 of the Writing your first Django app tutorial in a fresh Ubuntu container.

About the Ubuntu Container#

The Ubuntu container is not a stand-alone OS like an Ubuntu server. The container does not run any services and if you start it without a command it quits immediately. It’s purpose is to be the base of a customized app. It’s important that you follow the Django instructions inside a container. Later we’ll translate the instructions into a Dockerfile.

Start the Ubuntu container:

$ docker run -it -p 8000:8000 --name django -v $(pwd)/app:/app  ubuntu:20.04 /bin/bash

The Ubuntu container is very spare. You have to install Python and pip manually.

root@1ae055ea1432:/# apt update 
root@1ae055ea1432:/# apt install python3-pip tzdata

The tutorial expects you to have Django installed. Install it with this command:

root@1ae055ea1432:/# python3 -m pip install django 

Now you’re ready to start the Tutorial

Tips for Working in a Container#

Important

There are key differences between a VM and a container. Read and understand the advice in this section before you begin.

  1. The instructions use the python command, which is not installed in the container. Use python3 instead. You can make an alias so you don’t have to remember:

    alias python=python3
    
  2. The container was run with -p 8000:8000. That connects port 8000 on the host (first number) to port 8000 in the container (second number). Services run on localhost or 127.0.0.1/8 in the container will not be available to the host. Run the Django server on 0.0.0.0:8000 instead of the default 127.0.0.1:8000. This command will run the Django server:

    $ python manage.py runserver 0.0.0.0:8000
    
  3. The container was run with -v $(pwd)/app:/app connecting the /app directory in the container with ./app on the host. You should perform the Django installation steps in the /app directory so that you can easily access the installed files from the host. This will be essential for the project.

  4. You can edit files in the container with vim, but you have to install it first! You can also edit files in the /app directory from outside the container.

Cloud Shell Specific Notes#

Cloud Shell uses a proxy to connect you with running apps. That causes problems in Django. Before you can login to your new Django application you must put this line at the bootom of mysite/settings.py:

CSRF_TRUSTED_ORIGINS = ['https://*.cloudshell.dev']

Writing Your First Django App#

Follow the instructions at this URL:

https://docs.djangoproject.com/en/4.0/intro/tutorial01/

When you’re done you should be able to log in to Django using the administrative interface and see the polls. Your container will not be deployable, however because the changes you made are in the writable layer of the container and on your host directory. To make it deployable you have to translate your work into a Dockerfile.

Starting and Stopping the Container#

The work you’ve done is in the writable layer. Don’t delete the container or you loose your work! When you exit the shell the container will stop. You can see it’s still there with docker ps -a:

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND                  CREATED             STATUS                       PORTS      NAMES
69545ebcd7a2   ubuntu:20.04    "/bin/bash"              About an hour ago   Exited (127) 2 seconds ago              django

If you want to start the container again you have to attach to it:

$ docker start -ia django  

An Entry Point for Django#

An entrypoint is a command that you run in the container by default. For most containers it’s a shell script that does startup tasks. Often, containers have to do some tasks only on the first start (or docker run command). A Django application has to be started a specific way in order to guarantee it will run. Use this shell script as the command in your container. It should be put in the same directory as manage.py:

#! /bin/sh 

# This causes the script to fail on any error that's what you want so 
# Docker sees the failure. 
set -e 

# The migrate command is safe to re-run, but will fail if the Database isn't
# ready. It keeps this container from starting before the database.  
python3 ./manage.py migrate 

# This startup task can only run once. Subsequent runs will fail or cause a 
# problem. Using '|| true' suppresses the error.
python3 ./manage.py createsuperuser --no-input --email $DJANGO_ADMIN_EMAIL --username $DJANGO_ADMIN_USERNAME || true
# Don't forget to also set $DJANGO_SUPERUSER_PASSWORD in the container

# Start the application.
python3 ./manage.py runserver 0.0.0.0:8000

The commands in this entrypoint came straight from the Django tutorial. They’re included here to make it a bit easier to run the container that you need to complete the next milestone.