38π
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.
67π
Get the container ID and run the command.
docker exec -it container_id python manage.py createsuperuser
- [Django]-Django Rest Framework Conditional Field on Serializer
- [Django]-Requirements.txt greater than equal to and then less than?
- [Django]-Retrieving a Foreign Key value with django-rest-framework serializers
30π
Use environment variables and non interactive mode. So you add something like this in your env file.
DJANGO_SUPERUSER_PASSWORD=**********
DJANGO_SUPERUSER_EMAIL=example@example.com
DJANGO_SUPERUSER_USERNAME=admin
Then, in your docker entrypoint file, add these commands:
python manage.py makemigrations
python manage.py migrate
python manage.py createcachetable
if [ "$DJANGO_SUPERUSER_USERNAME" ]
then
python manage.py createsuperuser \
--noinput \
--username $DJANGO_SUPERUSER_USERNAME \
--email $DJANGO_SUPERUSER_EMAIL
fi
$@
Note there is no need to put the password, as Djangoβs createsuperuser script takes that from DJANGO_SUPERUSER_PASSWORD by default in noninteractive mode.
This will run the migrations and create the admin user as needed when the container is started using environment variables.
- [Django]-How to check if a user is logged in (how to properly use user.is_authenticated)?
- [Django]-With DEBUG=False, how can I log django exceptions to a log file
- [Django]-Where to put Django startup code?
16π
Disclaimer:
Storing the passwords plaintext in the Dockerfile is insecure as the passwords can be extracted from the image at any time and the Dockerfiles are usually committed to version control. However, this answer is not about password security, rather about automating the createsuperuser
command; if you are looking for a proper way to store the superuser password, take a look at this SO question: Docker and securing passwords
.
I handle this by evaluating the python code line in Dockerfile.
ENV DJANGO_DB_NAME=default
ENV DJANGO_SU_NAME=admin
ENV DJANGO_SU_EMAIL=admin@my.company
ENV DJANGO_SU_PASSWORD=mypass
RUN python -c "import django; django.setup(); \
from django.contrib.auth.management.commands.createsuperuser import get_user_model; \
get_user_model()._default_manager.db_manager('$DJANGO_DB_NAME').create_superuser( \
username='$DJANGO_SU_NAME', \
email='$DJANGO_SU_EMAIL', \
password='$DJANGO_SU_PASSWORD')"
Note that this is different from calling
User.objects.create_superuser('admin', 'admin@example.com', 'pass')
as django.contrib.auth.get_user_model
will work fine with custom user model if you should have any (which is quite common), while with User.objects.create
you only create a standard user entity, ignoring any custom user model.
Also, itβs the same call that djangoβs createsuperuser
command does under the hood, so it should be pretty safe to do.
- [Django]-Django excluding specific instances from queryset without using field lookup
- [Django]-How can I build multiple submit buttons django form?
- [Django]-How to set and get session in Django?
15π
I use this command when using compose
docker-compose run <web> python manage.py createsuperuser
where <web>
is the name of the docker service(in docker-compose.yml)
https://docs.docker.com/compose/reference/run/
When run with Dockerfile
docker exec -it <container_id> python manage.py createsuperuser
- [Django]-How do I migrate a model out of one django app and into a new one?
- [Django]-Django: Fat models and skinny controllers?
- [Django]-Django test runner not finding tests
14π
I would suggest running a Data Migration, so when you startup your Docker services (e.g. app & db) via docker-compose up
, you can execute all migrations exactly once docker-compose exec web python code/manage.py migrate
So your migration would look like this (assuming you store credentials etc. in environment variables)
import os
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('<your_app>', '<previous_migration>'),
]
def generate_superuser(apps, schema_editor):
from django.contrib.auth.models import User
DJANGO_DB_NAME = os.environ.get('DJANGO_DB_NAME', "default")
DJANGO_SU_NAME = os.environ.get('DJANGO_SU_NAME')
DJANGO_SU_EMAIL = os.environ.get('DJANGO_SU_EMAIL')
DJANGO_SU_PASSWORD = os.environ.get('DJANGO_SU_PASSWORD')
superuser = User.objects.create_superuser(
username=DJANGO_SU_NAME,
email=DJANGO_SU_EMAIL,
password=DJANGO_SU_PASSWORD)
superuser.save()
operations = [
migrations.RunPython(generate_superuser),
]
This allows you to use a built container to execute against a database, whether itβs a local db in the same container or a separate service. And itβs not done every time you rebuild your container, but only when the migration is necessary.
- [Django]-How to run a celery worker with Django app scalable by AWS Elastic Beanstalk?
- [Django]-Adding links to full change forms for inline items in django admin?
- [Django]-How to update an existing Conda environment with a .yml file
7π
I used decople lib to load the environment variables from the .env
file and I did the test if the username exists.
from decouple import config
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
username = config('DJANGO_SUPERUSER_USERNAME')
email = config('DJANGO_SUPERUSER_EMAIL')
password = config('DJANGO_SUPERUSER_PASSWORD')
if not User.objects.filter(username=username).exists():
print('Creating account for %s (%s)' % (username, email))
admin = User.objects.create_superuser(
email=email, username=username, password=password)
else:
print('Admin account has already been initialized.')
So I do it like this:
source .env
python manage.py initadmin
My .env file has:
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_EMAIL=admin@admin.com
DJANGO_SUPERUSER_PASSWORD=mypass
- [Django]-What does "'tests' module incorrectly imported" mean?
- [Django]-With DEBUG=False, how can I log django exceptions to a log file
- [Django]-Django-admin.py makemessages not working
3π
None of the answers had worked in my project.
This worked:
docker exec web ./manage.py shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('your_user', 'your_password')"
- [Django]-Where is a good place to work on accounts/profile in Django with the Django registration app?
- [Django]-Get class name of django model
- [Django]-How to change a django QueryDict to Python Dict?
2π
Might be easiest to just put together a Python script to create the Django superuser for you, instead of trying to feed all those commands through manage.py shell
. Can you put your commands in a .py file, letβs say yourfile.py
:
#!/usr/bin/env python
from django.contrib.auth.models import User
User.objects.create_superuser('admin', 'admin@example.com', 'pass')
And then, after doing chmod +x yourfile.py
:
fabric run:
run("docker exec container_django yourfile.py")
Depending on your setup you may need to make sure that the DJANGO_SETTINGS_MODULE
environment variable is set appropriately for that run() command.
- [Django]-Loading initial data with Django 1.7+ and data migrations
- [Django]-How to assign items inside a Model object with Django?
- [Django]-Django : DRF Token based Authentication VS JSON Web Token
2π
I took @hoeflingβs answer, and changed it a little.
I needed to create super user AFTER the build step. So i put it inside a supervisor script. That means it will be executed every time i run the container. So i added a simple if / else control to check if superuser is already created. That reduces the execution time. And we need to set DJANGO_SETTINGS_MODULE
environment variable as well.
python -c "import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'project_name.settings'
import django
django.setup()
from django.contrib.auth.management.commands.createsuperuser import get_user_model
if get_user_model().objects.filter(username='$DJANGO_SUPERUSER_USERNAME'):
print 'Super user already exists. SKIPPING...'
else:
print 'Creating super user...'
get_user_model()._default_manager.db_manager('$DJANGO_DB_NAME').create_superuser(username='$DJANGO_SUPERUSER_USERNAME', email='$DJANGO_SUPERUSER_EMAIL', password='$DJANGO_SUPERUSER_PASSWORD')
print 'Super user created...'"
- [Django]-Django query filter with variable column
- [Django]-On Heroku, is there danger in a Django syncdb / South migrate after the instance has already restarted with changed model code?
- [Django]-Django/DRF β 405 Method not allowed on DELETE operation
1π
create file Makefile
.ONESHELL:
reset-superuser: SHELL := python
reset-superuser:
import os
import django
from django.contrib.auth import get_user_model
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.develop")
django.setup()
User = get_user_model()
user = User.objects.filter(is_superuser=True).first()
if user:
user.set_password("admin")
user.save()
else:
user = User.objects.create_superuser(
username="josuedjh",
first_name="Josue djh",
password="admin",
)
print(f"Superuser {user.username!r} with password `admin`")
run comando:
make reset-superuser
- [Django]-Scoped_session(sessionmaker()) or plain sessionmaker() in sqlalchemy?
- [Django]-OperationalError: database is locked
- [Django]-Django β "Incorrect type. Expected pk value, received str" error
0π
The clean and elegant way is not to put any additional custom code or commands into the codebase if you are running the Django in the container. Instead use a bash script to run any configuration required (e.g. creating superuser). This way you can better mange and automate your configurations and keeping the codebase clean and reusable accross environments.
Put in your docker-compose.yml
command: >
bash -c '..
&& source create_superuser_prod.sh
&& ..'
Put in the create_superuser_prod.sh
echo "from django.contrib.auth.models import User; User.objects.create_superuser($PROD_USER,$PROD_USER_EMAIL,$PROD_USER_PASS)" | python manage.py shell
- [Django]-Unable to import path from django.urls
- [Django]-How can one change the type of a Django model field from CharField to ForeignKey?
- [Django]-How to use subquery in django?