Cuong Tran presented on Django development with Docker. The presentation covered:
1. Introduction to the Django Docker stack including Nginx, Django, Postgres, and Redis.
2. How to run the Django stack using Docker Compose including building, starting containers, and migrating data.
3. Common activities like running commands in containers, updating code in Git, and rebuilding Docker images.
4. Problems and solutions like handling Docker stop signals gracefully, ensuring proper startup order, and optimizing the Docker build process.
5. Useful Docker snippets for stats, removing containers/images, and saving/loading images.
8. 2. Run Django Stack
# build stack
docker-compose build
# up stack
docker-compose up -d
# migrate data
docker-compose run --rm web /usr/local/bin/python manage.py
migrate
8
9. 3. Common Activity: Run container
● View web
● Run command in container
● Show logs
● Connect database to container
9
10. 3. Common Activity: Update git
● Edit and git commit
● Git ignore files for dev, test, prod environments
● Update git
10
11. 3. Common Activity: Build container
● Rebuild docker images
● Push to private registry
● Update docker images in production
11
12. 4. P&S: Handle `docker stop`
● When call docker stop, docker will send SIGTERM to main process
inside the container. And after a grace period (default 10s), docker will
send SIGKILL.
12Image Source: http://www.slideshare.net/LeszekGodlewski/advanced-linux-game-programming
13. 4. P&S: Handle `docker stop`
● The main process need to handle the signal and graceful stop.
import sys, signal, time
def handler(signum = None, frame = None):
print('Signal handler called with signal', signum)
time.sleep(1) #here check if process is done
print('Wait done')
sys.exit(0)
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
signal.signal(sig, handler)
while True:
time.sleep(6)
13
14. 4. P&S: Startup order
Issue: Docker Compose:
● Will not wait until a container is "ready".
● Only until it’s running.
Solution:
● Use a tool such as wait-for-it or dockerize.
● (Or) Write your own wrapper script to perform a more application-specific
health check.
14Reference: https://docs.docker.com/compose/startup-order/
15. 4. P&S: Startup order
wait-for-postgres.sh
#!/usr/bin/env bash
set -e
host="$1"
shift
cmd="$@"
until psql -h "$host" -U "postgres" -c 'l'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
15
wait-for-it.sh
#!/usr/bin/env bash
# Use this script to test if a given TCP
host/port are available
cmdname=$(basename $0)
echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@"
1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$cmdname host:port [-s] [-t timeout] [--
command args]
-h HOST | --host=HOST Host or IP under
test
-p PORT | --port=PORT TCP port under
test
...
16. 4. P&S: Speed up `docker build`
Use .dockerignore
● Because docker will put current directory in build context.
● To increase the build's performance, you can exclude files and directories
by adding a .dockerignore file.
● Syntax like .gitignore.
16
17. 4. P&S: Speed up `docker build`
Build cache
● The orders of command -> image layers -> build speed & image size &
storage capacity
1. Install fixed things before. Ex: library, runtime
2. Install changed things after. Ex: code
17
20. 5. Snippets (cont.)
Save all the images on docker-compose.yml and deploy on machine not
connected to the internet
# Save Compressed Images
IMAGES=`grep '^s*image' docker-compose.yml | sed 's/image://' | sort | uniq`
docker save $IMAGES | gzip > images.tar.gz
# Load Compressed Images
gunzip -c images.tar.gz | docker load
20