25

I am trying to put up a simple django app on elastic beanstalk. I thought I had the static parts of the app figured out as it works with heroku and on a server that was set up manually. In debugging I even checked in a pushed the static files in the static directory to try to simplify things. The mapping seems very strange in that it doesn't seem to follow the STATIC_ROOT.

My relevant configs: settings.py

PROJECT_ROOT = os.path.abspath(os.path.dirname(__name__))
STATIC_ROOT = os.path.join(PROJECT_ROOT,'static/')
STATIC_URL = '/static/'
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

urls.py

(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),

LOGS:

[Wed Dec 26 15:39:04 2012] [error] [client 10.29.203.20] File does not exist: /opt/python/current/app/css, referer 10.29.203.20 - - 
[26/Dec/2012:15:39:04 +0000] "GET /static/css/styles.css HTTP/1.1" 404 329 "http://" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.101 Safari/537.11"
Omni
  • 313
  • 1
  • 3
  • 9

9 Answers9

34

Just so you guys know, namespace for static files in recent versions of EBS, changed to aws:elasticbeanstalk:environment:proxy:staticfiles, like this:

option_settings:
  aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static
Lucero del Alba
  • 470
  • 1
  • 5
  • 7
  • Yes this worked for me as well for the new Amazon Linux 2 instances https://docs.amazonaws.cn/en_us/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-environmentproxystaticfiles – Simone Jul 13 '20 at 09:20
  • 1
    This works for me, according to the newly updated documentation of the elastic benstalk for Django, I updated Django.config file inside the .ebextensions folder – Mayur Gupta Oct 15 '21 at 06:46
25

I came across the same problem today, and I realized that I forgot this option in the .ebextensions/.config file. Make sure you have it too

option_settings:
  - namespace: aws:elasticbeanstalk:container:python:staticfiles
    option_name: /static/
    value: static/
Dharman
  • 30,962
  • 25
  • 85
  • 135
osamu
  • 983
  • 1
  • 9
  • 13
  • 13
    Just to make it crystal clear: The value `static/` refers to the folder your static files are in. In my case that was `app/static`, which left me wondering why `static/` wasn't working. – Felix Sep 16 '13 at 03:37
  • 2
    I got a syntax error... This seems to be the new syntax: `option_settings:` `"aws:elasticbeanstalk:container:python:staticfiles":` `/static/: "app/static/"` I don't think this is the optimal solution though, since it seems app-specific.. – Anis Abboud Sep 09 '16 at 17:19
  • 1
    Will this work if there are several apps each with their own `static` directory? – MadPhysicist Jan 22 '17 at 22:14
  • HELP PLEASE! how should I do the same with a multi container Django application on elastic beanstalk?? I am mostly concerned with this line ```namespace: aws:elasticbeanstalk:container:python:staticfiles``` – Mwibutsa Floribert Aug 10 '20 at 16:38
18

To support multiple apps and do this you need to run collectstatic

Settings.py

STATIC_ROOT = os.path.join(BASE_DIR, "static")

Make sure you have a folder called "static" in your root

In your ebs config file eg. (02_python.config or similar)

option_settings:
    ...
    "aws:elasticbeanstalk:container:python:staticfiles":
        /static/: "static/"

Then before you upload to ebs run python manage.py collectstatic

This collects all the static files in one folder which you have already pointed to in your config.

Then you can run eb deploy like normal

Opptionally if you don't want to commit the static files to your source control twice and want the server to do this for you add this to your config

container_commands:
01_collectstatic:
    command: "source /opt/python/run/venv/bin/activate && python manage.py collectstatic --noinput"

So your file should look something like this:

container_commands:
01_collectstatic:
  command: "source /opt/python/run/venv/bin/activate && python manage.py collectstatic --noinput"


option_settings:
    "aws:elasticbeanstalk:container:python":
      WSGIPath: app/wsgi.py
    "aws:elasticbeanstalk:container:python:staticfiles":
      /static/: "static/"

This will run collect static for you when you run eb deploy

  • with this in, static files load now but the container_commands entry I get: '.ebextensions/django.config' - Contains invalid key: '01_collectstatic'. groking the documentation it's not clear how these are processed. however these examples are helping: https://github.com/awsdocs/elastic-beanstalk-samples/blob/9720e38e9da155752dce132a31d8e13a27364b83/configuration-files/aws-provided/instance-configuration/awslogs-change-frequency.config#L56 – JohnZaj Sep 21 '20 at 00:10
13

If your environment uses a platform branch based on Amazon Linux 2, the right settings for .config file inside .ebextensions folder

aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static

Inside your project settings.py you should have:

STATIC_URL = '/static/'
STATIC_ROOT = 'static'
Ayser
  • 1,035
  • 12
  • 15
7

For me, the problem was having

STATIC_ROOT = os.path.join(os.path.dirname(__file__), 'static')

Instead, I changed it to

STATIC_ROOT = 'static'

Also, my .conf file has

option_settings:
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "static/"
Jorjon
  • 5,316
  • 1
  • 41
  • 58
2

All previous answers didn't help me This works for me.

Basically I created two steps inside .ebextensions

01_django.config

container_commands:
    01_migrate:
        command: "source /opt/python/current/env && source /opt/python/run/venv/bin/activate && cd /opt/python/current/app && python manage.py migrate --noinput"
        leader_only: true
    02_touch_superuser:
        command: "source /opt/python/current/env && source /opt/python/run/venv/bin/activate && cd /opt/python/current/app && python manage.py touch_superuser"
        leader_only: true
option_settings:
    aws:elasticbeanstalk:container:python:
        WSGIPath: config/wsgi.py
        NumProcesses: 2
        NumThreads: 10
    aws:elasticbeanstalk:application:environment:
        STAGING: 1
        DJANGO_SETTINGS_MODULE: config.settings.production
    aws:elasticbeanstalk:container:python:staticfiles:
        "/static/": "htdocs/static/"
        "/media/": "htdocs/media/"

config/wsgi.py Could be a different path in your project

02_collec_static.config

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/10_collect_static.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      set -xe

      source /opt/python/current/env
      source /opt/python/run/venv/bin/activate
      cd /opt/python/current/app && python manage.py collectstatic --noinput

      echo "Statics collected...!!"

An important thing, you settings/*.py should match with your static path that EBS serves, in my case this is my config.

...
PROJECT_PATH = dirname(dirname(dirname(__file__)))
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'htdocs/media')
STATIC_ROOT = os.path.join(PROJECT_PATH, 'htdocs/static')
...
2

Add a file name static-files.config under .ebextensions, and add below content:

option_settings:
  aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static

That works for me. I am using django2.2 + python 3.7

For more detail please check:https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environment-cfg-staticfiles.html#environment-cfg-staticfiles.namespace

quinn li
  • 21
  • 2
  • BTW, my settings is like: STATIC_URL = '/static/' STATIC_ROOT = 'static' # STATIC_ROOT = os.path.join(BASE_DIR, "static") # STATICFILES_DIRS = ( # os.path.join(BASE_DIR, "static"), # ) – quinn li Apr 22 '22 at 06:05
1

I did the following to fix static path in beanstalk

STATIC_URL = '/static/'

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

option_settings:
  ...
  ...
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "static/"
SuperNova
  • 25,512
  • 7
  • 93
  • 64
1

I struggled for quite a while on that, thinking that the issue was with :

option_settings:
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "static/"

But actually my issue was with the other commands in the xxx.config file. basicaly, make sure the other lines are correct.

If you want to know my personal setup, I used the settings file shown above and I added the static directory in the root of my project. For the settings.py file here is what I had for the static_url and root :

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = 'static'

Hope it helps !