Tips on dockerizing python apps

While I have been dockerizing a variety of apps I realized that python has its own special set of gotchas. Therefore I decided to write this post to list a few tips that will save time to first-timers.

PYTHONBUFFERRED: Missing standard output

One of the first gotchas you might notice is that if you are missing PYTHONBUFFERED configuration stdout/stderr messages may not be preset in terminal output in a timely manner or several lines may be entirely missing on application crash. Depending on you use-case, you may set PYTHONBUFFERED to a non-empty string so that output will be unbuffered. The above issues are solved afterwards.

Slow builds: The curse of alpine

If you try to build your app in alpine you ‘ll notice slow builds, by magnitude slower than installing apps on your local machine. This is because Standard PyPI wheels don’t work on Alpine.

Most Linux distributions use the GNU version (glibc) of the standard C library that is required by pretty much every C program, including Python. I contrast Alpine Linux uses musl and since pipy wheels are compiled using giblic they are not supported on Alpine.

Although most Python packages include binary wheels that significantly decrease install time on all alpine set-ups you ‘ll need need to compile all the C code in every Python package that you use.

To my experience the most convenient distro base image for python is debian slim. I t keeps your image small whilst not sacrificing on distributed wheel support, hence giving faster build times.

Optimal pipenv dependency setup

In first instance, using pipenv virtual environment seemed quite unstable. Issues ranged form not setting current directory in python path - to crashing shells. I am sure all the above might have already been fixed, and I already knew a few workarounds that could mitigate them. Another thing to consider is optimal image size, global setup of dependencies in an isolated image would hardly cause any issue whilst it can keep image size to the minimum. In order to install to the parent system rather than creating a virtual environment, the --system flag needs to be used. Another thing we need to take care of is to ensure lock file entries are exactly what’s installed using --ignore-pipfile. To ensure lock file is up-to date we can use --deploy which will fail the command if any dependency is outdated.

Considering the above the ideal command for most use cases I dealt with is:

1
pipenv install --system --deploy --ignore-pipfile

I am sure this is just a few of the things I could list here but I ll keep this page updated.

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2012-2023 Andreas Galazis

请我喝杯咖啡吧~