Создайте суперпользователя 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')"