Let’s assume you are sold on Docker – you need and love Docker.
How is it used?
On your computer:
– install docker (docker desktop is most popular, podman is gaining ground)
– develop an application adjusting your Dockerfile
– use Dockerfile to build a “image” – a portable package of your app
– test locally by running the image as a “containerized process” (container)
– upload image it to hosted image registry (typically DockerHub)
On your server:
– install docker engine
– pull image from hosted image registry
– run the image as a “container”
Development Workflow: Dockerfile -> Image -> Container
– Dockerfile is instructions to build an application environment and run application
– Image is a portable package built by running Dockerfile with everything needed to run the application.
– Container is a running instance of an image
Note: some people say the image is like a recipe, but it actually has all the code needed to run your application.
How to write a Dockerfile
Remember Dockerfiles are instructions for building an image. Include s:
– setting a base image to build upon
– setting environment variables
– setting a “working directory” (WORKDIR) of the image
– running COPY, RUN, CMD commands to execute inside WORKDIR
WORKDIR – “While building the image, change the working directory to /code. If /code doesn’t exist yet in the image, create it inside the image.”
COPY – “Copy these files from the local machine into the image WORKDIR”
RUN – “Execute this command in the container”
# Dockerfile
# Pull base image
FROM python:3.10.4-slim-bullseye
# Set environment variables
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory for the image
# Automatically creates the /code directory (in the image)
# Sets it as the current directory for all following commands:
# RUN, CMD, COPY, and ENTRYPOINT
WORKDIR /code
# Note: Docker uses / (the root directory) by default,
# which is usually not what you want —
# it's better to work in an isolated app folder like /code, /app, or /srv/app.
# Install dependencies (with layer caching)
# 1. copy requirements file into the image
# 2. run pip install
# The COPY command takes two parameters:
# 1. what local file(s) to copy into the image,
# 2. where you want the file(s) to be copied (relative to WORKDIR).
# In this case, we are copying the existing requirements.txt file
# from our local computer into the current working directory
COPY ./requirements.txt .
RUN pip install -r requirements.txt
# Note: We usually install dependencies before copying the rest of the app
# to take advantage of Docker's layer caching:
# So RUN pip install happens before COPY . .
# Copy project
# copy the current directory on our local filesystem (.)
# into the working directory (.) of the image.
COPY . .
Now you can run the image as a container
# builds the image "." is where the Dockerfile is located
docker build .
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 0cc1074c90de 3 minutes ago 253MB
# Note: returns immediately and doesnt start the server because there is no CMD to do so
docker run 0cc1074c90de
# Run a django server
# Note: you need to add 0.0.0.0 to allowed hosts
# 0.0.0.0 tells Django to accept requests from any IP address, including the host machine
# 127.0.0.1:8000 is only accessible inside the container
docker run -p 8000:8000 0cc1074c90de python manage.py runserver 0.0.0.0:8000
Docker compose
Docker compose allows you to set up multi-container applications
– you will soon have separate containers for the web server, database, cache
– here you have one container “web”
# docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
# “Map port 8000 inside the container to port 8000 on my host machine.”
- "8000:8000"
# 0.0.0.0 means listens for incoming requests on any IP address inside the container.
command: python manage.py runserver 0.0.0.0:8000
# visit http://127.0.0.1:8000
# “Send this request to port 8000 on my own machine.”
# Docker receives that request and passes it to your Django container
# Sync with the local filesystem:
# Take the current directory on my host machine (the .),
# and mount it into the container at the /code path.
# Develop without rebuilding the Docker image for every Python file change.
volumes:
- .:/code
You can now use docker compose to run the container
docker-compose up
# visit 127.0.0.1:8000
docker-compose down
Learn more:
Previous: https://theptrk.com/wp-admin/post.php?post=1585&action=edit