Deploying my Python app to Heroku breaks Heroku's Python interpreter - python

This is an old app, running since about two years on Heroku. Now suddenly, when I deploy (standard git push), it breaks the Python interpreter, both on regular and one-off dynos. Here's what it looks like:
$ heroku run python
Running `python` attached to terminal... up, run.8338
python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
Further pushes, heroku restart, scaling the dynos to zero and back up, that all doesn't fix it.
The only changes contained in this deployment which I could imagine being related to this problem are: gevent upgraded from 0.13.6 to 1.0.1 and the introduction of a runtime.txt (before there was none, resulting in 2.7.4, now there's one for 2.7.6).
I rolled all of this back to no effect, however. In fact, I went back about 30 commits (the deployment contained maybe five) and pushed that and the app is still broken.
Rolling back with heroku rollback is the only way I've found to take the app back into a usable state. But of course that doesn't help me going forward.
What might cause this? Can I somehow rebuild my whole app environment from scratch?
EDIT 1: I opened a shell in a one-off dyno and I can see the libpython2.7.so.1.0 file there:
/ $ ls -la /app/.heroku/python/lib/libpython2.7.so.1.0
-r-x------ 1 u49295 49295 5694572 2014-06-03 23:39 /app/.heroku/python/lib/libpython2.7.so.1.0
Of course I don't know if that's where it's supposed to be.

Somehow certain apps did not upgrade properly. A temporary fix to locate the correct python library:
heroku config:set LD_LIBRARY_PATH=/app/.heroku/python/lib

Kenneth Reitz from the Python team here.
So, we're rolling out security updates to the version of Python that we have installed on our base system. Customers shouldn't be affected by this in any way, because their apps use their own version of Python, and because we set local runtime-specific (such as LD_LIBRARY_PATH) in a .profile.d scripts, outside of user-set configuration.
However, we allow power users to override these environment variables with $ heroku config. That's basically what the application was doing — although, not knowingly. This was an accidental side-effect of a much, much older Heroku. In older days, we couldn't have any runtime-specific configuration without being a part of user configuration. This is why your application had an LD_LIBRARY_PATH config set, and this is what caused this bug.
Because of this, I've disabled the overridability of LD_LIBRARY_PATH for Python apps, and all should be well moving forward.
Thanks for being a part of the gradual rollout process, and thanks for helping us get to the bottom of this regression. I'm very sorry for the inconvenience.

Are you using the default Python buildpack? Heroku is in the process of updating the Stack image, and especially if you're not using a current buildpack, there may be incompatibilities.
To see if you're using a default buildpack, run
$ heroku config | grep BUILDPACK_URL
Please contact Heroku support if you think this might be the cause.

Related

Trying to make a development instance for a Python pyramid project

So I have this Python pyramid-based application, and my development workflow has basically just been to upload changed files directly to the production area.
Coming close to launch, and obviously that's not going to work anymore.
I managed to edit the connection strings and development.ini and point the development instance to a secondary database.
Now I just have to figure out how to create another copy of the project somewhere where I can work on things and then make the changes live.
At first, I thought that I could just make a copy of the project directory somewhere else and run it with different arguments pointing to the new location. That didn't work.
Then, I basically set up an entirely new project called myproject-dev. I went through the setup instructions:
I used pcreate, and then setup.py develop, and then I copied over my development.ini from my project and carefully edited the various references to myproject-dev instead of myproject.
Then,
initialize_myproject-dev_db /var/www/projects/myproject/development.ini
Finally, I get a nice pyramid welcome page that everything is working correctly.
I thought at that point I could just blow out everything in the project directory and copy over the main project files, but then I got that feeling in the pit of my stomach when I noticed that a lot of things weren't working, like static URLs.
Apparently, I'm referencing myproject in includes and also static URLs, and who knows where else.
I don't think this idea is going to work, so I've given up for now.
Can anyone give me an idea of how people go about setting up a development instance for a Python pyramid project?
The first thing you should do, if it's not the case, is version control your project. I'd recommend using git.
In addition to the benefits of managing the changes made to the application when developing, it will aldo make it easier to share copies between developers... or with the production deployment. Indeed, production can just be a git clone of the project, just like your development instance.
The second thing is you need to install the project in your Python library path. This is how all the imports and includes are going to work.
I'd recommend creating a virtual environment for this, with either virtualenv or pew, so that your app (and its dependencies) are "isolated" from the rest of your system and other apps.
You probably have a setup.py script in your project. If not, create one. Then install your project with pip install . in production, or pip install -e . in development.
Here's how I managed my last Pyramid app:
I had both a development.ini and a production.ini. I actually had a development.local.ini in addition to the other two - one for local development, one for our "test" system, and one for production. I used git for version control, and had a main branch for production deployments. On my prod server I created the virtual environment, etc., then would pull my main branch and run using the production.ini config file. Updates basically involved jumping back into the virtualenv and pulling latest updates from the repo, then restarting the pyramid server.

Deploy Django project using wsgi and virtualenv on shared webhosting server without root access

I have a Django project which I would like to run on my shared webspace (1und1 Webspace) running on linux. I don't have root access and therefore can not edit apache's httpd.conf or install software system wide.
What I did so far:
installed squlite locally since it is not available on the server
installed Python 3.5.1 in ~/.localpython
installed virtualenv for my local python
created a virtual environment in ~/ve_tc_lb
installed Django and Pillow in my virtual environment
cloned my django project from git server
After these steps, I'm able to run python manage.py runserver in my project directory and it seems to be running (I can access the login screen using lynx on my local machine).
I read many postings on how to configure fastCGI environments, but since I'm using Django 1.9.1, I'm depening on wsgi. I saw a lot about configuring django for wsgi and virtualenv, but all examples required access to httpd.conf.
The shared web server is apache.
I can create a new directory in my home with a sample hello.py and it is working when I enter the url, but it is (of course) using the python provided by the server and not my local installation.
When I change the first line indicating which python version to use to my virtual environment (#!/path/to/home/ve_tc_lb/bin/python), it seems to use the correct version in the virtual environment. Since I'm using different systems for developing and deployment, I'm not sure whether it is a good idea to e.g. add such a line in my djangoproject/wsgi.py.
Update 2016-06-02
A few more things I tried:
I learned that I don't have access to the apache error logs
read a lot about mod_wsgi and django in various sources which I just want to share here in case someone needs them in the future:
modwsgi - IntegrationWithDjango.wiki
debug mod_wsgi installation (only applicable if you are root)
mod_wsgi configuration guide
I followed the wsgi test script installation here - but the wsgi-file is just displayed in my browser instead of beeing executed.
All in all it seems like my provider 1und1 did not install wsgi extensions (even though the support told me a week ago it would be installed)
Update 2016-06-12: I got a reply from support (after a week or so :-S ) confirming that they dont have mod_wsgi but wsgiref...
So I'm a bit stuck here - which steps should I do next?
I'll update the question regularly based on comments and remarks. Any help is appreciated.
Since your apache is shared, I don't expect you can change the httpd.conf but use instead your solution. My suggestion is:
If you have multiple servers you will deploy your project (e.g. testing, staging, production), then do the following steps for each deploy target.
In each server, create a true wsgi.py file which you will never put in versioning systems. Pretty much like you would do with a local_settings.py file. This file will be named wsgy.py since most likely you cannot edit the apache settings (since it is shared) and that name will be expected for your wsgi file.
The content for the file will be:
#!/path/to/your/virtualenv/python
from my_true_wsgi import *
Which will be different for each deploy server, but the difference will be, most likely, in the shebang line to locate the proper python interpreter.
You will have a file named my_true_wsgi to have it matching the import in the former code. That file will be in the versioning systems, unlike the wsgi.py file. The contents of such file is the usual contents of the wsgi.py on any regular django project, just that you are not using that name directly.
With this solution you can have several different wsgi files with no conflict on shebangs.
You'll have to use a webhost that supports Django. See https://code.djangoproject.com/wiki/DjangoFriendlyWebHosts. Personally, I've used WebFaction and was quite happy with it, their support was great and customer service very responsive.

Can I use Heroku as a Python server?

My web host does not have python and I am trying to build a machine learning application. I know that heroku lets you use python. I was wondering if I could use heroku as a python server? As in I would let heroku do all of the python processing for me and use my regular domain for everything else.
Yes, and it may be a pain at first but once it is set I would say Heroku is the easiest platform to continually deploy to. However, it is not intuitive - don't try and just 'take a stab' at it; follow a tutorial and try and understand why Heroku works the way it does.
Following the docs is a good bet; Heroku has great documentation for the most part.
Here's the generalized workflow for deploying to Heroku:
Locally, create your project and use virtualenv to install/manage
libraries.
Initialize a git repository in the base dir for your
Python project; create a heroku remote (heroku create)
Create a
procfile for Heroku to use when starting gunicorn (or see
the options for using waitress/etc); this is used by Heroku to start your process
cd to your base dir; freeze
your virtualenv (pip freeze > requirements.txt) and add/commit
requirements.txt. This tells Heroku what packages need to be installed, a requirement for your deployment to work. If you are trying to run a Python project and there are required packages missing, the app will be unable to start and Heroku will display an Internal Server Error.
Whenever changes are made, git commit your changes and git push heroku master to push all commits to Heroku. This will cause Heroku to restart the server application with your updated deployment. If there's a failure, you can use heroku rollback to just return to your last deployment.
In reality, it's not a pain in the ass, just particular. Knowing the rules of Heroku, you are able to manage your deployment with command-line git commands with ease.
One caveat - If deploying Django, Flask applications etc there are peculiarities to account for; specifically, non-project files (including assets) should NOT be stored on Heroku as Heroku periodically restarts your 'dyno' (server instance(s)), loading the whole project from the latest push to Heroku. With Django and Flask, this typically means serving assets/static/media files from an Amazon S3 bucket.
That being said, if you use virtualenv properly, provision your databases, and follow Heroku practices for serving files and commiting updates, it is (imho) the absolute best platform out there for ease of use, reliable uptime, and well-oiled rolling deployments.
One last tip - if you are creating a Django app, I'd suggest starting your project out of this boilerplate. I have a custom one I use for new projects and can start and publish a project in minutes.
Yes, you can use Heroku as a python server. I put a Python Flask server on Heroku but it was a pain: Heroku seemed to have some difficulties, and there were lots of conflicting advice on getting around those. I eventually got it working, can't remember what web page had the ultimate answer but you might look at this one: http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xviii-deployment-on-the-heroku-cloud
Have you done your Python Server on Heroku by using twisted?
I don't know if this can help you.
I see the doc 'Getting Started on Heroku with Python' is about the Django.
It is sure that Heroku can use Twisted from docs
Pure Python applications, such as headless processes and evented web frameworks like Twisted, are fully supported.
django-twisted-server has twisted in django but it isn't on Heroku.

How to tell if Pyramid/python is loading the right .egg?

This is a weird question but its been driving me bonkers for the last 3 hours. I wanted to play around with a pyramid based cms Kotti and I made a mistake by installing it using easy_install first(sudo easy_install kotti). I'm getting weird behavior and I'm not sure if its the way the program itself or the way I installed it.
I want to change some parts of the code and see how it works but my changes are not taking effect. After I installed it via easy_install I did:
virtualenv mysite --no-site-packages
bin/easy_install pyramid
git clone https://github.com/Pylons/Kotti.git
cd Kotti
sudo ../bin/python setup.py develop
../bin/pserve app.ini --reload
I went to 127.0.0.0:5000 and saw it was working. The first page has text that says "Congratulations! You have successfully installed Kotti." so I went into the kotti directory and did a grep "Congratulations" *.* and found it was coming from populate.py. So I opened the file and changed the line to a different piece of text and saved. Because I have the --reload flag on pserve I noticed it reloaded my code on the terminal and when I went back to the site the data did not change.
I'm so confused because the server reloads when I change the python code, so it sees the change but its not reflected in the browser(just to test if its the browser cache I tried it using different browsers and cleared the cache).
Any ideas?
When you run a Kotti web application for the first time, as with most CMS systems, it runs a set of data population methods (including that populate.py code you mentioned) to set up a database and insert all the content you see. The --reload is only telling the deployment server to watch for file changes as you work on the file system.
If you want to rerun the installation/population code then you need to delete the created database. If you haven't made any changes from their example app.ini file it will likely be Kotti.db.
Alternatively use the CMS to make the changes, as is intended by the CMS systems.
Running python -v will show all the imports

How to chroot Django

Can one run Django in a chroot? Notably, what's necessary in order to set up (for example) /var/www as a chroot'd directory and then have Django run in that chroot'd directory?
Thank you - I'm grateful for any input.
There are many reasons mod_wsgi is preferred for Python web app deployment. One is stability, another is the variety of configuration options... one of which is ability to chroot the mod_wsgi daemon (starting with version 3.00).
The chroot option is not yet documented for the WSGIDaemonProcess directive at http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIDaemonProcess but there is enough documentation in Changes in Version 3.0.
You can also read a disussion of the feature at http://code.google.com/p/modwsgi/issues/detail?id=106
You will have to add a Python interpreter to that directory and add Django to it ofcourse.
After you've got the environment set-up you will have to create a wrapper script that does something like os.chroot('/var/www/') and you're done :)
To create a sandboxed/chrooted environment for Python try one of the following options: http://wiki.python.org/moin/Asking%20for%20Help/How%20can%20I%20run%20an%20untrusted%20Python%20script%20safely%20%28i.e.%20Sandbox%29?highlight=%28chroot%29
The PyPy option seems to be getting popular since Google started using it with the App-Engine.

Categories