10

Problem

Docker image sizes should commonly be as small as possible. Using full-blown environments like a standard python image results often, with all dependencies installed, in heavily bloated images. Packaging python into stand-alone executables (e.g. using pyinstaller) is a perfect way of reducing image sizes and overall complexity.

Environment: python3.6, pyinstaller==3.4

The problem arising is, that python uses per default buffered stdio. This can be mitigated by running python scripts with python -u .... But becomes inaccessible when using pyinstaller.

According to the docs it should be possible to add run-time options, such as u, v and W ... to the executable generated. But unfortunately in reality it doesn't seem to work. Both, v and W, work normally, but u seems to be completely ignored.

The following snippet shows the usage:

...
exe = EXE(...
          [('u', None, 'OPTION')],
          name="myapp",
          ...)
...

Is this flag still valid? Since the others work - has it been removed without notice or update of the docs?

Are there alternatives to disable buffering of stdio (with pyinstaller or as well externally), without modifying the python code, like so?

Why would that be needed?

Buffered IO is to be avoided, when running docker swarm services. In order to make the executable properly log in real-time to the docker daemon, it's necessary to attach a shell. But the attaching of a tty shell to the swarm tasks makes working with the logs much, much more complicated if even impossible.

p-j-e
  • 236
  • 1
  • 7

2 Answers2

0

At least it is broken on Windows (See issue on github) and it’s not in the docs.

karlsebal
  • 1,449
  • 17
  • 23
0

This pull request fixed the issue.

The '-u' option will set the Py_UnbufferedStdioFlag flag to enable unbuffered stdio mode in Python library.

This doc shows how to enable the runtime option with spec file.

options = [ ('u', None, 'OPTION') ]
a = Analysis( ...
        )
...
exe = EXE(pyz,
  a.scripts,
  options,   <--- added line
  exclude_binaries=...
  )

NOTE:

This enables unbuffered binary layer of stdout and stderr streams in all supported Python versions, while unbuffered text layer requires Python 3.7 or later.