Skip to content

Instantly share code, notes, and snippets.

@benspaulding
Created October 23, 2017 05:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benspaulding/a82717da81b2592b179f661af3c0dc93 to your computer and use it in GitHub Desktop.
Save benspaulding/a82717da81b2592b179f661af3c0dc93 to your computer and use it in GitHub Desktop.
Attempt to install Python packages and Pip data in special location on Nanobox

Simple Python WSGI app for testing some Nanobox stuff

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'
run.config:
engine: benspaulding/nanobox-engine-barebones
cache_dirs:
- .nanobox
extra_packages:
- python-3.6.3
- py36-expat # Needed for python -m ensurepip
- tree
web.site:
start: gunicorn -b 0.0.0.0:8000 -w 2 -k gevent myapp:app
"""
A simple WSGI app for testing.
"""
def app(environ, start_response):
status = '200 OK'
output = b'Hello Nanobox!\n'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
@danhunsaker
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment