Lia*_*odi 17 python django shell fabric docker
我在带有织物的django docker容器中创建了createperperuser.
要在django中创建超级用户,我需要在django交互模式下运行它:
./manage.py createsuperuser
Run Code Online (Sandbox Code Playgroud)
因为我想让它在Fabric脚本中运行,所以我发现这个命令可以避免输入密码
echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'pass')" | ./manage.py shell
Run Code Online (Sandbox Code Playgroud)
然后我把它与"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
Run Code Online (Sandbox Code Playgroud)
问题出来了linux管道,管道(|)左边的所有内容(包括docker exec)到它的右边(./ manage.py shell)
这不仅是困难的部分,考虑将所有这些容器放入结构运行中,这意味着它们需要两端的引号.它会让整件事变得非常难看.
fabric run:
run("docker exec container_django {command to create django super user}")
Run Code Online (Sandbox Code Playgroud)
我仍在努力研究如何在面料运行中制作至少垃圾工作,但我不知道该怎么做.
Sup*_*ova 16
获取容器ID并运行命令。
docker exec -it container_id python manage.py createsuperuser
Run Code Online (Sandbox Code Playgroud)
Hen*_*k F 13
我建议运行数据迁移,因此当您通过 启动 Docker 服务(例如应用程序和数据库)时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),
]
Run Code Online (Sandbox Code Playgroud)
这允许您使用构建的容器对数据库执行,无论它是同一容器中的本地数据库还是单独的服务。并不是每次重建容器时都这样做,而是仅在需要迁移时才这样做。
我建议添加一个新的管理命令,如果不存在用户,将自动创建超级用户.
请参阅我在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')
Run Code Online (Sandbox Code Playgroud)
(请参阅身份验证/管理/命令).
您可以看到Dockerfile如何只运行CMD到runserver.sh,它基本上运行
python manage.py migrate --noinput
python manage.py initadmin
python manage.py runserver 0.0.0.0:8080
Run Code Online (Sandbox Code Playgroud)
显然,这假设管理员在服务器启动后立即更改密码.这对你来说可能是也可能不够好.
我在使用 compose 时使用这个命令
docker-compose run <web> python manage.py createsuperuser
Run Code Online (Sandbox Code Playgroud)
<web>docker 服务的名称在哪里(在 docker-compose.yml 中)
https://docs.docker.com/compose/reference/run/
使用 Dockerfile 运行时
docker exec -it <container_id> python manage.py createsuperuser
Run Code Online (Sandbox Code Playgroud)
小智 9
使用环境变量和非交互模式。所以你在你的 env 文件中添加了这样的东西。
DJANGO_SUPERUSER_PASSWORD=**********
DJANGO_SUPERUSER_EMAIL=example@example.com
DJANGO_SUPERUSER_USERNAME=admin
Run Code Online (Sandbox Code Playgroud)
然后,在您的 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
$@
Run Code Online (Sandbox Code Playgroud)
请注意,无需输入密码,因为 Django 的 createsuperuser 脚本默认在非交互模式下从 DJANGO_SUPERUSER_PASSWORD 获取密码。
这将运行迁移并在使用环境变量启动容器时根据需要创建管理员用户。
将密码明文存储在Dockerfile中是不安全的,因为可以随时从映像中提取密码,并且Dockerfiles通常会提交版本控制.但是,这个答案不是关于密码安全性,而是关于自动化createsuperuser命令; 如果您正在寻找存储超级用户密码的正确方法,请查看此SO问题: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')"
Run Code Online (Sandbox Code Playgroud)
请注意,这与调用不同
User.objects.create_superuser('admin', 'admin@example.com', 'pass')
Run Code Online (Sandbox Code Playgroud)
如django.contrib.auth.get_user_model将正常工作与自定义用户模型,如果您有任何(这是很常见的),同时用User.objects.create你只创建一个标准的用户实体,忽略任何用户自定义模式.
此外,它与django的createsuperuser命令在引擎盖下执行的操作相同,因此它应该是非常安全的.
小智 7
我使用 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.')
Run Code Online (Sandbox Code Playgroud)
所以我这样做:
source .env
python manage.py initadmin
Run Code Online (Sandbox Code Playgroud)
我的 .env 文件有:
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_EMAIL=admin@admin.com
DJANGO_SUPERUSER_PASSWORD=mypass
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14024 次 |
| 最近记录: |