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}")
私はまだ生地のランで少なくともジャンクを機能させる方法に苦労していますが、それを行う方法がわかりません。
ユーザーが存在しない場合にスーパーユーザーを自動的に作成する新しい管理コマンドを追加することをお勧めします。
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
明らかに、これは管理者がサーバーの起動後すぐにパスワードを変更することを前提としています。それで十分かもしれません。
コンテナーIDを取得してコマンドを実行します。
docker exec -it container_id python manage.py createsuperuser
パスワードはいつでもイメージから抽出でき、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
コマンド 内部で実行される と同じ呼び出しであるため、実行してもかなり安全です。
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でも、別のサービスでも、データベースに対して実行するためにビルドされたコンテナーを使用できます。コンテナを再構築するたびに行われるのではなく、移行が必要な場合にのみ行われます。
作成を使用するときにこのコマンドを使用します
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
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
環境変数が適切に設定されていることを確認する必要がある場合があります。
私のプロジェクトではどの回答も機能しませんでした。これはうまくいきました:
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')"
@ 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...'"