Yesterday, I created this post: DjangoRestFramework browsable api looks different locally vs when deployed on server?
Basically, when I did python manage.py runserver
, this showed up:
But after I deployed it to AWS (eb deploy
), this is what I see when I access the site:
The answer to the post above mentioned that it is because my static files were missing. So I searched how to deploy static files on AWS and came across this tutorial: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-django.html#python-django-update-app
Under the "Create a Site Administrator" section, it mentions that in order to serve static files, I must first define STATIC_ROOT
in settings.py
(so I did: STATIC_ROOT = os.path.join(BASE_DIR, "ebdjangoapp/static/")
) and then I did eb deploy
. However, the site still looks the same as the 2nd image (without static files). I then tried doing python manage.py collectstatic
(this created the static folder with the rest_framework
directory inside it, containing the css
files etc.) and then did eb deploy
again but the site stil looks the same as the 2nd image.
How come the static files still aren't showing up?
Note, I searched around and came across this post: Django app deployment not loading static files and the answer says:
"You then need to serve settings.STATIC_ROOT
at settings.STATIC_URL
via your web server of choice, very commonly nginx as a reverse proxy behind your Apache-mod_wsgi app server."
But I have no idea how web servers (nginx, reverse proxy, Apache-mod_wsgi) works. I have a Django app I run locally with python manage.py runserver
, and I have AWS elastic beanstalk. I deploy my Django app to AWS by doing eb deploy
. What steps do I need to take in order for the static files to appear on deployment (assuming I don't know how to configure nginx, reverse proxy etc.).?
Using the collectstatic command, Django looks for all static files in your apps and collects them wherever you told it to, i.e. the STATIC_ROOT . In our case, we are telling Django that when we run python manage.py collectstatic , gather all static files into a folder called staticfiles in our project root directory.
There is definitive guide about deploying a django app to AWS Elastic Beanstalk from RealPython - here it is. It has whole section about static files and how to configure it with eb and you don't need to know anything about nginx/apache etc.
Basically you should define container_commands
in your eb config, these commands will be executed after application deploy is finished. For example migrate
and collectstatic
, so this is an example of such section in eb config file:
container_commands:
01_migrate:
command: "source /opt/python/run/venv/bin/activate && python iotd/manage.py migrate --noinput"
leader_only: true
02_collectstatic:
command: "source /opt/python/run/venv/bin/activate && python iotd/manage.py collectstatic --noinput"
option_settings:
"aws:elasticbeanstalk:application:environment":
DJANGO_SETTINGS_MODULE: "iotd.settings"
"PYTHONPATH": "/opt/python/current/app/iotd:$PYTHONPATH"
"ALLOWED_HOSTS": ".elasticbeanstalk.com"
"aws:elasticbeanstalk:container:python":
WSGIPath: iotd/iotd/wsgi.py
NumProcesses: 3
NumThreads: 20
"aws:elasticbeanstalk:container:python:staticfiles":
"/static/": "www/static/"
Pay attention to aws:elasticbeanstalk:container:python:staticfiles
part.
And also you should define this part in your django settings file:
STATIC_ROOT = os.path.join(BASE_DIR, "..", "www", "static")
STATIC_URL = '/static/'
I copied this example almost entirely from article above, you should really check it, it's awesome.
UPD: how to debug missing staticfiles. I usually do this (it involves sshing to your eb instance):
django.contrib.staticfiles
is included in my INSTALLED_APPS
./static/js/somefile.js
STATIC_URL
is the same e.g. /static/
.STATIC_ROOT
and check that this folder actually contains your static files in production server.option_settings
section in config)Also you can try to collect static into /static
dir on your production server (it's where eb looks for them by default). If all of a sudden it starts working - it means that your setting failed to override default one and you should check where else it was defined.
I hope these steps will help you to find right direction.
This is what worked for me.
Remove any staticfiles directives from .config
files. Find Static Files section under the Software Configuration. The left column is each of your /static/
url. The right is your static folder relative to your parent directory.
Make sure your STATIC_ROOT
setting matches the value on the right. Don't forget the trailing /
.
Pasting my settings anyway.
STATIC_URL = '/static/'
STATICFILES_DIRS = ('assets',)
STATIC_ROOT = os.path.join(BASE_DIR, '..', 'www', 'static')
And this is what my folder structure looks like relative to the settings files
project/
├── __init__.py
├── settings
│ ├── base.py
│ ├── __init__.py
│ ├── local.py
│ ├── production.py
wsgi.py
, urls.py
are located in project
folder. www
folder is one level above project
folder.
Hope this saves your Sunday at least.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With