Exposing a WSGI app from a Docker container - flask

I have a VM running on Google Compute Engine hosting a Flask application served by Apache/WSGI. This application has to be accessible on the Internet via www.my_application.com.
What is the best way to expose the application through WSGI when inside a Docker container?
Is there a specific docker run command to use?
Does my_application.conf need to be modified?
Anything else to know/to do?
Below is my_application.conf:
<VirtualHost *:80>
ServerName www.my_application.com
WSGIDaemonProcess my_application user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/my_application/application.wsgi
ErrorLog /var/log/my_application.log
<Directory /var/www/my_application>
WSGIProcessGroup my_application
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>

This may or may not be that relevant to you, but I made a public (and open source) Docker image with all the bells and whistles that you can use to build a Python Flask web application.
It has uWSGI for running the application, Nginx to serve HTTP and Supervisord to control them, so you don't have to learn how to install and configure all those to build your Python Flask web app.
And Google Compute Engine can run Docker: https://cloud.google.com/compute/docs/containers
It seems like uWSGI with Nginx is one of the more robust (and with great performance) ways to deploy a Python web app. Here are the benchmarks: http://nichol.as/benchmark-of-python-web-servers.
There are even some template projects you can use to bootstrap your own. And also, you don't have to clone the full project or something, you can just use it as a base image.
Docker Hub: https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
GitHub: https://github.com/tiangolo/uwsgi-nginx-flask-docker

Related

SOAP webservice with spyne, django and apache

I have a django based website deployed with apache and mod_wsgi.
I need to develop a SOAP based webservice and to host it with my django project, using the same port (80).
So I've read about spyne:
http://spyne.io/docs/2.10/manual/02_helloworld.html?highlight=django
Seems like it fits my needs. I just couldn't find how to deploy it with apache.
Ultimately you are going to need to end up with:
...
application = WsgiApplication(app)
That is, a WSGI script file which constructs your application and exposes it as application and not wsgi_app as the docs say to use.
Then configure mod_wsgi something like:
WSGIDaemonProcess soapapp
WSGIScriptAlias /suburl /some/path/soapapp.wsgi \
process-group=soapapp application-group=%{GLOBAL}
<Directory /some/path/>
<Files soapapp.wsgi>
# Order allow,deny
# Allow from all
Require all granted
</Files>
</Directory>
That is, create a separate daemon process group for this application. Mount it at a sub URL and delegate it to run in the separate daemon process group rather than in whatever process your Django application is. Also ensure you set up access rights so Apache knows it is allow to host the WSGI application from where it exists.
You would then access the SOAP service at that sub URL.

How to Deploy Django project on amazon AWS or other server

I am digging arround from some days and i can not figure out how to deploy a Django Project.
I have a Amazon AWS EC2 machine running.
I started the project on my laptop, then i configured and installed Virtualenv on AWS EC2 and all the requeriments.
This machine has Apache2 and libapache2-mod-wsgi and mysql installed.
When i do the command python manage.py runserver there are NO errors! I did the syncdb and everything is ok.
But a can not see the page in my browser.
Apache config:
File: /etc/apache2/sites-enabled/test_site.com.conf
WSGIScriptAlias / /home/ubuntu/server/workspace/proj/proj/wsgi.py
WSGIPythonPath /home/ubuntu/server/workspace/proj/
<Directory /home/ubuntu/server/workspace/proj/proj>
<Files wsgi.py>
Order deny,allow
Require all granted
</Files>
</Directory>
Alias /static/ /home/ubuntu/server/workspace/proj/static/
<Directory /home/ubuntu/server/workspace/proj/static>
Require all granted
</Directory>
How can i Deploy my Django?
Thanks,
Ricardo
I found a way to solve my problem.
For new comers, with a similar problem, take a look at this page Deploy django in Apacha2 server and mod wsgi
You can use this script that I wrote:
Safely deploy your Django app in less 1 minute!
Instructions
Installing the DeployDjango script
$ wget https://raw.githubusercontent.com/yask123/DeployDjango/master/deploydjango.sh && chmod +x deploydjango.sh
From your Django App’s root directory (Where manage.py file exists).
$ sudo ./deploydjango.sh project_name
Done!
Visit http://ip-address-of-your-instance to see your web app live!

Deploying Django on Apache and WSGI

Although I have found a bunch of tech support to deploy Django over Apache using WSGI but infact they all have confused me unfortunately, and I couldn't get the Django running. I hope this to be real easy job but being a new comer I am facing difficulties.
I have two Django projects namely website1 and website2 inside my /home/zia/Documents/Codes/Django/website1 and ..../website2 dir, respectively. The folder containing settings.py file is root/ inside the /website1 and /website2 dir.
Apache, mod_wsgi everything is installed as required. How to edit apache2.conf and wsgi.py file to keep these two projects running over port 8080 and 8081?
I am struggling with this issue for past few days and have tried all the following websites.
link1,link2,link3,link4
UPDATE1:
I have followed the following approach right from the beginning to make things going well but found myself in some new issues. Kindly guide me where I am wrong.
Installing mod-wsgi and apache2:
sudo apt-get install libapache2-mod-wsgi && sudo apt-get update && sudo apt-get install apache2
Edit the apache2 port to 8083, instead of 80 by altering file "/etc/apache2/ports.conf": Listen 8083
Add the following line into "/etc/hosts" file: 160.75.133.175 160.75.133.175
Edit the following code in the "/etc/apache2/apache2.conf" file:
<Directory />
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
Create a file inside "/etc/apache2/sites-available/" dir with name "sql_api.conf":
<VirtualHost *:8083>
ServerAdmin zia#gmail.com
ServerName 160.75.133.175
ServerAlias http://160.75.133.175
<Directory /home/zia/Documents/Codes/Django/sql_api/ >
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /home/zia/Documents/Codes/Django/sql_api/root/wsgi.py
WSGIDaemonProcess 160.75.133.175 user=www-data group=www-data threads=25 python-path=/home/zia/Documents/Codes/Django/sql_api/root/:/usr
WSGIProcessGroup 160.75.133.175
ErrorLog /home/zia/Documents/Codes/Django/sql_api/root/error.log
</VirtualHost>
Run the following commands being in "/etc/apache2/sites-available" dir: sudo a2enmod wsgi && sudo a2ensite sql_api.conf && sudo service apache2 restart
Open http://160.75.133.175:8083/ but getting the following error:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at zia#gmail.com to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log.
Apache/2.4.7 (Ubuntu) Server at 160.75.133.175 Port 8082
NOTE: When I am making a Django project in /var/www/ dir and then doing the same approach then working just fine! I think because I am trying to access /home/zia/.... dir, there is this issue. Anyways, this is just a guess. I would appreciate your help.
Thanks to everyone. Finally found a working procedure. Follow the following steps in order:
Installing mod-wsgi and apache2:
sudo apt-get install libapache2-mod-wsgi && sudo apt-get update && sudo apt-get install apache2
Edit the apache2 port to 8083, instead of 80 by altering file "/etc/apache2/ports.conf": Listen 8083
Add the following line into "/etc/hosts" file: 160.75.133.175 160.75.133.175
Edit the following code in the "/etc/apache2/apache2.conf" file:
<Directory />
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
Create a file inside "/etc/apache2/sites-available/" dir with name "sql_api.conf" (make as many .conf files you want with different names, each serving different website):
<VirtualHost *:8083>
ServerAdmin zia#gmail.com
ServerName 160.75.133.175
ServerAlias http://160.75.133.175
<Directory /home/zia/Documents/Codes/Django/sql_api/ >
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /home/zia/Documents/Codes/Django/sql_api/root/wsgi.py
WSGIDaemonProcess 160.75.133.175 user=www-data group=www-data threads=25 python-path=/home/zia/Documents/Codes/Django/sql_api/root/:/usr
WSGIProcessGroup 160.75.133.175
ErrorLog /home/zia/Documents/Codes/Django/sql_api/root/error.log
</VirtualHost>
Add the following lines in the wsgi.py file inside "/home/zia/Documents/Codes/Django/sql_api/root/": sys.path.append('/home/zia/Documents/Codes/Django/sql_api/root')
sys.path.append('/home/zia/Documents/Codes/Django/sql_api')
Run the following commands being in "/etc/apache2/sites-available" dir: sudo a2enmod wsgi && sudo a2ensite sql_api.conf && sudo service apache2 restart
Open http://160.75.133.175:8083/
you should probably just start over if you made a bunch of changes to your Apache config. I'm most familiar with setups under Ubuntu.
What you need to look to do is setup both sites under apache as a virtual host. After installing apache there is a folder called sites-available and sites-enabled they should contain the virtual host files with the names of your website projects. Each virtual host will point to whereever your .wsgi file is located. these virtual hosts typically listen under the same port number (as Daniel mentioned above) but serve whichever app is requested based on the domain name. noobmovies.com google.com ect...
how to setup a virtual host with apache is pretty well explained here. this assumes you're using ubuntu though.
https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-virtual-hosts-on-ubuntu-14-04-lts
your virtual host (the file should be named after your domain exp... noobmovies.com) and will look something like this...
**<VirtualHost *:8080>
ServerAdmin your_admin_email#gmail.com
ServerName www.yourdomain.com
ServerAlias yourdomain.com
<Directory /home/path/your/project/ >
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /home/path/your/project/app/wsgi.py
WSGIDaemonProcess yourdomain.com user=www-data group=www-data threads=25 python-path=/path/to/your/project/app/:/path/to/python/virtual/host/site-packages
WSGIProcessGroup yourdomain.com
ErrorLog /path/to/your/app/error.log
</VirtualHost>**
keep in mind the WSGIDaemonProcess is only if you're running your app using virtualenv (which you should). this tells apache where python is that should be used to read the wsgi app/run django app.
So if you're using ubuntu or linux you may just want to uninstall apache and reinstall then just follow the digital ocean instructions to get setup.

Django 1.7 on AWS Elastic Beanstalk - App not running, only see "Index Of /"

I'm trying to deploy this repo to Elastic Beanstalk: https://github.com/jordanmessina/test_beanstalk/tree/5e9a919d991adf22bce1a9b8f6c1515e83b1babb with this configuration: 64bit Amazon Linux 2014.09 v1.0.9 running Python 2.7
I'm getting the following error on deployment:
ERROR: [Instance: i-2eb19dc2 Module: AWSEBAutoScalingGroup ConfigSet: null] Command failed on instance. Return code: 1 Output: [CMD-AppDeploy/AppDeployStage0/EbExtensionPostBuild] command failed with error code 1: Error occurred during build: Command 01_syncdb failed.
When I go to the webpage after deployment, all I see is: Index of /
Is there something wrong with my configuration file?
UPDATE
I made some changes and managed to get the app running and 500ing (progress).
I've poked around on the instances the code is deployed to. I've narrowed the issue down to the mod_wsgi pythonpath that's setup. Here's the configuration:
LoadModule wsgi_module modules/mod_wsgi.so
WSGIPythonHome /opt/python/run/baselinenv
WSGISocketPrefix run/wsgi
WSGIRestrictEmbedded On
<VirtualHost *:80>
Alias /static/ /opt/python/current/app/static/
<Directory /opt/python/current/app/static/>
Order allow,deny
Allow from all
</Directory>
WSGIScriptAlias / /opt/python/current/app/webapp/beanstalk/wsgi.py
<Directory /opt/python/current/app/>
Require all granted
</Directory>
WSGIDaemonProcess wsgi processes=1 threads=15 display-name=%{GROUP} \
python-path=/opt/python/current/app:/opt/python/run/venv/lib/python2.7/site-packages user=wsgi group=wsgi \
home=/opt/python/current/app
WSGIProcessGroup wsgi
</VirtualHost>
I also found the logs for the httpd process (standard /var/log/httpd/error_log for future reference) and was tailing them to see what the issue was. The problem was an ImportError with beanstalk.settings (because it's not on the path).
Now I'm trying to think of a sane way to keep my app structure (webapp directory in the root containing my django app) and update the python path for mod_wsgi so this thing works...I'm very frustrated with the opinionated app structure that Elastic Beanstalk is trying to push on me. Any suggestions would be great!
You can't have the DB locally on elastic beanstalk as you are attempting. EB is meant just as an application container, what you have there will try and setup SQLite on the system, which beanstalk isn't gonna let you do.
You need to configure Django to point to some DB off the beanstalk, there is no DB on that instance and your Django config doesn't seem to have any DB configured on it as you seem to just be trying to use the included SQLite DB, which I'd imagine they don't let you install that on beanstalk, so why not try configuring an another DB or using no DB at all, if possible.
I'd spin up a small RDS instance and configure my Django app to tie into that. That should allow you to sync the DB and get started. It also might be a matter of SQLite not being on the system, so you'd have to configure EB to install that if it's even possible.

Django project doesn't show up with Apache and mod_wsgi

I've installed Apache and mod_wsgi on windows xp service pack 3 and added these line to my httpd.conf :
WSGIScriptAlias / "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo/wsgi.py"
WSGIPythonPath "C:/Documents and Settings/X/My Documents/Downloads/Foo"
<Directory "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
but when I open localhost on my firefox, it shows Apache's It Works! message, what should I do to run my project on localhost ?
EDIT :
I checked and recognized that my project's path is not included in PYTHONPATH. Isn't the line WSGIPythonPath ... expected to add the address to PYTHONPATH ?
Alright, so my setup is in linux so this is not tested on windows, but:
I did not see your LoadModule statement
File: httpd.conf
LoadModule wsgi_module modules/mod_wsgi.so
modwsgi wont work without that.
Also: the your grant statement seems a bit suspicious.
In the wsgi configuration guide suggests using a Directory directive for allowing this access to your mod_wsgi application.
<Directory "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo/">
Order allow,deny
Allow from all
</Directory>
Finally:
Make your life easy down the road.
configure apache in worker mode
configure mod_wsgi in daemon mode.
profit
Might I suggest watching this PyCon talk Making Apache suck less for hosting Python web applications from 'the-man' Graham. I wish I knew all of that stuff years ago.
Note: To figure out if you have apache in mpm worker mode.
httpd.exe -V
look for the "Server MPM" value of worker.
Django runs on port 8000 so you'll want to do two things. First, you need to run the server by entering into your console python manage.py runserver. Second, you need to direct your browser to localhost:8000.
As an aside, you don't need Apache to run a simple, local development environment. Django has its own server built in that you can leverage.