我在带有结构的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}")
我仍在苦苦思索如何在面料运行中至少制作垃圾工作,但我不知道该怎么做。
答案 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')"