mod_wsgi: How to run different apps under single domain? - python

I have a domain example.com and I run a standard Apache there (serving static files and PHP). I want to run Python served pages on subdomain.example.com.
I managed to configure Apache to do this and there is a Flask app running at subdomain.example.com. However, in the virtual host config file, the whole subdomain is tight to this one single app. I would like to go further and run several different apps on this subdomain.
For example:
subdomain.example.com/app1/ would run /var/www/apps/app1/app.wsgi
subdomain.example.com/app2/ would run /var/www/apps/app2/app.wsgi
and so on...
Furthermore I would like this to be fully automatic, that is when I set up new folder in /var/www/apps/, I could reach the app through the Apache without further configuration.
I can see several ways of doing this:
Configure Apache to route every subdomain.example.com request
to a single "meta app" in Python which would run a specific app
based on given URL.
Do some magic with Apache configuration that would take care of
this automatically.
Maybe use nginx? I don't really have much experience with this,
but someone told me this could solve the problem.
Is there any best practice about how to do this? Thank you.

It looks like you should be able to do this by providing a directory path (in your case, /var/www/apps) to the WSGIScriptAlias directive. Read more here:
https://modwsgi.readthedocs.org/en/develop/configuration-directives/WSGIScriptAlias.html
This seems like a neater solution than using a meta app.

Related

Where is Flask running from on my OS X machine?

I'm used to building my websites with PHP, and on my OS X machine I expect to have to ensure that I have my scripts living in an explicitly specified location that I define as my Apache server's document root. But when I follow the simple instructions for building a Flask website, I magically get a working website, with nothing at all in any of the places on my machine that serve as document roots, regardless of where I have my Flask script. This is especially confusing since I always think if deployment as involving careful duplicating the file structure of my site under document root on the deployment server's document root.
Where is Flask "running from" on my OS X machine? Where do I "put it" when I deploy it (and what to I put)?
It's running from wherever you put it. You surely know where you saved the code: that's where it is.
But your mistake is in thinking that this development environment is running through Apache, or indeed has anything to do with how you'll run it in production. Neither is true. You're using a development server, the separate Werkzeug project, but that is not suitable for running in prod.
When you are ready to deploy, Flask has full instructions on how to either connect it to Apache through mod_wsgi, or set up a separate WSGI server which you'll usually connect to through a reverse proxy such as nginx.
Supposed you have your main.py under /path/to/my_project/, when you run the internal server python main.py, Flask is then running under your project folder.
Of course that built-in server is only good for development, when you're trying to deploy for production, normally Gunicorn (via wsgi app, read more HERE) or other web server is more appropriated (and advised by Flask) itself. And your production folder can be placed wherever you want, just like Apache PHP you may place your folder under /var/www/ (EDITED: as Daniel Roseman pointed out, you may try to change this folder location for security concern), it's the same for Flask, that's nothing stops you placing the folder but rather have the permission set properly.
Hope this helps.

On cloudcontrol, how can I do a URL rewrite?

For a Python / Django application running on cloudcontrol, what's the recommended way of rewriting urls, e.g. attaching a wordpress blog to a certain url path like example.com/blog/, or even just redirecting a subdomain?
I'd know how to do this with an .htaccess file - is there an equivalent that would work on cloudcontrol? I found some sample cctrl apps that use .htaccess files (e.g. https://github.com/cloudControl/example_apps/blob/master/php/kohana/example.htaccess), but that's all PHP and it does not seem to work for my Django app.
You have multiple options. Let me explain the basic concept first. Generally every app on cloudControl has its own subdomain like APP_NAME.cloudcontrolled.com. Requests to those subdomains (or from a CNAME pointing to that subdomain) are forwarded by the routing tier to one or more of the containers available to serve requests. What runs inside each container is controlled by the Buildpack. Depending on the preferences of each language ecosystem (e.g. PHP vs Python) the runtime environment in the container differs. So for PHP, Apache is available while for Python it is not.
Option 1: The recommended way would be to have e.g. www.example.com poing to PYTHON_APP.cloudcontrolled.com and blog.example.com point to PHP_APP.cloudcontrolled.com.
Option 2: Alternatively if you have to use /blog instead of a blog. subdomain you can teach the Apache running inside the PHP App's containers to only serve requests for /blog and forward everything else to PYTHON_APP.cloudcontrolled.com.
Option 3: Soon you'd have a third option also, but this isn't available yet. We're currently working on enabling the Python buildpack to run Nginx inside the containers and use WSGI to communicate with the Python process. (Currently the Python process has to listen on the $PORT and serve HTTP directly) As soon as Nginx is available you could also configure it to forward /blog to PHP_APP.cloudcontrolled.com and serve everything else directly.
My recommendation would be to go with option 1, since that keeps both apps nicely decoupled. By permanently redirecting /blog in the Python app to blog.example.com you can make the migration painless.

How do I configure a Flask-based python app using nginx and uwsgi?

I have a Flask-based python app that needs a bunch of configuration information (e.g. database connection parameters) on app start.
In my nginx configuration, I can provide parameters using uwsgi_param, as shown in this SO question.
However my problem is that the request.environ object is not available outside of a request handler, so I can't use it at application start. Furthermore, I'm trying to provide a mostly deployment-agnostic configuration mechanism so that I can test using Flask's embedded server during development and use parameters passed by uWSGI in production.
What's the best way to get configuration into my application so that it's accessible via os.environ or something similar?
Look at http://flask.pocoo.org/docs/config/#development-production. You always can have development, test and production config, you also can get some settings from OS envarment or specific file.
For example I have config module and import some secret settings (which don't want store with source code) from another module. Then on deploy I just replace file with secret settings. Probably better use for this OS envarement.

Django same project multiple times on one server

I had to develop something in Django (new to it) and it went quite smoothly. But after delivering to the client I had to setup a second "testing" instance so that any new features would be tested on it to avoid errors in the production one.
And I have only one apache server at my disposal and this breed some weird things.
I run my applications by adding path to the wsgi script in the httpd.conf.
It works fine, the new server is up and running. it used a different database so all is good. But it doesent use the views and models from its folder, it used the ones from the original app instead and I just ran out of ideas on how to fix it. Please help me in some way.
I believe that your two django projects should be deployed on your staging and production server as two completely seperate projects/directories.
If you use version control, this could be as trivial as branching your main project and adding the new features. After you have two seperate code bases you can put your fixed branch on your production server.
Your project can exist anywhere on your server. You could set up a staging subdomain and create a virtualhost that points to your django project branch
http://httpd.apache.org/docs/2.2/vhosts/examples.html
This would allow both projects to exist on the same server, without one project having to be aware of the other

Getting started with pylons on a VPS with Apache

I currently have Apache setup on my VPS and I'm wondering what would be the best way to handle Pylons development.
I have the directory structure with public_html in my home directory which includes separate website directories to which I map the IP to the DNS provided by my name registrar.
Is there a way to get paster running within a new directory (i.e. make an env/bin/paster) and run it to that?
If so then do I even need to get a new IP? Or would I be able to run both webservers in parallel on the same server without experiencing any conflicts?
I'm looking to convert all my new projects to Pylons.
It's usually more practical to develop first your application locally using pserve, the builtin HTTP server in Pyramid (it used to be paster before Pyramid 1.3 but pserve behaves similarly). This HTTP server comes quite handy when developing for debugging, but you don't usually expose your web application publicly with this server.
Once your application is ready to go public you should deploy your application on your server with another HTTP server like Apache. You can use WSGIScriptAlias if you have Apache with mod_wsgi, as it's documented in Pyramid, to map a subdirectory.
The official documentation explains also explains how you can have different subdirectories running different Pyramid instances with a virtual root.
If you really want to make your application accessible publicly with pserve, you can still use the urlmap composite functionality of PasteDeploy as explained in the documentation.
If your DNS are properly configured you don't need to mess with the IP.

Categories