SlideShare uma empresa Scribd logo
1 de 43
Baixar para ler offline
Copyright 2019 © systemati.co
Docker and Django
Meet For A Tango
Hendrik Frentrup

hendrik@systemati.co

15 July 2019

London, UK
Copyright 2019 © systemati.co
Ways to get in touch
hendrik@systemati.co

@HendrikFrentrup

linkedin.com/in/frentrup/

github.com/hendrikfrentrup

medium.com/@hendrik.frentrup
Copyright 2019 © systemati.co
Links
•GitHub repo for the code

•github.com/hendrikfrentrup/docker-django

•Walkthrough:

•medium.com/devopslinks/tech-edition-how-to-dockerize-a-django-web-
app-elegantly-924c0b83575d

•https://medium.com/@hendrik.frentrup/tech-edition-django-dockerization-
with-bells-and-whistles-and-a-tad-bit-of-cleverness-2b5d1b57e289

•Further reading:

•medium.com/panaseer-labs-engineering-data-science/how-devops-
helped-us-solve-our-big-data-development-problem-263474dfeedb

•Contact details:

•Email: hendrik@systemati.co

•Twitter: @hendrikfrentrup
•LinkedIn: linkedin.com/in/frentrup/
Copyright 2019 © systemati.co
Code!
• This will be a pretty detailed walk-through

• There will be a lot of code in detail

• Sometimes I’ll flick through things pretty quickly

• I’ll make the slides available
Copyright 2019 © systemati.co
The Problem
• Moving code from development environments to staging or
production can break things

• The state of environments drifts and is hard to manage

• For lack of access, developers have no insight into the specifics of
production environments
Copyright 2019 © systemati.co
Why?
• Ease the pain of moving from Dev to Prod

• Step towards being Cloud Native

• Twelve Factor App (https://12factor.net/)

• Infrastructure-as-Code

• Productivity
Copyright 2019 © systemati.co
From here
Application
Database
Local machine
Copyright 2019 © systemati.co
To here
Docker
web
gunicorn
server
db
postgres
Local machine
db-admin
pgadmin
server
nginx
nginx
server
python
manage.py
runserver
*.conf
+ static/
pg-data/
Copyright 2019 © systemati.co
• Move a locally running app into a container

• Setup database, admin and nginx services

• Run migrations

• Logging
• Implement Infrastructure-as-code

• Bring development and production
environments close together

• Increase productivity & working collaboratively
Outline
Copyright 2019 © systemati.co
Simple app running locally
python manage.py runserver
db.sqlite3
Local machine
Copyright 2019 © systemati.co
10 commands to set up
> git init
> git checkout -b develop
> virtualenv env
> source env/bin/activate
> pip install Django>=2.1
> echo 'Django>=2.1' >> requirements.txt
> django-admin startproject my-site
> git add * && git commit -m "..."
> python mysite/manage.py runserver
Copyright 2019 © systemati.co
App running in container
Docker
web
python manage.py runserver
db.sqlite3
Local machine
Copyright 2019 © systemati.co
App inside Docker
> touch Dockerfile
> docker build -t django-docker:0.0.1 .
> docker run -p 8001:8001 docker-django:0.0.1
______Dockerfile____________________________________________________________
FROM python:3.6.7-alpine
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD ./ /code/
RUN pip install -r requirements.txt
CMD ["python", "mysite/manage.py", "runserver", "0.0.0.0:8001"]
Copyright 2019 © systemati.co
Success looks like …
Copyright 2019 © systemati.co
Local storage
Docker
web
python manage.py runserver
db.sqlite3db.sqlite3
Local machine
Copyright 2019 © systemati.co
Moving to docker-compose
> touch docker-compose.yml
> docker-compose up
______docker-compose.yml__________________________________________________
version: "3"
services:
web:
build: .
command: python mysite/manage.py runserver 8001
ports:
- “8001:8001”
volumes:
- ./mysite/:/code
maps ports and container code/db to local filesystem
Copyright 2019 © systemati.co
Database service
Docker
web
python
manage.py
runserver
db
postgres
Local machine
Copyright 2019 © systemati.co
Adding a database service
______docker-compose.yml__________________________________________________
version: "3"
services:
web:
build: .
command: python mysite/manage.py runserver 8001
ports:
- “8001:8001”
volumes:
- ./mysite/:/code
db:
image: postgres
networks:
- backend
networks:
backend:
driver: bridge
Copyright 2019 © systemati.co
Handling env. variables
______settings.py____________________________________________________________
POSTGRES_PASSWORD = os.environ.get('POSTGRES_PASSWORD')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': POSTGRES_PASSWORD,
'HOST': ‘db',
'PORT': '5432',
},
______.env__________________________________________________________________
POSTGRES_PASSWORD=secret
POSTGRES_USER=postgres
DJANGO_SECRET_KEY=secret
> touch .env
> echo 'psycopg2-binary' >> requirements.txt
Copyright 2019 © systemati.co
Credentials in envvars
______docker-compose.yml__________________________________________________
version: "3"
services:
web:
[...]
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
db:
[...]
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
Copyright 2019 © systemati.co
Rebuilding the web image
______Dockerfile____________________________________________________________
FROM python:3.6.7-alpine
ENV PYTHONUNBUFFERED 1
RUN apk update && 
apk add --virtual build-deps gcc python-dev musl-dev && 
apk add postgresql-dev
RUN mkdir /code
WORKDIR /code
ADD ./ /code/
RUN pip install -r requirements.txt
Copyright 2019 © systemati.co
A bit of admin
> docker-compose exec web python mysite/manage.py migrate
> docker-compose exec web python mysite/manage.py createsuperuser
Run that every time we tear down our containers?

Note down the credentials we’ve used?
Copyright 2019 © systemati.co
Data migrations
______0001_initial.py___________________________________________________________
import os
from django.db import migrations
class Migration(migrations.Migration):
dependencies = []
def generate_superuser(apps, schema_editor):
from django.contrib.auth.models import User
DJANGO_SU_NAME = os.environ.get('DJANGO_SU_NAME')
DJANGO_SU_EMAIL = os.environ.get('DJANGO_SU_EMAIL')
DJANGO_SU_PASSWORD = os.environ.get('DJANGO_SU_PASSWORD')
superuser = User.objects.create_superuser(
username=DJANGO_SU_NAME, email=DJANGO_SU_EMAIL,
password=DJANGO_SU_PASSWORD)
superuser.save()
operations = [
migrations.RunPython(generate_superuser),
]
Copyright 2019 © systemati.co
More credentials
______docker-compose.yml__________________________________________________
version: "3"
services:
web:
[...]
environment:
DJANGO_DB_NAME: ${DJANGO_DB_NAME}
DJANGO_SU_NAME: ${DJANGO_SU_NAME}
DJANGO_SU_EMAIL: ${DJANGO_SU_EMAIL}
DJANGO_SU_PASSWORD: ${DJANGO_SU_PASSWORD}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
Copyright 2019 © systemati.co
web, db and admin services
Docker
web
python
manage.py
runserver
db
postgres
Local machine
db-admin
pgadmin server
Copyright 2019 © systemati.co
Adding a DB admin service
______docker-compose.yml__________________________________________________
[...]
db-admin:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
depends_on:
- db
ports:
- "8080:80"
networks:
- backend
[...]
Copyright 2019 © systemati.co
pgadmin in action
Copyright 2019 © systemati.co
Local app for debugging
Docker
web
python
manage.py
runserver
db
postgres
Local machine
db-admin
pgadmin
server
python
manage.py
runserver
Copyright 2019 © systemati.co
Run a local app alongside
______settings.py____________________________________________________________
from decouple import config
SECRET_KEY = config(‘DJANGO_SECRET_KEY')
DEBUG = config('DJANGO_DEBUG', default=False, cast=bool)
WEB_HOST = config('DJANGO_WEB_HOST', default='localhost')
DB_HOST = config('DJANGO_DB_HOST', default='localhost')
DB_NAME = config(‘DJANGO_DB_NAME’)
[...]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': POSTGRES_USER,
'PASSWORD': POSTGRES_PASSWORD,
'HOST': DB_HOST,
'PORT': '5432',
},
Copyright 2019 © systemati.co
Run a local app alongside
______docker-compose.yml_____________________________________
[...]
environment:
DJANGO_DEBUG: "True"
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY}
DJANGO_DB_HOST: “db"
[...]
Copyright 2019 © systemati.co
With nginx
Docker
web
gunicorn
server
db
postgres
Local machine
db-admin
pgadmin
server
nginx
nginx
server
python
manage.py
runserver
Copyright 2019 © systemati.co
Add nginx server
______default.conf_______________________________
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web:8001;
}
}
______settings.py________________________________
[...]
ALLOWED_HOSTS = [WEB_HOST, ‘localhost']
[...]
> echo “gunicorn” >> requirements.txt
Copyright 2019 © systemati.co
Add nginx server
______docker-compose.yml__________________________________________________
[...]
web:
command: gunicorn mysite.wsgi --bind 0.0.0.0:8001
[...]
nginx:
image: nginx:latest
ports:
- 8088:80
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- backend
depends_on:
- web
[...]
Copyright 2019 © systemati.co
Static files & persistent data
Docker
web
gunicorn
server
db
postgres
Local machine
db-admin
pgadmin
server
nginx
nginx
server
python
manage.py
runserver
*.conf
+ static/
pg-data/
Copyright 2019 © systemati.co
Serving static assets
______settings.py_______________________________________
[...]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
> python mysite/manage.py collectstatic
______default.conf_____________________
server {
[...]
location /static {
alias /code/static;
}
}
Copyright 2019 © systemati.co
Serving static assets
______docker-compose.yml__________________________________________________
[...]
nginx:
[...]
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./mysite/static:/code/static
[...]
db:
volumes:
- ./postgres-data:/var/lib/postgresql/data
[...]
Copyright 2019 © systemati.co
Mapped ports
Docker
web
8001
db
5432
Local machine
db-admin
8080
nginx
8088
8000
Copyright 2019 © systemati.co
Splitting YAML files
______docker-compose.override.yml_____________
[...]
volumes:
- ./mysite:/code
environment:
DJANGO_DEBUG: “True"
[...]
______docker-compose.yml_______________
[...]
web:
build: .
command: gunicorn mysite.wsgi
--bind 0.0.0.0:8001
depends_on:
- db
networks:
- backend
[...]
Copyright 2019 © systemati.co
Logs
Copyright 2019 © systemati.co
Logging locally
• To STDOUT!
Copyright 2019 © systemati.co
Logs in shared envs
• Complex topic and no one size fits all

• Log aggregator (SumoLogic, Splunk, ELK etc.)

• A complete ELK stack in one container

• Various logging driver options

• Fluentd

• Gelf
Log aggregatorFluentd
LogStash
ElasticSearch
Kibana
Copyright 2019 © systemati.co
Logging
Local machine
Staging environment
Build
server
Log aggregator
Production
Code
repo
Local machine
push
trigger
tail
deploy
stream
deploy
stream
Copyright 2019 © systemati.co
That’s all!
Thanks

Mais conteúdo relacionado

Mais procurados

SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
Fred Sauer
 
Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKit
Ariya Hidayat
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
Shreedhar Ganapathy
 

Mais procurados (19)

GIT, RVM, FIRST HEROKU APP
GIT, RVM, FIRST HEROKU APPGIT, RVM, FIRST HEROKU APP
GIT, RVM, FIRST HEROKU APP
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
 
Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020
 
Bootiful Development with Spring Boot and React - UberConf 2018
Bootiful Development with Spring Boot and React - UberConf 2018Bootiful Development with Spring Boot and React - UberConf 2018
Bootiful Development with Spring Boot and React - UberConf 2018
 
Bootiful Development with Spring Boot and React - SpringOne 2017
Bootiful Development with Spring Boot and React - SpringOne 2017Bootiful Development with Spring Boot and React - SpringOne 2017
Bootiful Development with Spring Boot and React - SpringOne 2017
 
Front End Development for Back End Java Developers - NYJavaSIG 2019
Front End Development for Back End Java Developers - NYJavaSIG 2019Front End Development for Back End Java Developers - NYJavaSIG 2019
Front End Development for Back End Java Developers - NYJavaSIG 2019
 
A Gentle Introduction to Angular Schematics - Angular SF 2019
A Gentle Introduction to Angular Schematics - Angular SF 2019A Gentle Introduction to Angular Schematics - Angular SF 2019
A Gentle Introduction to Angular Schematics - Angular SF 2019
 
Microservices for the Masses with Spring Boot, JHipster, and OAuth - Utah JUG...
Microservices for the Masses with Spring Boot, JHipster, and OAuth - Utah JUG...Microservices for the Masses with Spring Boot, JHipster, and OAuth - Utah JUG...
Microservices for the Masses with Spring Boot, JHipster, and OAuth - Utah JUG...
 
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
 
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
 
Teaching Your WAF New Tricks
Teaching Your WAF New TricksTeaching Your WAF New Tricks
Teaching Your WAF New Tricks
 
Bootiful Development with Spring Boot and React - RWX 2017
Bootiful Development with Spring Boot and React - RWX 2017Bootiful Development with Spring Boot and React - RWX 2017
Bootiful Development with Spring Boot and React - RWX 2017
 
Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKit
 
Advanced Mac Software Deployment and Configuration: Just Make It Work!
Advanced Mac Software Deployment and Configuration: Just Make It Work!Advanced Mac Software Deployment and Configuration: Just Make It Work!
Advanced Mac Software Deployment and Configuration: Just Make It Work!
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
 
Spring Boot APIs and Angular Apps: Get Hip with JHipster! KCDC 2019
Spring Boot APIs and Angular Apps: Get Hip with JHipster! KCDC 2019Spring Boot APIs and Angular Apps: Get Hip with JHipster! KCDC 2019
Spring Boot APIs and Angular Apps: Get Hip with JHipster! KCDC 2019
 
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
 
Os Johnson
Os JohnsonOs Johnson
Os Johnson
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RS
 

Semelhante a Docker and Django Meet For A Tango - London Meetup

Easy Web Project Development & Management with Django & Mercurial
Easy Web Project Development & Management with Django & MercurialEasy Web Project Development & Management with Django & Mercurial
Easy Web Project Development & Management with Django & Mercurial
Widoyo PH
 
Docker and Your Path to a Better Staging Environment - webinar by Gil Tayar
Docker and Your Path to a Better Staging Environment - webinar by Gil TayarDocker and Your Path to a Better Staging Environment - webinar by Gil Tayar
Docker and Your Path to a Better Staging Environment - webinar by Gil Tayar
Applitools
 

Semelhante a Docker and Django Meet For A Tango - London Meetup (20)

Dockerize a Django app elegantly
Dockerize a Django app elegantlyDockerize a Django app elegantly
Dockerize a Django app elegantly
 
Container Power Hour with Jess, Clare, and Abby (CON362) - AWS re:Invent 2018
Container Power Hour with Jess, Clare, and Abby (CON362) - AWS re:Invent 2018Container Power Hour with Jess, Clare, and Abby (CON362) - AWS re:Invent 2018
Container Power Hour with Jess, Clare, and Abby (CON362) - AWS re:Invent 2018
 
Easy Web Project Development & Management with Django & Mercurial
Easy Web Project Development & Management with Django & MercurialEasy Web Project Development & Management with Django & Mercurial
Easy Web Project Development & Management with Django & Mercurial
 
Software Project Management
Software Project ManagementSoftware Project Management
Software Project Management
 
Heroku
HerokuHeroku
Heroku
 
Odoo development workflow with pip and virtualenv
Odoo development workflow with pip and virtualenvOdoo development workflow with pip and virtualenv
Odoo development workflow with pip and virtualenv
 
Overseeing Ship's Surveys and Surveyors Globally Using IoT and Docker by Jay ...
Overseeing Ship's Surveys and Surveyors Globally Using IoT and Docker by Jay ...Overseeing Ship's Surveys and Surveyors Globally Using IoT and Docker by Jay ...
Overseeing Ship's Surveys and Surveyors Globally Using IoT and Docker by Jay ...
 
Django Architecture Introduction
Django Architecture IntroductionDjango Architecture Introduction
Django Architecture Introduction
 
Dart on Arm - Flutter Bangalore June 2021
Dart on Arm - Flutter Bangalore June 2021Dart on Arm - Flutter Bangalore June 2021
Dart on Arm - Flutter Bangalore June 2021
 
Introduction to PaaS and Heroku
Introduction to PaaS and HerokuIntroduction to PaaS and Heroku
Introduction to PaaS and Heroku
 
Django by rj
Django by rjDjango by rj
Django by rj
 
Easy Step-by-Step Guide to Develop REST APIs with Django REST Framework
Easy Step-by-Step Guide to Develop REST APIs with Django REST FrameworkEasy Step-by-Step Guide to Develop REST APIs with Django REST Framework
Easy Step-by-Step Guide to Develop REST APIs with Django REST Framework
 
Droidcon London 2021 - Full Stack Dart
Droidcon London 2021   - Full Stack DartDroidcon London 2021   - Full Stack Dart
Droidcon London 2021 - Full Stack Dart
 
EuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears TrainingEuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears Training
 
Django
DjangoDjango
Django
 
Introduction to Heroku
Introduction to HerokuIntroduction to Heroku
Introduction to Heroku
 
Docker and Your Path to a Better Staging Environment - webinar by Gil Tayar
Docker and Your Path to a Better Staging Environment - webinar by Gil TayarDocker and Your Path to a Better Staging Environment - webinar by Gil Tayar
Docker and Your Path to a Better Staging Environment - webinar by Gil Tayar
 
Introduction to django framework
Introduction to django frameworkIntroduction to django framework
Introduction to django framework
 
Mini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico CesMini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico Ces
 
بررسی چارچوب جنگو
بررسی چارچوب جنگوبررسی چارچوب جنگو
بررسی چارچوب جنگو
 

Último

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Último (20)

Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 

Docker and Django Meet For A Tango - London Meetup

  • 1. Copyright 2019 © systemati.co Docker and Django Meet For A Tango Hendrik Frentrup hendrik@systemati.co 15 July 2019 London, UK
  • 2. Copyright 2019 © systemati.co Ways to get in touch hendrik@systemati.co @HendrikFrentrup linkedin.com/in/frentrup/ github.com/hendrikfrentrup medium.com/@hendrik.frentrup
  • 3. Copyright 2019 © systemati.co Links •GitHub repo for the code •github.com/hendrikfrentrup/docker-django •Walkthrough: •medium.com/devopslinks/tech-edition-how-to-dockerize-a-django-web- app-elegantly-924c0b83575d •https://medium.com/@hendrik.frentrup/tech-edition-django-dockerization- with-bells-and-whistles-and-a-tad-bit-of-cleverness-2b5d1b57e289 •Further reading: •medium.com/panaseer-labs-engineering-data-science/how-devops- helped-us-solve-our-big-data-development-problem-263474dfeedb •Contact details: •Email: hendrik@systemati.co •Twitter: @hendrikfrentrup •LinkedIn: linkedin.com/in/frentrup/
  • 4. Copyright 2019 © systemati.co Code! • This will be a pretty detailed walk-through • There will be a lot of code in detail • Sometimes I’ll flick through things pretty quickly • I’ll make the slides available
  • 5. Copyright 2019 © systemati.co The Problem • Moving code from development environments to staging or production can break things • The state of environments drifts and is hard to manage • For lack of access, developers have no insight into the specifics of production environments
  • 6. Copyright 2019 © systemati.co Why? • Ease the pain of moving from Dev to Prod • Step towards being Cloud Native • Twelve Factor App (https://12factor.net/) • Infrastructure-as-Code • Productivity
  • 7. Copyright 2019 © systemati.co From here Application Database Local machine
  • 8. Copyright 2019 © systemati.co To here Docker web gunicorn server db postgres Local machine db-admin pgadmin server nginx nginx server python manage.py runserver *.conf + static/ pg-data/
  • 9. Copyright 2019 © systemati.co • Move a locally running app into a container • Setup database, admin and nginx services • Run migrations • Logging • Implement Infrastructure-as-code • Bring development and production environments close together • Increase productivity & working collaboratively Outline
  • 10. Copyright 2019 © systemati.co Simple app running locally python manage.py runserver db.sqlite3 Local machine
  • 11. Copyright 2019 © systemati.co 10 commands to set up > git init > git checkout -b develop > virtualenv env > source env/bin/activate > pip install Django>=2.1 > echo 'Django>=2.1' >> requirements.txt > django-admin startproject my-site > git add * && git commit -m "..." > python mysite/manage.py runserver
  • 12. Copyright 2019 © systemati.co App running in container Docker web python manage.py runserver db.sqlite3 Local machine
  • 13. Copyright 2019 © systemati.co App inside Docker > touch Dockerfile > docker build -t django-docker:0.0.1 . > docker run -p 8001:8001 docker-django:0.0.1 ______Dockerfile____________________________________________________________ FROM python:3.6.7-alpine ENV PYTHONUNBUFFERED 1 RUN mkdir /code WORKDIR /code ADD ./ /code/ RUN pip install -r requirements.txt CMD ["python", "mysite/manage.py", "runserver", "0.0.0.0:8001"]
  • 14. Copyright 2019 © systemati.co Success looks like …
  • 15. Copyright 2019 © systemati.co Local storage Docker web python manage.py runserver db.sqlite3db.sqlite3 Local machine
  • 16. Copyright 2019 © systemati.co Moving to docker-compose > touch docker-compose.yml > docker-compose up ______docker-compose.yml__________________________________________________ version: "3" services: web: build: . command: python mysite/manage.py runserver 8001 ports: - “8001:8001” volumes: - ./mysite/:/code maps ports and container code/db to local filesystem
  • 17. Copyright 2019 © systemati.co Database service Docker web python manage.py runserver db postgres Local machine
  • 18. Copyright 2019 © systemati.co Adding a database service ______docker-compose.yml__________________________________________________ version: "3" services: web: build: . command: python mysite/manage.py runserver 8001 ports: - “8001:8001” volumes: - ./mysite/:/code db: image: postgres networks: - backend networks: backend: driver: bridge
  • 19. Copyright 2019 © systemati.co Handling env. variables ______settings.py____________________________________________________________ POSTGRES_PASSWORD = os.environ.get('POSTGRES_PASSWORD') DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'postgres', 'USER': 'postgres', 'PASSWORD': POSTGRES_PASSWORD, 'HOST': ‘db', 'PORT': '5432', }, ______.env__________________________________________________________________ POSTGRES_PASSWORD=secret POSTGRES_USER=postgres DJANGO_SECRET_KEY=secret > touch .env > echo 'psycopg2-binary' >> requirements.txt
  • 20. Copyright 2019 © systemati.co Credentials in envvars ______docker-compose.yml__________________________________________________ version: "3" services: web: [...] environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_USER: ${POSTGRES_USER} db: [...] environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_USER: ${POSTGRES_USER}
  • 21. Copyright 2019 © systemati.co Rebuilding the web image ______Dockerfile____________________________________________________________ FROM python:3.6.7-alpine ENV PYTHONUNBUFFERED 1 RUN apk update && apk add --virtual build-deps gcc python-dev musl-dev && apk add postgresql-dev RUN mkdir /code WORKDIR /code ADD ./ /code/ RUN pip install -r requirements.txt
  • 22. Copyright 2019 © systemati.co A bit of admin > docker-compose exec web python mysite/manage.py migrate > docker-compose exec web python mysite/manage.py createsuperuser Run that every time we tear down our containers? Note down the credentials we’ve used?
  • 23. Copyright 2019 © systemati.co Data migrations ______0001_initial.py___________________________________________________________ import os from django.db import migrations class Migration(migrations.Migration): dependencies = [] def generate_superuser(apps, schema_editor): from django.contrib.auth.models import User DJANGO_SU_NAME = os.environ.get('DJANGO_SU_NAME') DJANGO_SU_EMAIL = os.environ.get('DJANGO_SU_EMAIL') DJANGO_SU_PASSWORD = os.environ.get('DJANGO_SU_PASSWORD') superuser = User.objects.create_superuser( username=DJANGO_SU_NAME, email=DJANGO_SU_EMAIL, password=DJANGO_SU_PASSWORD) superuser.save() operations = [ migrations.RunPython(generate_superuser), ]
  • 24. Copyright 2019 © systemati.co More credentials ______docker-compose.yml__________________________________________________ version: "3" services: web: [...] environment: DJANGO_DB_NAME: ${DJANGO_DB_NAME} DJANGO_SU_NAME: ${DJANGO_SU_NAME} DJANGO_SU_EMAIL: ${DJANGO_SU_EMAIL} DJANGO_SU_PASSWORD: ${DJANGO_SU_PASSWORD} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_USER: ${POSTGRES_USER}
  • 25. Copyright 2019 © systemati.co web, db and admin services Docker web python manage.py runserver db postgres Local machine db-admin pgadmin server
  • 26. Copyright 2019 © systemati.co Adding a DB admin service ______docker-compose.yml__________________________________________________ [...] db-admin: image: dpage/pgadmin4 environment: PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL} PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD} depends_on: - db ports: - "8080:80" networks: - backend [...]
  • 27. Copyright 2019 © systemati.co pgadmin in action
  • 28. Copyright 2019 © systemati.co Local app for debugging Docker web python manage.py runserver db postgres Local machine db-admin pgadmin server python manage.py runserver
  • 29. Copyright 2019 © systemati.co Run a local app alongside ______settings.py____________________________________________________________ from decouple import config SECRET_KEY = config(‘DJANGO_SECRET_KEY') DEBUG = config('DJANGO_DEBUG', default=False, cast=bool) WEB_HOST = config('DJANGO_WEB_HOST', default='localhost') DB_HOST = config('DJANGO_DB_HOST', default='localhost') DB_NAME = config(‘DJANGO_DB_NAME’) [...] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'postgres', 'USER': POSTGRES_USER, 'PASSWORD': POSTGRES_PASSWORD, 'HOST': DB_HOST, 'PORT': '5432', },
  • 30. Copyright 2019 © systemati.co Run a local app alongside ______docker-compose.yml_____________________________________ [...] environment: DJANGO_DEBUG: "True" DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY} DJANGO_DB_HOST: “db" [...]
  • 31. Copyright 2019 © systemati.co With nginx Docker web gunicorn server db postgres Local machine db-admin pgadmin server nginx nginx server python manage.py runserver
  • 32. Copyright 2019 © systemati.co Add nginx server ______default.conf_______________________________ server { listen 80; server_name localhost; location / { proxy_pass http://web:8001; } } ______settings.py________________________________ [...] ALLOWED_HOSTS = [WEB_HOST, ‘localhost'] [...] > echo “gunicorn” >> requirements.txt
  • 33. Copyright 2019 © systemati.co Add nginx server ______docker-compose.yml__________________________________________________ [...] web: command: gunicorn mysite.wsgi --bind 0.0.0.0:8001 [...] nginx: image: nginx:latest ports: - 8088:80 volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf networks: - backend depends_on: - web [...]
  • 34. Copyright 2019 © systemati.co Static files & persistent data Docker web gunicorn server db postgres Local machine db-admin pgadmin server nginx nginx server python manage.py runserver *.conf + static/ pg-data/
  • 35. Copyright 2019 © systemati.co Serving static assets ______settings.py_______________________________________ [...] STATIC_ROOT = os.path.join(BASE_DIR, 'static') > python mysite/manage.py collectstatic ______default.conf_____________________ server { [...] location /static { alias /code/static; } }
  • 36. Copyright 2019 © systemati.co Serving static assets ______docker-compose.yml__________________________________________________ [...] nginx: [...] volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf - ./mysite/static:/code/static [...] db: volumes: - ./postgres-data:/var/lib/postgresql/data [...]
  • 37. Copyright 2019 © systemati.co Mapped ports Docker web 8001 db 5432 Local machine db-admin 8080 nginx 8088 8000
  • 38. Copyright 2019 © systemati.co Splitting YAML files ______docker-compose.override.yml_____________ [...] volumes: - ./mysite:/code environment: DJANGO_DEBUG: “True" [...] ______docker-compose.yml_______________ [...] web: build: . command: gunicorn mysite.wsgi --bind 0.0.0.0:8001 depends_on: - db networks: - backend [...]
  • 39. Copyright 2019 © systemati.co Logs
  • 40. Copyright 2019 © systemati.co Logging locally • To STDOUT!
  • 41. Copyright 2019 © systemati.co Logs in shared envs • Complex topic and no one size fits all • Log aggregator (SumoLogic, Splunk, ELK etc.) • A complete ELK stack in one container • Various logging driver options • Fluentd • Gelf Log aggregatorFluentd LogStash ElasticSearch Kibana
  • 42. Copyright 2019 © systemati.co Logging Local machine Staging environment Build server Log aggregator Production Code repo Local machine push trigger tail deploy stream deploy stream
  • 43. Copyright 2019 © systemati.co That’s all! Thanks