Django and AWS: Configure statics in Elastic Beanstalk
Django is, in terms of documentation, one of the most complete projects than I have ever worked. Any weird issue wich solution is not inside the official documentation, is likely to be amongs either Medium or StackOverFlow or any other well-known blog of technology in the enormous jungle of internet.
By the same way, Amazon Web Services (AWS) have an extended and helpful documentation which include tutorials, API references, examples and thousands of examples than help you to put in practice which you have learned.
Nevertheless, sometimes you have to face problems which solution is neither easy to find nor understand. Almost Always, my problems are because the second one.
In the last year I have been involved in a Django project (I will talk more about it in next posts) which is deployed in AWS through Elastic BeanStalk(AEB). After a couple of hours reading the AWS documentation I finally reach to manage the entire project without many drawbacks. Nevertheless, configuring the the Django’s admin was not as easy as I though: The static files were not properly configured and consequently, the admin page was rendered without styles.
I was browsing across the internet for hours looking for the reason the static files were not served by AEB, and after a while, I was able to configure it.
Requirements
Configure the static folder in the django settings
- Define the static url in the project
settings.py
- Very important, define the
django.contrib.staticfiles
in youINSTALLED_APPS
list.
INSTALLED_APPS = [
...
...'django.contrib.staticfiles',...
...]STATIC_URL = ‘/static/’
NOTA: The
STATIC_ROOT
variable is absolutely ignored by Elastic Beanstalk. I realised about that after thousands and thousands of deployments.
- Create the file `.ebextensions/django.config` to configure the eb-extension that will execute the scripts to migrate the model changes and collect the static files into the EC2 instance in the deployment process.
packages:
yum:
git: []
postgresql95-devel: []
libjpeg-turbo-devel: []container_commands:
01_migrate:
command: “source /opt/python/run/venv/bin/activate && python manage.py migrate — noinput”
leader_only: true02_collectstatic:
command: “source /opt/python/run/venv/bin/activate && python manage.py collectstatic — noinput”
leader_only: true
- Deploy your application with the EB-CLI by executing the following instruction from the root folder
eb deploy
Configure the static files in Elastic Beanstalk
By default, the settings.py
file is defined in the appname
folder, and your folder structure is likely to be similar to this:
...├── manage.py
├── runtime.txt
├── appname
│ ├── settings.py
│ ├── templates
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
├── staticfiles
...
Since thedjango.crontib.staticfile
is defined in your INSTALLED_APPS
and the STATIC_ROOT
variable is not defined, the static files will be generated into a folder named staticfiles
created in the root folder. Just like the above folder structure.
In this case, you have to modify the AEB configuration so that the proxy server can render the static files.
To do that, go to the AEB dashboard → configuration → Software and modify the static’s path. The static files configuration in the Elastic Beanstalk application should be similar to this:
As you can see, the path /static/
have a Directory value of /staticfiles/
. and Yeah!!. the static files are finally rendered.
All was working well until I decided to split the settings.py
file in several modules with the django-split-settings library. Then, the new folder estructure had changed to this:
...├── manage.py
...
├── appname
│ ├── settings
│ │ ├─--components
│ │ ├──- static.py
│ │ ├──- common.py
...
...
│ │ └── __init__.py│ ├── staticfiles
│ └── __init__.py
...
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
...
Now, the settings is a python’s package and it is splitted by concepts in several files.
After running the script to collect the statics.. Sorprise!!!:
The staticfiles
folder has been created inside the appname
folder.
I do not know what is exactly the technical reason of this. Maybe in the future, after read deeply the Django API, I might create an new entry explaining the reason. But not today.
Knowing that, I had to chage the configuration of static files in the AEB application:
And Oulá!.. everything returned to normality.
Thank you for read me and I hope it can help you.
Cheers!.