Создайте суперпользователя django в контейнере докера без ввода пароля

Я пытаюсь создать createereruser в контейнере django docker с тканью.

Чтобы создать суперпользователя в django, мне нужно запустить его в интерактивном режиме django:

./manage.py createsuperuser

И потому, что я хочу запустить его в тканью script, поэтому я нахожу эту команду не вводить пароль

echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'pass')" | ./manage.py shell

Затем я поставил это вместе с "docker exec" , чтобы запустить его в контейнере django

docker exec container_django echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'pass')" | ./manage.py shell

Проблема заключается в том, что linux pipe, pipe (|) содержит все содержимое слева (включая docker exec) справа (./manage.py shell)

И это не только сложная часть, если учесть, что все эти джунки превращаются в трюк, что означает, что им нужны котировки на обоих концах. Это сделает все очень срочно.

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

Я все еще борется за то, как сделать хотя бы нежелательную работу в прогоне, но я не знаю, как это сделать.

Ответ 1

Отказ от ответственности:

Хранение открытого текста паролей в Dockerfile небезопасно, так как пароли могут быть извлечены из образа в любое время, а Dockerfiles обычно предназначены для контроля версий. Однако этот ответ не о безопасности пароля, а об автоматизации команды createsuperuser; Если вы ищете правильный способ хранения пароля суперпользователя, взгляните на следующий вопрос: Docker и защита паролей.


Я справляюсь с этим, оценивая строку кода Python в Dockerfile.

ENV DJANGO_DB_NAME=default
ENV DJANGO_SU_NAME=admin
ENV [email protected]
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')"

Обратите внимание, что это отличается от вызова

User.objects.create_superuser('admin', '[email protected]', 'pass')

as django.contrib.auth.get_user_model будет отлично работать с пользовательской моделью пользователя, если она у вас есть (что довольно часто встречается), в то время как с помощью User.objects.create вы создаете только стандартную пользовательскую сущность, игнорируя любую пользовательскую модель пользователя.

Кроме того, это тот же самый вызов, который команда django createsuperuser делает createsuperuser, так что это должно быть довольно безопасно.

Ответ 2

Я рекомендую добавить новую команду управления, которая автоматически создаст суперпользователя, если пользователей не существует.

Посмотрите небольшой пример, который я создал на https://github.com/dkarchmer/aws-eb-docker-django. В частности, посмотрите, как у меня есть python manage.py initadmin который запускается:

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')

(См. Аутентификация/управление/команды).

Вы можете увидеть, как Dockerfile затем просто запускает CMD для runserver.sh, который в основном выполняется

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

Очевидно, это предполагает, что администраторы сразу же меняют свои пароли после запуска сервера. Это может или не может быть достаточно хорошо для вас.

Ответ 3

Получите идентификатор контейнера и выполните команду.

docker exec -it container_id python manage.py createsuperuser

Ответ 4

Может быть проще всего собрать Python script, чтобы создать для вас суперпользователя Django, вместо того, чтобы пытаться передать все эти команды через manage.py shell. Можете ли вы поместить свои команды в файл .py, скажем yourfile.py:

#!/usr/bin/env python

from django.contrib.auth.models import User
User.objects.create_superuser('admin', '[email protected]', 'pass')

И затем, после выполнения chmod +x yourfile.py:

fabric run:
run("docker exec container_django yourfile.py")

В зависимости от вашей настройки вам может потребоваться убедиться, что переменная среды DJANGO_SETTINGS_MODULE установлена ​​для этой команды().

Ответ 5

Я взял @hoefling answer и немного изменил его.

Мне нужно было создать суперпользователя ПОСЛЕ этапа сборки. Поэтому я помещаю его в супервизор script. Это означает, что он будет выполняться каждый раз, когда я запускаю контейнер. Поэтому я добавил простой if/else-элемент управления, чтобы проверить, создан ли суперпользователь. Это сокращает время выполнения. И нам также нужно установить переменную среды DJANGO_SETTINGS_MODULE.

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...'"

Ответ 6

Я бы посоветовал запустить Data Migration, поэтому, когда вы запускаете свои сервисы Docker (например, app & db) через docker-compose up, вы можете выполнить все миграции ровно после того, как docker-compose exec web python code/manage.py migrate

Таким образом, ваша миграция будет выглядеть так (при условии, что вы храните учетные данные и т.д. В переменных среды)

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),
    ]

Это позволяет использовать встроенный контейнер для выполнения в базе данных, будь то локальная база данных в том же контейнере или отдельная служба. И это делается не каждый раз, когда вы перестраиваете свой контейнер, а только тогда, когда необходима миграция.

Ответ 7

Ни один из ответов не сработал в моем проекте. Это сработало:

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')"