web-dev-qa-db-ja.com

パスワードを入力せずにDockerコンテナにDjangoスーパーユーザーを作成する

Djangoファブリックを備えたDockerコンテナーでスーパーユーザーを作成することに挑戦しています。

Djangoでスーパーユーザーを作成するには、これをDjangoインタラクティブモードで実行する必要があります。

./manage.py createsuperuser

そして、私はそれをファブリックスクリプトで実行させたいので、 this コマンドがパスワードの入力を回避できることがわかります

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パイプで発生し、パイプ(|)の左側のすべてのコンテンツ(docker execを含む)が右側(./manage.pyシェル)に

そして、これは難しい部分であるだけでなく、これらすべてのジャンクをファブリックの実行に入れることを考えると、両端に引用符が必要であることを意味します。それはすべてを非常に緊急にします。

fabric run:
run("docker exec container_Django {command to create Django super user}")

私はまだ生地のランで少なくともジャンクを機能させる方法に苦労していますが、それを行う方法がわかりません。

19
Liao Zhuodi

ユーザーが存在しない場合にスーパーユーザーを自動的に作成する新しい管理コマンドを追加することをお勧めします。

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が基本的に実行されるrunserver.shにCMDを実行する方法を確認できます

python manage.py migrate --noinput
python manage.py initadmin
python manage.py runserver 0.0.0.0:8080

明らかに、これは管理者がサーバーの起動後すぐにパスワードを変更することを前提としています。それで十分かもしれません。

9
dkarchmer

コンテナーIDを取得してコマンドを実行します。

docker exec -it container_id python manage.py createsuperuser
13
SuperNova

免責事項:

パスワードはいつでもイメージから抽出でき、Dockerfileは通常、バージョン管理にコミットされているため、Dockerfileにプレーンテキストでパスワードを保存することは安全ではありません。ただし、この回答はパスワードのセキュリティではなく、createsuperuserコマンドの自動化に関するものです。スーパーユーザーのパスワードを保存する適切な方法を探している場合は、このSO質問: Dockerとセキュリティで保護されたパスワード を参照してください。


これは、Dockerfileのpythonコード行を評価することで処理します。

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

なので Django.contrib.auth.get_user_modelを使用すると、非常に一般的ですが、 カスタムユーザーモデル を使用すると正常に機能しますが、User.objects.createカスタムユーザーモデルを無視して、標準ユーザーエンティティのみを作成します。

また、これはDjangoのcreatesuperuserコマンド 内部で実行される と同じ呼び出しであるため、実行してもかなり安全です。

8
hoefling

Data Migration を実行することをお勧めします。そのため、Dockerサービス(例:app&db)を起動するときにdocker-compose up、すべての移行を1回だけ実行できます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),
    ]

これにより、同じコンテナー内のローカルdbでも、別のサービスでも、データベースに対して実行するためにビルドされたコンテナーを使用できます。コンテナを再構築するたびに行われるのではなく、移行が必要な場合にのみ行われます。

3
Hendrik F

作成を使用するときにこのコマンドを使用します

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
2
anmolakhilesh

Pythonスクリプトをまとめて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")

設定によっては、そのrun()コマンドに対してDjango_SETTINGS_MODULE環境変数が適切に設定されていることを確認する必要がある場合があります。

2

私のプロジェクトではどの回答も機能しませんでした。これはうまくいきました:

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')"
1
Carmen Jara

@ hoefling's answer を取り、少し変更しました。

ビルドステップの後にスーパーユーザー[〜#〜] [〜#〜]を作成する必要がありました。だから私はそれをスーパーバイザースクリプトの中に入れました。つまり、コンテナーを実行するたびに実行されます。だから私はスーパーユーザーが既に作成されているかどうかを確認するための単純な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...'"
1
alix