在docker容器中创建django超级用户而无需输入密码

时间:2015-05-04 09:52:33

标签: python django shell docker fabric

我在带有结构的django docker容器中创建了createperperuser。

要在django中创建超级用户,我需要在django交互模式下运行它:

./manage.py createsuperuser

因为我想让它在Fabric脚本中运行,所以我发现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}")

我仍在苦苦思索如何在面料运行中至少制作垃圾工作,但我不知道该怎么做。

10 个答案:

答案 0 :(得分:9)

我建议添加一个新的管理命令,如果没有用户,将自动创建一个超级用户。

查看我在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

显然,这假设管理员在服务器启动后立即更改密码。对你来说这可能或不够好。

答案 1 :(得分:8)

获取容器ID并运行命令。

docker exec -it container_id python manage.py createsuperuser

答案 2 :(得分:7)

声明:

将密码明文存储在Dockerfile中是不安全的,因为密码可以随时从映像中提取,Dockerfiles通常会提交版本控制。但是,这个答案不是关于密码安全性,而是关于自动化createsuperuser命令;如果您正在寻找存储超级用户密码的正确方法,请查看此SO问题:Docker and securing passwords

我通过评估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可以与custom user model一起工作,如果你应该有(很常见),而User.objects.create你只能创建一个标准用户实体,忽略任何自定义用户模型

此外,它与django createsuperuser命令does under the hood的呼叫相同,因此应该非常安全。

答案 3 :(得分:5)

我在使用撰写时使用此命令

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

答案 4 :(得分:4)

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

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_USERNAME
fi

$@

请注意,无需输入密码,因为Django的createsuperuser脚本默认在非交互模式下从DJANGO_SUPERUSER_PASSWORD获取密码。

这将在使用环境变量启动容器时运行迁移并根据需要创建admin用户。

答案 5 :(得分:1)

最简单的方法是将Python脚本放在一起为您创建Django超级用户,而不是尝试通过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")

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

答案 6 :(得分:1)

我拿了@hoefling's answer,稍稍改了一下。

我需要创建超级用户 AFTER 构建步骤。所以我把它放在一个主管脚本中。这意味着每次运行容器时都会执行它。所以我添加了一个简单的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...'"

答案 7 :(得分:1)

我建议运行一个Data Migration,因此,当您通过docker-compose up启动Docker服务(例如,app和db)时,您可以一次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),
    ]

这允许您使用构建的容器对数据库执行操作,无论它是同一容器中的本地数据库还是单独的服务。并不会在每次重建容器时都执行此操作,只是在需要迁移时才执行。

答案 8 :(得分:1)

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

答案 9 :(得分:0)

没有一个答案在我的项目中起作用。 这可行:

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