Docker

docker #

CMD & ENTRYPOINT #

https://www.docker.com/blog/docker-best-practices-choosing-between-run-cmd-and-entrypoint/

Building docker image from scratch when using K8S #

  • replication is handled at the cluster level, instead of using process manager in each container that starts multiple worker process (like Gunicorn with workers)
  • building docker image from scratch and running a single process
# Gunicorn config variables, app/gunicorn_conf.py
loglevel = "info"
errorlog = "-"  # stderr
accesslog = "-"  # stdout
worker_tmp_dir = "/dev/shm"
graceful_timeout = 120
timeout = 120
keepalive = 5
threads = 3
FROM python:3.9

WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD ["gunicorn", "--conf", "app/gunicorn_conf.py", "--bind", "0.0.0.0:80", "app.main:app"]
#!/usr/bin/env python
# coding: utf8
"""app/main.py"""

from flask import Flask

app = Flask(__name__)

@app.get('/')
def index():
    return 'Hello, world!'
# requirements.txt
flask==2.0.2
gunicorn==20.1.0

alpine python warning #

  • good for building static binary using multi-stage docker building, for example Golang
  • it use musl instead of glibc, which is not the standard tooling for building Python extensions
  • use slim version based on Debian

uwsgi-nginx-flask #

meinheld-gunicorn-flask #

400% performant than uwsgi version

uvicorn-gunicorn-fastapi #

virtualenv #