在不输入密码的情况下,在Docker容器中创建Django Super用户



我正在用织物在django docker容器中创建createsuperuser。

要在Django中创建超级用户,我需要以Django交互式运行:

./manage.py createsuperuser

并且因为我想使其在面料脚本中运行,所以我发现 this 命令可以避免输入密码

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

然后,我将其与" Docker Exec" 一起放在我的Django容器

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

问题带有Linux管道,管道(|)左侧(包括docker exec)的所有内容都位于其右侧(./manage.py shell)

>

考虑到将所有这些垃圾放入织物运行中,这不仅是困难的部分,这意味着它们都需要两端的引号。这将使整个事情变得非常艰难。

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

我仍在努力在如何使垃圾运行中的垃圾工作,但我不知道该怎么做。

获取容器ID并运行命令。

docker exec -it container_id python manage.py createsuperuser

我建议添加一个新的管理命令,该命令将在不存在的情况下自动创建超级用户。

请参阅我在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

显然,这是假设管理员在服务器启动后立即更改密码。

使用环境变量和非交互式模式。因此,您在Env文件中添加了类似的内容。

DJANGO_SUPERUSER_PASSWORD=**********
DJANGO_SUPERUSER_EMAIL=example@example.com
DJANGO_SUPERUSER_USERNAME=admin

然后,在您的Docker入门点文件中,添加以下命令:

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
$@

请注意,无需添加密码,因为Django的CreateSuperuser脚本默认情况下从django_superuser_passer_password中获取了密码。

默认情况下。

这将运行迁移并根据需要在使用环境变量开始时根据需要创建管理用户。

免责声明:

将密码存储在Dockerfile中的纯文本是不安全的,因为可以随时从图像中提取密码,并且通常将DockerFiles从图像中提取。但是,此答案与密码安全无关,而是关于自动化createsuperuser命令的内容。如果您正在寻找一种存储Superuser密码的正确方法,请查看此问题:Docker并确保密码。


我通过评估Dockerfile中的Python代码线来处理此操作。

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

请注意,这与调用

不同
User.objects.create_superuser('admin', 'admin@example.com', 'pass')

由于django.contrib.auth.get_user_model应该与自定义用户模型一起使用,如果您有任何(非常常见),而使用User.objects.create,则仅创建标准用户实体,忽略任何自定义用户模型。

另外,这是Django的createsuperuser命令在引擎盖下的呼叫使用compose

docker-compose run <web> python manage.py createsuperuser

其中 <web>是docker服务的名称(在docker-compose.yml中)https://docs.docker.com/compose/reference/run/

与Dockerfile一起运行

docker exec -it <container_id> python manage.py createsuperuser

我建议运行数据迁移,因此,当您通过docker-compose up启动Docker Services(例如App&amp; db)时,您可以精确执行所有迁移,一旦docker-compose exec web python code/manage.py migrate <</p>

,您的迁移看起来像这样(假设您存储凭据等在环境变量中)

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

这使您可以使用构建容器来针对数据库执行,无论是同一容器中的本地DB还是单独的服务。而且,每次重建容器时都不会完成,但只有在需要迁移时才完成。

我使用decople lib从 .env加载环境变量文件,如果存在用户名,我进行了测试。

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

所以我这样做:

  source .env
  python manage.py initadmin

我的.env文件具有:

DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_EMAIL=admin@admin.com
DJANGO_SUPERUSER_PASSWORD=mypass

我的项目中没有一个答案。这有效:

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

可能最容易组合一个python脚本来为您创建Django Superuser,而不是尝试通过manage.py shell来喂食所有这些命令。您可以将命令放在.py文件中吗,例如yourfile.py

#!/usr/bin/env python
from django.contrib.auth.models import User
User.objects.create_superuser('admin', 'admin@example.com', 'pass')

,然后在执行chmod +x yourfile.py之后:

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

根据您的设置,您可能需要确保适当设置DJANGO_SETTINGS_MODULE环境变量的run()命令。

我接受了 @hoefling的答案,然后对其进行了一些更改。

我需要在之后创建超级用户构建步骤。因此,我将其放在主管脚本中。这意味着每次运行容器时都会执行它。因此,我添加了一个简单的IF/else控件来检查Superuser是否已经创建。这减少了执行时间。我们还需要设置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...'"

创建文件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`")

运行comando:

make reset-superuser

如果您在容器中运行Django,那么干净而优雅的方式不将任何其他自定义代码或命令放入代码库中。而是使用BASH脚本运行任何需要的配置(例如创建Superuser)。这样,您就可以更好地管理和自动化配置,并保持代码库清洁和可重复使用的累加环境。放入您的docker-compose.yml

command: >
  bash -c '.. 
  && source create_superuser_prod.sh 
  && ..'

放入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 

最新更新