I've been trying for several days now to set up Django under Amazon Web Services' Elastic Beanstalk. I think the problem I'm hitting is this one:
ERROR - Your WSGIPath refers to a file that does not exist.
I followed the tutorial here and all goes well until the end of Step 6, but I can't for the life of me get anything to display other than the generic Elastic Beanstalk page from Step 5, #2. When I run
./manage.py runserver
on my local machine, everything works as it should, but I can't get that page to deploy. I first tried with a small Django site I wrote myself. It didn't work, so I deleted everything I'd done and tried again, that didn't work, so I deleted all that and tried again with a fresh django install. I tried that a bunch of times fiddling with little things, but I think I'm missing something major.
I added a python.config file as described in this tutorial.
Here's my file structure:
-.git/
-.mysite/
-myapp/
-__init__.py
-models.py
-tests.py
-views.py
-mysite/
-__init__.py
-settings.py
-urls.py
-wsgi.py
-.ebextensions/
-python.config
-manage.py
-mysite.db
-requirements.txt
From my settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mysite.db',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
}
}
Here's python.config:
container_commands: 01_syncdb:
command: "django-admin.py syncdb --noinput"
leader_only: true
option_settings:
- namespace: aws:elasticbeanstalk:container:python
option_name: WSGIPath
value: mysite/wsgi.py
- option_name: DJANGO_SETTINGS_MODULE
value: mysite.settings
- option_name: AWS_SECRET_KEY
value: <This is my secret key>
- option_name: AWS_ACCESS_KEY_ID
value: <This is my access key>
Is there another place I need to define my WSGIPath? Is there a way to do it through the AWS console? Should I just skip EB altogether and use EC2 directly?
From https://forums.aws.amazon.com/thread.jspa?messageID=396656񠵰
The ".ebextensions" directory must be in the root level directory of your application, but from the log output, the directory is instead in the "mysite/.ebextensions" directory. So for example, after following the django tutorial in the docs when you run "git aws.push" your root directory would look like this:
.
├── .ebextensions
│ └── python.config
├── .elasticbeanstalk
│ ├── config
├── .git
├── .gitignore
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── requirements.txt
Instead of this:
.
└── mysite
├── .ebextensions
├── .elasticbeanstalk
├── .git
├── .gitignore
├── manage.py
├── mysite
└── requirements.txt
Find .elasticbeanstalk/optionsettings.your-app-name in your app's root directory. Search for WSGIPath and make sure it's the path you intend. It looks like it defaults to application.py.
I had the same problem ("Your WSGIPath refers to a file that does not exist"), and finally found a solution:
The problem: I was downloading the bundle of the project directly from GitHub ("Download Zip"), which maybe had an improper structure.
The solution: I properly zip the files, without the main folder, using the Compress command. (cf http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.deployment.source.html).
Note: At first, I was searching in the wrong direction, because EB was also showing this message: Error occurred during build: Command 01_migrate failed.. So I though the files, including the *.config, were correctly located.
Solution: using EBCLI
open eb config
For me it showed WSGIPath: application.py
Now Change it to
WSGIPath: my_app/wsgi.py
save and deploy.
Ok, here's what worked for me after trying a million things. You have to run eb update in order to update the environment.
So make sure .elasticbeanstalk/optionsettings.whatever-env has WSGIPath set to what you want it, and make sure .ebextensions/whatever.config has this:
option_settings:
- namespace: aws:elasticbeanstalk:container:python
option_name: WSGIPath
value: whatever/wsgi.py
Then run eb update and it should work. Remember you have to set the alias to make sure your eb command actually works. For example:
alias eb="python2.7 ../AWS-ElasticBeanstalk-CLI-2.6.3/eb/linux/python2.7/eb"
I had the same issue after following AWS's docs to the dot. What I did to avoid it was initialize an application through the EB CLI step by step, without using the command the AWS docs instructed (~/ebdjango$ eb init -p python2.7 django-tutorial), and creating an environment step by step as well. The steps I took in the EB CLI are the following:
Initialize Application
eb init
Select a default region
Enter Application Name (used default by pressing enter)
Confirmed that I am using Python
Selected Python version compatible with my local environment
Set up SSH
Create Environment
eb create
Enter Environment Name (used default by pressing enter)
Enter DNS CNAME prefix (used default by pressing enter)
Select a load balancer type (I selected classic by entering 1)
After Environment is created I use eb config to open EB's config file to confirm that the path to my WSGI is what it should be:
aws:elasticbeanstalk:container:python:
NumProcesses: '1'
NumThreads: '15'
StaticFiles: /static/=static/
WSGIPath: path/to/wsgi.py
If any changes are made, make sure you save the file and confirm that everything is squared up by entering eb open in your terminal to open a browser window using the domain name specified in previous steps.
Related
I'm trying to deploy a Flask app on Google Compute Engine. I have it all configured, but when I try to deploy it with gcloud app deploy, it says ModuleNotFoundError: No module named 'main'. This is my file structure:
└── gpt-redteam-api/
├── app.yaml
├── main.py
└── ...other files
and I am deploying it from inside gpt-redteam-api. Is this a common problem/are there any elementary fixes I’m missing?
For your issue you need to add a custom entrypoint to recognize the main.py
Entrypoint: Optional. Overrides the default startup behavior by executing the entrypoint command when your app starts. For your app to receive HTTP requests, the entrypoint element should contain a command which starts a web server that listens on port 8080.
You need to configure the entrypoint field by the following steps.
This line says to look for the variable named app in the module named main.py:
entrypoint: gunicorn -b:$PORT main:app
You could either rename your app.py to main.py or update this line to:
entrypoint: gunicorn -b:$PORT app:app
For more information follow this doc and refer to this stack question also.
by default ebs uses Dockerrun.aws.json file to deploy. we have a requirement to have multiple dockerrun files, like Dockerrun.aws.json and Dockerrun-staging.aws.json.
Is it possible to make sure deployment uses Dockerrun-Staging.aws.json file instead of Dockerrun.aws.json?
I had the same problem and could not find any documentation on how to provide target file on deploy. I ended up creating separate folders for staging and production then execute the eb deploy on the target environment folder
:docker-run$ tree
.
├── production
│ └── Dockerrun.aws.json
└── staging
└── Dockerrun.aws.json
2 directories, 2 files
I'm just getting started with Django. I like to hack at things, so alongside the polls tutorial I'm also building my own experimental application. It has come to pass that I want to change the name of the experimental application and its associated project.
In the course of working on that, I decided to drop my current database and start over fresh. Something went wrong, I can't remember what. It's been several hours now, making progress here, googling that there.
The situation I now seem to be in is that Django refuses to notice changes in my models.py. Currently, there are no migrations listed for the app when I run manage.py showmigrations, although the app is itself listed.
I have tried deleting the migrations directory, changing the contents of the models.py file, and combinations thereof, and also trying out various manage.py commands that looked promising. So far, nothing has worked.
So, what might I be doing wrong? Remember that I have changed the name of the app, which includes changing the name of directory it is stored in, as well as the name of the database. Search and replace has been performed on the files in the project and app. settings.py has been pored over, but everything I know about seems to match up fine.
Thanks!
I assume you have changed your app name in your settings.py? And when you say you changed your app name, did you start a new app or a new project... meaning, when you start you do this:
django-admin.py startproject myproject
Running startproject gives you the following folder and file structure:
├── manage.py
└── myproject
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
From there, you can run
python manage.py startapp myapp
This will make your folder structure look like this:
├── manage.py
├── my_django15_project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── myapp
├── __init__.py
├── models.py
├── tests.py
└── views.py
From there, you could change your app by changing the folder name 'myapp' to 'mynewapp' and then by modifying your settings.py to have 'mynewapp' listed in your INSTALLED_APPS section.
After doing this you should run
pythonmanage.py makemigrations mynewapp
Verify that it makes the migration files
then run
python manage.py migrate
If you changed the folder myproject to a new name, such as mynewproject, I would suggest to try changing it's name back, then running
django-admin.py startproject mynewproject
then after you do that, update those files accordingly, and copy your myapp folder into the mynewproject folder.
Some other things you may want to check are that your database connectors are correct, and also try restarting your webserver.
If none of this works, you will need to give me some more information, so leave me a comment and let me know
Good Luck
I'm trying to upload my Flask application to AWS however I receive an error on doing so:
Your WSGIPath refers to a file that does not exist.
After doing some digging online I found that in the .ebextensions folder, I should specify the path. There was not a .ebextensions folder so I created one and added the following code to a file named settings.config:
option_settings:
"aws:elasticbeanstalk:container:python":
WSGIPath: project/application.py
the WSGIPath is the correct path to the application.py file so I'm not sure what raises this error. Am I changing the WSGIPath right, is there a better way or is there an issue with something else which causes this to happen? Thanks.
There's a lot of configuration issues that can arise with Flask deployed on AWS. I was running into a similar issue as you, so I can at least show you what I did to resolve the WSGI error.
First, apparently you can do this without the .ebextensions folder (see this post here. and look at davetw12's answer. However, be aware that while this works, I'm not entirely sure that davetw12's conclusion about .ebextensions is correct, based on some of the comments below). Instead, (in the Terminal), I navigated to my project at the same level as my .elasticbeanstalk directory and used the command eb config. This will open up a list of options you can set to configure your beanstalk application. Go down through the options until you find the WSGI path. I notice you have yours set to project/application.py, however, this should not include the folder reference, just application.py. Here is how it looks on my Mac in the terminal (WSGI path is near the bottom).
Note that once you get that set, EB will probably redeploy. That's fine. Let it.
Once you get that set, go into your application.py file and make sure you call your app application. For example, mine looks like this:
from flask import Flask
from flask import render_template
application = Flask(__name__)
#application.route('/')
#application.route('/index')
def index():
return render_template('index.html',
title='Home')
This took away the WSGI path error - although I still had to fix some other issues following this :-) But that is a different set of questions.
If anyone here is doing via AWS Console (GUI), modify the configuration and put your script name in WSGIPath as below.
I'm giving bonus hints if you are newer.
You should match the script name and the Flask object too.
Common mistake: When you're compressing the source code, you need to
select the files and compress, not the folder. (make sure you have the
.py in the root of the zip)
from flask import Flask
application = Flask(__name__)
#application.route("/")
def hello():
return "Hello"
if __name__ == "__main__":
application.run()
I had the same message, but for a very stupid reason.
Apparently, when I cloned the repo to my Windows PC and then pushed back the changes, somewhere along the way Windows changed ".ebextensions" folder to "ebextensions" (dropping the leading ".").
So when I renamed back the folder to ".ebextensions" in the master repo, everything started working again perfectly.
For me the problem was I had misspelled a filename:
I wrote: ..ebextensions/django.conf
When I needed: ..ebextensions/django.config
This cost me about 3 hours of my life today. The trouble was that the AWS error is misleading, because the "WSGIPath" it refers to is not the file above, but some invisible default.
In my case trying many solutions didn't solve the issue but changing WSGIPath from
option_settings:
"aws:elasticbeanstalk:container:python":
WSGIPath: project_name/application_name.py
to
option_settings:
"aws:elasticbeanstalk:container:python":
WSGIPath: project_name.wsgi
worked like a charm. Here is the file structure:
├── manage.py
├── mysite ***
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py ***
├── myvenv
│ └── ...
└── requirements.txt
I'm using Django 1.6.5 with the setting:
DEBUG = True
When I change to DEBUG = False and run manage.py runserver, I get the following error:
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False
I get the same error with the following setting:
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
How can I fix this?
Try
ALLOWED_HOSTS = ['*']
Less secure if you're not firewalled off or on a public LAN, but it's what I use and it works.
EDIT: Interestingly enough I've been needing to add this to a few of my 1.8 projects even when DEBUG = True. Very unsure why.
EDIT: This is due to a Django security update as mentioned in my comment.
Your solution might be to add the original IP and/or hostname also:
ALLOWED_HOSTS = [
'localhost',
'127.0.0.1',
'111.222.333.444',
'mywebsite.example']
The condition to be satisfied is that the host header (or X-Forwarded-Host if USE_X_FORWARDED_HOST is enabled) should match one of the values in ALLOWED_HOSTS.
Make sure it's not redefined again lower down in your settings.py. The default settings has:
ALLOWED_HOSTS = []
From documentation:
https://docs.djangoproject.com/en/1.10/ref/settings/
if DEBUG is False, you also need to properly set the ALLOWED_HOSTS
setting. Failing to do so will result in all requests being returned
as “Bad Request (400)”.
And from here:
https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-ALLOWED_HOSTS
I am using something like this:
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'www.mysite.com']
Use this:
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
If you work in PyCharm, check the Environmental variables for your Django server. You should specify the proper module.settings file
This works for me:
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
If you are using PyCharm
This solution applies only if you are using a different settings.py and have environment variables set
I had the same issue, but in my case the issue was, I was using a different settings.py file than the default (and had commented out my whole original settings.py), though I had it properly configured in my manage.py but in PyCharm I had to configure it as well in my Environment Variables via:
Edit Run Configurations >> Environment Variables
In my case I had split out my settings.py into base.py and development.py in a settings folder. It looked something like:
<name-of-your-project-app>/
├── __init__.py
├── asgi.py
├── settings
│ ├── __init__.py
│ ├── base.py
│ └── development.py
├── urls.py
└── wsgi.py
The problem was much bigger than ALLOWED_HOSTS=... because none of the settings were recognized by python manage.py runserver.
The fix was to configure the DJANGO_SETTINGS_MODULE by running
export DJANGO_SETTINGS_MODULE=decoupled_dj.settings.development
in the command line. I think this tells Django, 'Hey look for my settings in the development.py'
Try
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
A value of '*' will match anything; in this case you are responsible to provide your own validation of the Host header.
I had set ALLOW_HOSTS, INTERNAL_IPS and DEBUG=TRUE
but still got this error.
my problem was i had created a python package which its name
was 'settings' in main app.
and that package name interfered with 'settings.py' file.
I also experienced the same error and found it is happening due to settings file configuration change. You have to configured few things as below mentioned.
Try
In settings.py
ALLOWED_HOSTS = ['*']
In manage.py
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<your-project-name>.settings')
In asgi.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<your-project-name>.settings')
In wsgi.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<your-project-name>.settings')
So in my main directory in my django project, I had a two directories that had the same name so I deleted the settings folder I had and kept the settings.py file that comes with django.
What I had originally
<name-of-your-project-app>/
├── __init__.py
├── asgi.py
├── settings
│ ├── __init__.py
│ ├── base.py
│ └── development.py
├── settings.py
├── urls.py
└── wsgi.py
What I had afterwards
<name-of-your-project-app>/
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
Make sure the name of the directory is the same that you are mentioning in the INSTALLED_APPS. These are the solution to errors sometimes.
Faced the same error when using a .env file in development in a local setup on my computer which I didn't copy on the production server. As soon as I added the .env file on the production server the error was resolved. I have also added the server's IP Address to the allowed_hosts list on the settings file.
I also experienced this cmderror. After trying all the answers on here, I couldn't still figure out the problem, here is what I did:
Cd into the project directory. e.g cd project-dir
I migrated. e.g python manage.py migrate
I created a super user. e.g python manage.py createsuperuser
Enter the desired info like username, password, email etc
You should get a "super user created successfully" response
Now run the server. E.g python manage.py runserver
Click on the URL displayed
The URL on your browser should look like this, 127.0.0.1:8000/Quit
Now edit the URL on your browser to this, 127.0.0.1:8000/admin
You should see an administrative login page
Login with the super user info you created earlier on
You should be logged in to the Django administration
Now click on "view site" at the top of the page
You should see a page which shows "the install worked successfully..... Debug = True"
Voila! your server is up and running
Just simply comment out the line: ALLOWED_HOSTS = [...]