The boxfile is simple, setting up only the bare minimum for this test. You will see that the engine is also very simple. I wanted one that didn’t do any magic or sniffing to install system or Python packages.
I wanted to see if I could put all the pip files and Python packages in a custom, cacheable location. For what it's worth, this all seems to work for me. You can run each command below to see the output. But I think, if this actually does work, all of these steps could be put in the Python engine.
# Fire up the box.
nanobox run --trace --debug
# Install pip in our custom location.
python -m ensurepip --default-pip --root=/app/.nanobox/python
# Look, there it is! But ... what the heck? Why did it use `data` as a prefix?
tree -a -L 5 .nanobox/python
# Now setup our paths. (Just roll with the `data` prefix for now.)
export PATH="/app/.nanobox/python/data/bin:$PATH"
export PYTHONPATH="/app/.nanobox/python/data/lib/python3.6/site-packages"
# Make an alias for a pip install to test this out. All of these can be set
# with environtment variables instead (e.g. `PIP_ROOT=/blah`), or by a properly
# placed pip.conf. Those could be part of the engine, to coordinate the
# cache_dirs and these values.
alias pinstall="pip install --verbose \
--build=/app/.nanobox/pip/build \
--cache=/app/.nanobox/pip/cache \
--src=/app/.nanobox/pip/src \
--log=/app/.nanobox/pip/pip.log \
--root=/app/.nanobox/python"
# Upgrade bits and install wheel (which does not come with pip by default).
pinstall -U pip setuptools wheel
# Run these then view your app at http://172.nn.0.nn:8000
pinstall gunicorn gevent
gunicorn -b 0.0.0.0:8000 -w 2 -k gevent myapp:app
# See, there it all is! (And that darn `data` prefix. Ugh.)
tree -a -L 3 .nanobox/
The only caveat is the data
prefix thing. I cannot figure out how to stop
ensurepip
from adding that data
prefix. But the interesting thing is that
if you add --install-option=\"--prefix=\" \
as a line in that pinstall
alias, everything after ensurepip gets put where we want, at
/app/.nanobox/python/(bin|lib|include)
. So it must be some distutils/setuptools
config thing that Nanobox has set. I think that is in
/data/lib/python3.6/config-3.6/Makefile
, and you can see it with this:
/app $ python
>>> import sysconfig
>>> sysconfig.get_config_var('prefix')
'/data'
Yeah, we set that prefix because all the binaries are installed under
/data
, so Python needs to look for them there. Interesting that it's not being overridden for ensurepip.