Run multiple independent Flask apps in Ubuntu - apache

I'm trying to run two or more Flask applications in separate virtual directories with Apache, like http://localhost/site1 for /var/www/myapps/app1 and http://localhost/site2 for /var/www/myapps/app2. Each app has its own virtual environment under an env directory.
I started with a fresh install of Ubuntu 14.04 with Apache2 (v2.4.7), removed the default site configuration with sudo a2dissite 000-default and added configuration for my two apps.
Here's the conf file for app1 at /etc/apache2/sites-available/app1.conf. The cofiguration for app2 is identical, replacing app2 for app1 (and site2 for site1.)
<VirtualHost *:80>
ServerName localhost
WSGIProcessGroup site1
WSGIDaemonProcess site1 user=myserviceuser group=myserviceuser threads=5 python-path=/var/www/myapps/app1:/var/www/myapps/app1/env/lib/python2.7/site-packages
WSGIScriptAlias /site1 /var/www/myapps/app1/application.wsgi
WSGIScriptReloading On
<Directory /var/www/mysites/app1>
WSGIApplicationGroup site1
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Then I enabled each site with sudo a2ensite app1 (and app2) then restarted the server with sudo apache2ctl restart.
Each of these apps has the following application.wsgi file in the root dir:
# put a copy of this file in the root dir of each app instance
import os, sys
# activate the virtual environment
app_dir = os.path.dirname(__file__)
# removed next two lines after a comment left below
# activate_this = os.path.join(app_dir, 'env', 'bin', 'activate_this.py')
# execfile(activate_this, dict(__file__=activate_this))
sys.path.insert(0, app_dir)
from myapp import app as application
What happens is that one of the sites runs fine, responding with the correct page when I hit it. The other gives me an Apache 404 page. There are no typos in the conf files.
It seems the configurations for the apps are clobbering each other and one is "winning." I've spent a lot of time tweaking the configurations but the only way I could make it work was if I added localhost2 to my hosts file and changed the ServerName to localhost2 in one of the app configs, which isn't desirable in my case. Can someone point me to the correct way to configure Apache? Or am I going the wrong way about this?
Ideally I'd want the configuration files to not care which host name was used to reach them, probably becoming multiple copies of this server running behind a load balancer.

I spent more time on this and, if I'm starting to understand Apache terminology and configuration a little better, I cannot use virtual hosts for this purpose. VirtualHost sections are intended for serving different host names (multiple domains or subdomains.)
For configuring parallel applications as subdirs I could have used Directory sections instead. I also didn't realize some of the WSGI* directives in the config file could appear more than once. This new knowledge allowed me to produce the following single config file that does what I wanted. So instead of enabling one Apache site for each app, I could enable a single site with the directories configured in it.
# this goes in /etc/apache2/sites-available/
<VirtualHost *:80>
ServerName localhost
# logs configuration
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
WSGIDaemonProcess site1 user=myserviceuser group=myserviceuser threads=5 python-home=/var/www/myapps/app1:/var/www/myapps/app1/env/lib/python2.7/site-packages
WSGIScriptAlias /site1 /var/www/myapps/app1/application.wsgi
<Directory /var/www/myapps/app1>
WSGIApplicationGroup site1
WSGIProcessGroup site1
Order deny,allow
Allow from all
</Directory>
WSGIDaemonProcess site2 user=myserviceuser group=myserviceuser threads=5 python-home=/var/www/myapps/app2:/var/www/myapps/app2/env/lib/python2.7/site-packages
WSGIScriptAlias /site2 /var/www/myapps/app2/application.wsgi
<Directory /var/www/myapps/app2>
WSGIApplicationGroup site2
WSGIProcessGroup site2
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
EDIT:
I later followed Graham Dumpleton's suggestion and removed the activate_this stuff from application.wsgi and changed the WSGIDaemonProcess directive lines to:
WSGIDaemonProcess site1 user=myserviceuser group=myserviceuser threads=5 python-home=/var/www/myapps/app1/env

Related

VirtualBox Ubuntu 16.04 apache2 vhost jumping to https or not showing the page

I am trying to set up some vhosts on a Virtual Box with Ubuntu 16.04 Apache2 PHP 7.0 to start moving the code to PHP7.
I have moved the v-host file from the older VBox which looked like this
<VirtualHost 192.168.2.174:80>
ServerName admin.ubuntu16.de
ServerAlias admin.ubuntu16.de
ServerAdmin email#company.de
DocumentRoot /home/www/public_html/workspace/admin
php_value auto_prepend_file '/home/www/public_html/workspace/admin/administration/conf/register_globals.php'
<Directory /home/www/public_html/workspace/admin>
Options Indexes FollowSymLinks MultiViews ExecCGI
Options All
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
But it kept on trying to load the page with https or saying that there is no access to site root folder
These settings work perfectly on Ubuntu 14 Virtuall Box with apache2 and PHP 5.5.something
So I followed the tutorial and changed it to simply
<VirtualHost 192.168.2.174:80>
ServerName admin.ubuntu16.de
ServerAlias admin.ubuntu16.de
ServerAdmin email#company.de
DocumentRoot /home/www/public_html/workspace/admin
</VirtualHost>
But now it just jumps straight to https mode
I obviously ran a2ensite
I also switched off the default site by running "a2dissite 000-default.conf"
I also enable modules to do with proxying and a bunch of others while getting appache to actuallly start :-)
Any ideas on things I might off missed are greatly appreciated.
Just a little edit:
All the files for the sites are situated on the main Windows machine and are imported through /media/sf-workspace
The symbolic link is then created as /home/www/public_html/workspace
I would first eliminate the symbolic links and just make a copy of all the files inside the virtual box to remove that variable.
Apache can be screwy with symlinks.

Prevent access to files through ip address - apache 2.4

I have asked a similar question before
Restrict access to directories through ip address
at that time the problem was solved for apache 2.2. Recently I re-installed the OS (to Debian 8) and it comes with apache 2.4.
I want to restrict access to files - when the request comes "by" IP. Mainly if in the browser I try to open http://192.168.252.178/test/image.jpg it should show error - 403 forbidden. Directory test is in www directory of apache. However I should be able to access that image if I type http://www.example.com/image.jpg - considering that example.com points to that test directory.
With apache version 2.2 I would simply put this lines in my default site config file - and the problem was solved
<Files ~ ".+">
Order allow,deny
Deny from all
</Files>
Now, trying the same thing does not work: I am getting 403 forbidden even if I try to open any site by the domain name.
Considering the changes in 2.4 I also tried this, but again getting the the same 403 forbidden when trying to open some site.
<Files ~ ".+">
Require all denied
</Files>
My goal is to prevent any kind of access to directories and files - if they are being accessed through ip address. I have also this lines in my default site's config to prevent the directory access and this works fine.
<Directory /home/username/www>
Options -Indexes
AllowOverride All
Require all granted
</Directory>
So, the question is - how to prevent file access through IP address. Also I need to achieve this by apache config, by htaccess is not a solution for me. And I need to achieve this for all the directories/files inside www recursively, so specifying the exact file names and/or directories is not a solution either.
Thanks
When you use name based virtual hosts, the main server goes away. Apache will choose which virtual host to use according to IP address (you may have more than one) and port first, and only after this first selection it will search for a corresponding ServerName or ServerAlias in this subset of candidates, in the order in which the virtual hosts appear in the configuration.
If no virtual host is found, then the first VHost in this subset (also in order of configuration) will be choosen. More.
I mention this because it will be important you have only one type of VirtualHost directive:
<VirutalHost *:80>
or
<VirtualHost 123.45.67.89:80>
I'll use the wildcard in the example.
You need a directory like /var/www/catchall with a file index.html or similar, as you prefer.
<VirtualHost *:80>
# This first-listed virtual host is also the default for *:80
# It will be used as the catchall.
ServerName 123.45.67.89
# Giving this DocRoot will avoid any request based on IP or any other
# wrong request to get to the other users directories.
DocumentRoot "/var/www/catchall"
<Directory /var/www/catchall>
...
</Directory>
</VirtualHost>
# Now you can add as usuall the configuration for any other VHost you need.
<VirtualHost *:80>
ServerName site1.com
ServerAlias www.site2.com
DocumentRoot "/home/username1/www"
<Directory /home/username1/www>
...
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName site2.com
ServerAlias www.site2.com
DocumentRoot "/home/username2/www"
<Directory /home/username2/www>
...
</Directory>
</VirtualHost>
Debian specific :
For Debian, you ideally put one VHost configuration per file, and put the file in the /etc/apache2/sites-available directory.
Name the files as you like, only the file containing the catchall vhost should be named something like 000-catchall, because they will be read in alphabetic order from the /etc/apache2/sites-enabled directory.
Then you disable Debian's usual default site :
a2dissite 000-default
and you enable the new catchall site and the other VHosts if needed :
a2ensite 000-catchall
An ls /etc/apache2/sites-enabled command should show the catchall as the first of list, if not change its file name so that it will always be the first. Restart Apache: service apache2 restart
Of course you could do all this changes in the original default VHost config file, but I usually prefer keep an original model.

How to route all *.dev to subfolders on vagrant box

I want that every *.dev Host will be routed to my vagrant machine to /var/www/vhosts/*.dev/public, for example my local development environment project1.dev is located in /var/www/vhosts/project1.dev/public
So when I add a new (sub)project into my box, I do not need to change my config.yaml (Vagrant installed via puphpet.com) and reload the machine.
On my computer, I added the following to the hosts file in /private/etc:
192.168.56.101 *.dev
On my VM, I changed my 10-default_vhosts80.conf in /etc/apache2/sites-enabled to:
# ************************************
# Vhost template in module puppetlabs-apache
# Managed by Puppet
# ************************************
<VirtualHost *:80>
ServerName default
## Vhost docroot
DocumentRoot "/var/www/default"
## Directories, there should at least be a declaration for /var/www/default
<Directory "/var/www/default">
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
</Directory>
## Load additional static includes
## Logging
ErrorLog "/var/log/apache2/default_vhost_80_error.log"
ServerSignature Off
CustomLog "/var/log/apache2/default_vhost_80_access.log" combined
## Custom fragment
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/default/$1
</VirtualHost>
<VirtualHost *.dev:80>
ServerName dev
VirtualDocumentRoot /var/www/vhosts/%0
</VirtualHost>
Unfortunately, this doesn't work. Any ideas? I am a beginner in this subject.
I use a proxy auto configuration file. This works on Windows, MacOS and Linux. Easy, flexible and no additional software required. The following example routes all *.dev traffic to your vagrant box:
function FindProxyForURL(url, host) {
if (dnsDomainIs(host, ".dev")) {
return "PROXY 127.0.0.1:8080";
}
return 'DIRECT';
}
When needed, replace 127.0.0.1:8080 with the IP and webserver port of your vagrant box. Store this file somewhere. You can store it locally or let the webserver on your Vagrant-box host the file.
Windows: See here how to use the PAC file on Windows.
MacOS: See here how to use the PAC file on MacOS. You can link to the file using file:///Users/username/path/to/proxy.pac.
Linux: For linux it depends, but I'm sure linux users will be able to Google for their specific situation.
Unfortunately hosts files do not support using wildcards. You have to manually define each and every host to redirect.
Also, your hosts file is at /etc/hosts
In the end, I use dnsmasq to route all .localdev Domains to 127.0.0.1. Note that I am using .localdev instead of just .dev or .local as this seems to cause problem (OS X 10.10) because .dev is a proposed gTLD and .local is used by Apple's Bonjour.
Then I configured Apache by creating and enabling this site:
<VirtualHost *:80>
ServerAlias localhost *.localdev #wildcard catch all
VirtualDocumentRoot /hosts/%1/public
UseCanonicalName Off
<Directory "hosts">
Options FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
(from: http://brunodbo.ca/blog/2013/04/26/setting-up-wildcard-apache-virtual-host-wildcard-dns)

vhosts dont appear to be working on OS X Mavericks Apache installation

I am trying to set up the Apache server which comes with OS X Mavericks with vhosts so that a domain name resolves to my user level document webroot. I have followed this tutorial which guided me through setting up the apache server with php:
http://coolestguidesontheplanet.com/get-apache-mysql-php-phpmyadmin-working-osx-10-9-mavericks/
as well as this one which guided me through setting up the vhosts:
http://coolestguidesontheplanet.com/set-virtual-hosts-apache-mac-osx-10-9-mavericks-osx-10-8-mountain-lion/
Following these tutorials, if I type localhost in my browser it correctly resolves to the system level root (/Library/WebServer/Documents/ folder). If I use localhost/~myusername it correctly resolves to my user level root (/users/myusername/Sites/).
However, whenever I navigate to my domain, I get redirected to the system level root rather than my user level root.
My vhosts file reads as follows:
<VirtualHost *:80>
ServerName localhost
DocumentRoot /Library/WebServer/Documents/
</VirtualHost>
<VirtualHost *:80>
ServerName mydomain.com
ServerAlias www.mydomain.com
DocumentRoot "/Users/myusername/Sites/mydomain"
<Directory "/Users/myusername/Sites/mydomain">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
Any ideas?
Have you enabled Virtualhosts?
NameVirtualHost *:80
And included your vhosts directory
Include <path>/vhosts/*
On a Macbook, you may need to include /private/ at the beginning of any absolute path, so that Apache can read it correctly off the file system.
For others who have the same problem...
It was frustratingly simple - I had missed the "" around the localhost directory.
How annoying!
Try starting apache manually with the -S option to see what the problem might be:
/usr/sbin/httpd -S

Rails: Vhost config for Apache and Passenger

I'm trying to get a simple Rails 4 app deployed on my server which already has Apache2 and is hosting several other sites and services (ie there are several vhost configs under sites-enabled). I've had some problems doing this on my local machine as well as my test server so I'm trying first to get it working on an AWS t1.micro instance with only one vhost config. I've written a script to do most of the heavy lifting for me which is on my github at rails-apache-passenger.
I have two vhost config files in the repo and have tried to get one or the other working. The script just copies over and enables one at a time.
Using the my-ruby-app-basic or the my-ruby-app vhost config I navigate to http://54.xxx.xxx.xxx/my-ruby-app/ but all I see is "The page you were looking for doesn't exist. You may have mistyped the address or the page may have moved." When I go to ttp://54.xxx.xxx.xxx/ I just get the default apache2 page ("It works!").
My /var/www/my-ruby-app/log/production.log shows
I, [2014-01-24T10:47:36.900542 #9612] INFO -- : Started GET "/my-ruby-app" for 80.81.17.94 at 2014-01-24 10:47:36 +0000
F, [2014-01-24T10:47:36.902169 #9612] FATAL -- :
ActionController::RoutingError (No route matches [GET] "/my-ruby-app"):
So clearly I need to modify my routes.rb file, but what am I supposed to change? As you can see from the script in the git repo, it's just the default routes.rb from rails new. I just want to see the default rails app landing page at this point so I'm not sure what to do to the routes.rb file.
Here are the vhost configs
my-ruby-app-basic
#This is the config suggested by the passenger module after it finishes compiling, modified for 'my-ruby-app'
<VirtualHost *:80>
ServerName www.my-ruby-app-host.com
# !!! Be sure to point DocumentRoot to 'public'!
DocumentRoot /var/www/my-ruby-app/public
<Directory /var/www/my-ruby-app/public>
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options -MultiViews
</Directory>
</VirtualHost>
my-ruby-app
#Based on Apache section of Passenger documents
<VirtualHost *:80>
ServerName www.my-ruby-app-host.com
# !!! Be sure to point DocumentRoot to 'public'!
DocumentRoot /var/www/
<Directory /var/www/>
Allow from all
</Directory>
Alias /my-ruby-app /var/www/my-ruby-app/public
<Location /my-ruby-app>
PassengerBaseURI /my-ruby-app
PassengerAppRoot /var/www/my-ruby-app
</Location>
<Directory /var/www/my-ruby-app/public>
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options -MultiViews
</Directory>
</VirtualHost>
Using Apache and Passenger is a short term solution but I want to know how to do it in any case (The long term view is that I want to maintain compatibility with Jruby and just run our app through Tomcat or Glassfish, which will no doubt be another Apache config debacle ;-) )