Workshop: Python en Django in Docker

A manual (in Dutch) written for the local Docker Grunn Meetup, to become familiar with Docker & docker-compose, by setting up a small Python / Django app.

Docker Grunn workshop, 26 mei 2016

Doel

Het opzetten van een in Python geschreven Linux-dashboard, served through Django, in een Docker-container draaien.

Vereisten

  • een computer (Doh!) met Linux / OS X / Windows
  • daarop een werkende Docker-setup (>= v1.10.3)
    • Docker / boot2docker / Docker for Mac
  • docker-compose (>= v1.6)
  • git-client
  • een editor bijv. Vim (of als je onder de 18 bent: nano)

Stap voor stap

  • Maak met Git een clone van de pyDash-repository (ga niet voor de Django App!) en ga de directory in:
$ git clone git@github.com:k3oni/pydash.git
$ cd pydash
  • We kauwen niet alles helemaal voor, dus dit mag je zelf uitzoeken. Maar we houden je bij de hand.
    Ga naar Quickstart: Docker Compose and Django en gebruik de daar gevonden informatie om zowel een Dockerfile als een docker-compose.yml bestand aan te maken.
    [BELANGRIJK!] Skip het gebruik van genoemde “db” / “postgres”!
    Verwijder de regels die ze noemen - het is niet nodig, want de gebruikte DB straks is een sqlite3-bestand.
$ vi Dockerfile
$ vi docker-compose.yml
  • Start de container. Als het goed is wordt deze door de build-instructie automatisch aangemaakt op basis van een python:2.7-image:

$ docker-compose up -d

Building web
Step 1 : FROM python:2.7
2.7: Pulling from library/python
8b87079b7a06: Pull complete
a3ed95caeb02: Pull complete
1bb8eaf3d643: Pull complete
3e04171ce2e5: Pull complete
0b73d3fea769: Pull complete
167a085f33b1: Pull complete
a498799bc49b: Pull complete
c2e64a7ec940: Pull complete
Digest: sha256:a1cf98a212d2001617f7c6019fb2dce0ec429955db175ead2a8523d4d0b1ee99
Status: Downloaded newer image for python:2.7
 ---> 11a8b7c7f0ca
Step 2 : ENV PYTHONUNBUFFERED 1
 ---> Running in 6c157123d096
 ---> e5a947ed7ca8
Removing intermediate container 6c157123d096
Step 3 : RUN mkdir /code
 ---> Running in 20cfc6e452fd
 ---> a5e1288a5ec7
Removing intermediate container 20cfc6e452fd
Step 4 : WORKDIR /code
 ---> Running in dee0f4ff6dd1
 ---> 88750e61774a
Removing intermediate container dee0f4ff6dd1
Step 5 : ADD requirements.txt /code/
 ---> 278135f0e060
Removing intermediate container daac7f16f7b6
Step 6 : RUN pip install -r requirements.txt
 ---> Running in 8372bedb569d
Collecting django==1.6.8 (from -r requirements.txt (line 1))
  Downloading Django-1.6.8-py2.py3-none-any.whl (6.7MB)
Installing collected packages: django
Successfully installed django-1.6.8
 ---> 47a0e176db2f
Removing intermediate container 8372bedb569d
Step 7 : ADD . /code/
 ---> 8f2dad0477e0
Removing intermediate container ee29ded2a231
Successfully built 8f2dad0477e0
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating pydash_web_1
  • Voeg login credentials toe aan de database:

$ docker-compose run web python manage.py syncdb

Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'):
Email address: root@localhost
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

Hiermee wordt de database in bestand db.sqlite3 gevuld.

Errors

Deze fout

DataTables warning (table id = 'get_ips'): Requested unknown parameter '1' from the data source for row 0

wordt veroorzaakt door òf Docker òf Debian Jessie. Er is iets met interface namen de laatste tijd… laten we een kijkje nemen!

$ docker exec -ti pydash_web_1 bash

In de container zien we:

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:2/64 scope link
       valid_lft forever preferred_lft forever

Oplossing: in bestand main/views.py regel 77 vervangen door deze:

eth = os.popen("ip addr | grep LOWER_UP | awk -F'@' '{print $1}' | awk '{print $2}'")

Et voila!

PyDash

Stoppen en verwijderen

$ docker-compose stop
Stopping pydash_web_1 ... done
$ docker-compose rm -f
WARNING: Not including one-off containers created by `docker-compose run`.
To include them, use `docker-compose rm --all`.
This will be the default behavior in the next version of Compose.

Going to remove pydash_web_1
Removing pydash_web_1 ... done

$ docker-compose rm --all
Going to remove pydash_web_run_1
Are you sure? [yN] y
Removing pydash_web_run_1 ... done

Appendix

Dit is zijn de werkende Dockerfile en docker-compose.yml:

Dockerfile:

FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

docker-compose.yml:

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

Henk

Recovering sysadmin

Groningen, the Netherlands