pythondjangoshelldockerfabric

Create django super user in a docker container without inputting password


I am tring to createsuperuser in a django docker container with fabric.

To create the super user in django, I need run this in a django interactive mode:

./manage.py createsuperuser

And because I want to make it run in a fabric script, so I find this command could avoid inputing password

echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'pass')" | ./manage.py shell

Then I put this together with "docker exec" to run it in my django container

docker exec container_django echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'pass')" | ./manage.py shell

The problem comes out with the linux pipe, the pipe(|) all the contents on its left(including the docker exec) to its right(./manage.py shell)

And this is not only difficult part, considering to put all these junks into a fabric run, which means they need quotes on both end. It will make whole thing very urgly.

fabric run:
run("docker exec container_django {command to create django super user}")

I am still struggling on how to make at least the junk work in a fabric run, but I don't know how to do it.


Solution

  • I recommend adding a new management command that will automatically create a superuser if no Users exist.

    See small example I created at https://github.com/dkarchmer/aws-eb-docker-django. In particular, see how I have a python manage.py initadmin which runs:

    class Command(BaseCommand):
    
        def handle(self, *args, **options):
            if Account.objects.count() == 0:
                for user in settings.ADMINS:
                    username = user[0].replace(' ', '')
                    email = user[1]
                    password = 'admin'
                    print('Creating account for %s (%s)' % (username, email))
                    admin = Account.objects.create_superuser(email=email, username=username, password=password)
                    admin.is_active = True
                    admin.is_admin = True
                    admin.save()
            else:
                print('Admin accounts can only be initialized if no Accounts exist')
    

    (See Authentication/management/commands).

    You can see how the Dockerfile then just runs CMD to runserver.sh which basically runs

    python manage.py migrate --noinput
    python manage.py initadmin
    python manage.py runserver 0.0.0.0:8080
    

    Obviously, this assumes the Admins immediately go change their passwords after the server is up. That may or may not be good enough for you.