13

I have a very minimalist Dockerfile for my production Django application:

FROM python:3.8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN apt-get update &&
  apt-get -y upgrade

WORKDIR /app

COPY requirements.txt ./
RUN pip install --upgrade pip && \
  pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD [ "gunicorn", "api.wsgi:application", "--bind=0.0.0.0" ]

Do I need to run apt-get update && apt-get -y upgrade? From my understanding, the two commands (1) download the latest listing of available packages and (2) upgrade already installed packages. Why does the official python docker image not do this already?

If I don't need to run them in this minimalist Dockerfile, when do I need to run them? I've noticed they're commonly run when installing other packages.

Johnny Metz
  • 5,977
  • 18
  • 82
  • 146

2 Answers2

10

The base Docker Hub Linux distribution images like ubuntu:18.04 actually update themselves fairly regularly: if you docker pull ubuntu:18.04, wait a week, and repeat it, you will get a newer image. You're somewhat dependent on intermediate images, like python:3.8, doing the same thing.

It is unusual, but not unheard-of, to run apt-get update and similar "upgrade everything" commands in a Dockerfile; it is more common to either assume the base image is up-to-date already, or to have specific provenance requirements and build everything from scratch on top of a base distribution image.

If you're using a major-version or minor-version image tag (python:3, python:3.8, python:3.8-buster) you're probably okay, so long as you make sure to update your base image to something listed on the Docker Hub image page periodically. If you're forcing a specific patch level (python:3.8.4) you're at some risk, since these images stop getting updates once a newer upstream version is released.

You do need to run apt-get update if you need to install any OS-level packages, and for Docker layer-caching reasons you should do it in the same RUN command as the corresponding apt-get install

# Doesn't usually have an "upgrade"
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      a-package \
      another-package \
      more-packages
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • “and for Docker layer-caching reasons you should do it in the same RUN command” — please provide evidence supporting this statement. – alexpirine Mar 17 '23 at 11:12
  • [Docker build: unable to fetch archives](https://stackoverflow.com/questions/39518377/docker-build-unable-to-fetch-archives) is one example. If Docker has cached yesterday's `RUN apt-get update` line, then when it tries to `RUN apt-get install` today, it can try to fetch URLs that don't exist any more. – David Maze Mar 17 '23 at 13:35
1

Looking at the docker best pratices, you should do update but not upgrade as this require your container to run with privileged permission. Doing the update make sure you are installing the latest version of the package you want to install. Considering this, the provider of the base image is responsible to choose the version of the package used inside the base (or update to the latest) while you are responsible for the ones you need.

Cyril G.
  • 1,879
  • 2
  • 5
  • 19