'Not able to create django superuser in aws beanstalk either through container command or manage.py

I have been stuck to a bottleneck which I have tried to resolve using official docs and other answers here in stackoverflow but still not able to create django superuser programatically in the beanstalk environment.

Current state - a. Application is getting deployed smoothly and I am able to access database from my UI application. basically the entry is getting made in some other table that i have in application.

How I have tried to create superuser -

a. By passing container commands -

Option 1-

container_commands:
  01_migrate:
    command: "django-admin.py migrate"
    leader_only: true
  02_collectstatic:
    command: "django-admin.py collectstatic --noinput"

commands:
  super_user:
    command: "source /opt/python/run/venv/bin/activate && python <appname>/createuser.py"
    leader_only: true

  option_settings:
  "aws:elasticbeanstalk:application:environment":
    DJANGO_SETTINGS_MODULE: "<Appname>.settings"
    PYTHONPATH: "/opt/python/current/app:$PYTHONPATH"

In the logs - I didn't see it trying to run the custom command.

Option 2 -

container_commands:
  01_migrate:
    command: "django-admin.py migrate"
    leader_only: true
  02_collectstatic:
    command: "django-admin.py collectstatic --noinput"
  03_createsuperuser:
    command: "source /opt/python/run/venv/bin/activate && django-admin.py createsuperuser"

  option_settings:
  "aws:elasticbeanstalk:application:environment":
    DJANGO_SETTINGS_MODULE: "<appname>.settings"
    PYTHONPATH: "/opt/python/current/app:$PYTHONPATH"

For this, I created a createsuperuser.py file under /management/commands/ following the structure of init.py in both folders and one createsuperuser.py under commands -

from django.core.management.base import BaseCommand
from django.contrib.auth.models import User


class Command(BaseCommand):

   def handle(self, *args, **options):
      if not User.objects.filter(username="admin").exists():
          User.objects.create_superuser("admin", "[email protected]", "admin")

On this, I got a following message from logs -

Superuser creation skipped due to not running in a TTY. You can run `manage.py createsuperuser` in your project to create one manually.    

My queries are -

  1. why I am not able to create a superuser from command line of my virtual env? In that I am getting a message like this -

    raise ImproperlyConfigured("settings.DATABASES is improperly configured. " django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

A bit weird considering makemigrations command is working fine.

And when I echo $DJANGO_SETTINGS_MODULE, i get the right setting

appname.settings

Let me know where I am going wrong in create superuser thing?



Solution 1:[1]

I solved this problem recently with one of my sample app deployment in beanstalk. I mostly followed the official documentation from this link

  1. In your django app folder create python package 'management'
  2. create another package inside management package 'commands'
  3. create a python file in commands package mysuperuser.py

    import os
    from django.core.management.base import BaseCommand
    from django.contrib.auth.models import User
    
    class Command(BaseCommand):
        def handle(self, *args, **options):
            if not User.objects.filter(username='myuser').exists():
                User.objects.create_superuser('myuser',
                                              '[email protected]',
                                              'mypassword')
    
  4. In your django-migrate.config file, add a second command

    02_create_superuser_for_django_admin: command: "python manage.py mysuperuser" leader_only: true

  5. do python manage.py collectstatic and eb deploy.

Doing this created the superuser for me.I didn't have to add any PYTHONPATH as described in some answers available online.

Solution 2:[2]

Your custom file is named "createsuperuser.py" that's the same as the Django command, and that collision is what's causing the issue. Use "createsu.py" for the file name, then be sure to change the config file to also use "createsu."

Solution 3:[3]

I spent ages working out how to do this and this is by far the simplest & most secure way. Create the following file .platform > hooks > postdeploy > 01_migrate.sh and input the below:

#!/bin/bash

source /var/app/venv/*/bin/activate && { python migrate.py createsuperuser --noinput; }

You can then add DJANGO_SUPERUSER_PASSWORD, DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAIL to the configuration section of the application environment and it will know these are to be used as we have specified --noinput.

Then add the below to the folder .ebextentions > django.config . This just gets round permission issues in running 01_migrate.sh

container_commands:
    01_chmod1:
         command: "chmod +x .platform/hooks/postdeploy/01_migrate.sh"

That will create your superuser in a secure way, with the same logic you can also run migrations and collect static by adding to the 01_migrate.sh file.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Deepesh Pandey
Solution 2
Solution 3 Chalist