Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An Intro to Docker for Djangonauts

An Intro to Docker for Djangonauts

If you’ve never used it before, Docker can be a little overwhelming. There is new vocabulary to learn, new commands to memorize, and new files to add to each project. Most resources fall into one of two camps: they teach you the bare bones of Docker but still leave you with too many questions to comfortably try it on your own, or they throw you into the deep end by assuming you’re more familiar with Docker than you are.

In this talk, you will find that middle ground: a talk that doesn’t assume you’re familiar with Docker and so keeps everything simple, but leaves you with enough information that you can get started as soon as you leave the room. Together, we will step through the parts of a Dockerfile and learn what they do. Then, I’ll introduce you to Docker Compose and explain why using it to run multiple containers is helpful. Finally, you will learn to run commands and execute scripts from the command line using Docker, how to enter a container and why you might need to, and what to do before you go home for the day.

Lacey Williams Henschel

October 15, 2018
Tweet

More Decks by Lacey Williams Henschel

Other Decks in Technology

Transcript

  1. Docker ✓ Separate dependencies ✓ Shares your OS ✓ All

    team members on the same page ✓ No Python installs needed! @laceynwilliams | @revsys
  2. The image is the person you want to turn into

    @laceynwilliams | Source: Harry Po5er Wiki
  3. image executable that contains all the packages for your project

    container run6me instance of image @laceynwilliams | @revsys
  4. The Dockerfile is the hair of the person you want

    to turn into @laceynwilliams | Source: Beth Purchases
  5. image executable that contains all the packages for your project

    container run6me instance of image Dockerfile file that defines your image @laceynwilliams | @revsys
  6. Use hair to tell the po-on how to change into

    someone else. Drink it to transform your body. Use Dockerfile to tell Docker how to build your image. Run project in a container. @laceynwilliams | @revsys
  7. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  8. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  9. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  10. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  11. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  12. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  13. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  14. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  15. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] @laceynwilliams | @revsys
  16. $ docker build . Sending build context to Docker daemon

    246.8kB Step 1/8 : FROM python:3.6 ---> c1e459c00dc3 Step 2/8 : ENV PYTHONUNBUFFERED 1 ---> 4a0a06578949 Step 3/8 : COPY ./requirements.txt /code/requirements.txt ---> 5295a62d7c36 Step 4/8 : RUN pip install -r /code/requirements.txt ---> Running in 18b4fa19c07e Collecting Django (from -r /code/requirements.txt (line 1)) Downloading https://.../Django-2.0.5-py3-none-any.whl (7.1MB) Installing collected packages: Django Successfully installed Django-2.0.5 Removing intermediate container 18b4fa19c07e ---> 371f3b29d141 Step 5/8 : COPY . /code/ ---> 5443237e1306 Step 6/8 : WORKDIR /code/ Removing intermediate container cbafa8b61bd9 ---> 5a50cee784e7 Step 7/8 : EXPOSE 8000 ---> Running in a0b9b3f4da6f Removing intermediate container a0b9b3f4da6f ---> 80fbc70dc709 Step 8/8 : CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] ---> Running in 351cfbc91fa2 Removing intermediate container 351cfbc91fa2 Successfully built 80fbc70dc709 @laceynwilliams | @revsys
  17. $ docker build -t hogwarts . Successfully built 4521a153fa19 Successfully

    tagged hogwarts:latest @laceynwilliams | @revsys
  18. Step 1/8 : FROM python:3.6 ... Step 2/8 : ENV

    PYTHONUNBUFFERED 1 ... @laceynwilliams | @revsys
  19. • First (me through: Docker builds each layer by hand

    • Second (me through: Docker uses a cache if nothing has changed • Docker rebuilds changed layers and all layers a;er them @laceynwilliams | @revsys
  20. Step 1/8 : FROM python:3.6 ---> c1e459c00dc3 Step 2/8 :

    ENV PYTHONUNBUFFERED 1 ---> Using cache ---> 4a0a06578949 Step 3/8 : COPY ./requirements.txt /code/requirements.txt ---> 630e64f66d85 Step 4/8 : RUN pip install -r /code/requirements.txt ---> Running in b9ef1258f655 Collecting Django (from -r /code/requirements.txt (line 1)) Downloading https://.../Django-2.0.5-py3-none-any.whl (7.1MB) ... Step 8/8 : CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings" ] ---> Running in 351cfbc91fa2 Removing intermediate container 351cfbc91fa2 Successfully built a5392bb186c4 Successfully tagged hogwarts:latest @laceynwilliams | @revsys
  21. Imago Revelio $ docker images REPOSITORY TAG IMAGE ID CREATED

    SIZE hogwarts latest 4521a153fa19 42 hours ago 734MB @laceynwilliams ✨ spell to reveal images
  22. Continens Revelio $ docker container ls CONTAINER ID IMAGE COMMAND

    CREATED STATUS PORTS NAMES @laceynwilliams ✨ spell to reveal containers
  23. Continens Revelio $ docker container ls CONTAINER ID IMAGE COMMAND

    CREATED 2021341641d7 hogwarts "python ./manage.py …"About a minute ago STATUS PORTS NAMES Up About a minute 0.0.0.0:8000->8000/tcp fervent_allen @laceynwilliams ✨ spell to reveal containers
  24. root@2021341641d7:/code# cd .. root@2021341641d7:/# ls bin code etc lib media

    opt root sbin sys usr boot dev home lib64 mnt proc run srv tmp var @laceynwilliams | @revsys
  25. $ docker container ls CONTAINER ID IMAGE COMMAND 2021341641d7 hogwarts

    "python ./manage.py …" @laceynwilliams | @revsys
  26. Docker Compose ✓ Free ✓ Included with Mac, extra download

    otherwise ✓ Run more than one container at once ✓ Relate containers to each other @laceynwilliams | @revsys
  27. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  28. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  29. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  30. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  31. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  32. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  33. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  34. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  35. # docker-compose.yml version: '3' services: db: image: postgres web: build:

    . command: bash -c "python /code/manage.py migrate --noinput && python /code/manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db @laceynwilliams | @revsys
  36. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 CMD [ "python", "./manage.py", ... ] @laceynwilliams | @revsys
  37. FROM python:3.6 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 COPY ./requirements.txt

    /code/requirements.txt RUN pip install -r /code/requirements.txt COPY . /code/ WORKDIR /code/ EXPOSE 8000 ! @laceynwilliams | @revsys
  38. $ docker-compose up Creating network "hogwarts_default" with the default driver

    Creating hogwarts_db_1 ... done Creating hogwarts_web_1 ... done Attaching to hogwarts_db_1, hogwarts_web_1 db_1 | The files belonging to this database system will be owned by user "postgres". db_1 | This user must also own the server process. web_1 | Operations to perform: web_1 | Apply all migrations: admin, auth, blog, contenttypes, sessions web_1 | Running migrations: web_1 | No migrations to apply. db_1 | LOG: database system is ready to accept connections db_1 | LOG: autovacuum launcher started web_1 | Performing system checks... web_1 | web_1 | System check identified no issues (0 silenced). web_1 | May 03, 2018 - 12:12:57 web_1 | Django version 2.0.5, using settings 'mysite.settings' web_1 | Starting development server at http://0.0.0.0:8000/ web_1 | Quit the server with CONTROL-C. @laceynwilliams | @revsys
  39. Continens Revelio $ docker container ls CONTAINER ID IMAGE ...

    NAMES f78a4fac4772 hogwarts_web ... hogwarts_web_1 1fdf3604ce5c postgres:9.6.8 ... hogwarts_db_1 @laceynwilliams ✨ spell to reveal containers
  40. apparate into the shell $ docker-compose run --rm web ./manage.py

    shell Starting hogwarts_db_1 ... done ... In [1]: from spells.models import Spell In [2]: Spell.objects.all() Out[2]: <QuerySet ['Accio', 'Alohomora', 'Expelliarmus']> @laceynwilliams | @revsys
  41. stop and start at will $ docker-compose stop web Stopping

    hogwarts_web_1 ... done $ docker-compose start web Starting web ... done @laceynwilliams | @revsys
  42. Nox $ docker-compose down Removing hogwarts_web_1 ... done Removing hogwarts_db_1

    ... done Removing network hogwarts_default @laceynwilliams ✨ spell to darken containers
  43. It is the unknown we fear when we look upon

    Docker, nothing more. — Albus Dumbledore, probably @laceynwilliams | S/ll from Harry Po5er and the Order of the Phoenix
  44. Hogwarts Library · An Intro to Docker for Djangonauts ·

    Docker: Useful Command Line Stuff · Docker tutorial · Docker Compose tutorial, Compose and Django tutorial · Best PracAces for WriAng Dockerfiles · 10 Things to Avoid in Docker Containers, Rafael Benevides · Video: 5 Things About Docker, Jessie Frazelle · Docker CheatSheet · Dockerizing Django, UWISGI, and Postgres the Serious Way, Oliver Eidel · How to use Django, PostgreSQL, and Docker, William S. Vincent · Managing SensiAve Data with Docker Secrets @laceynwilliams | @revsys