Je vais essayer de créer un superutilisateur dans un Django conteneur docker avec du tissu.
Pour créer le super utilisateur dans Django, je dois l'exécuter dans un Django mode interactif:
./manage.py createsuperuser
Et parce que je veux le faire fonctionner dans un script Fabric, je trouve donc que la commande this pourrait éviter de saisir le mot de passe
echo "from Django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'pass')" | ./manage.py Shell
Ensuite, j'ai mis cela avec "docker exec" pour l'exécuter dans mon Django conteneur
docker exec container_Django echo "from Django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'pass')" | ./manage.py Shell
Le problème vient avec le pipe linux, le pipe (|) tout le contenu à sa gauche (y compris le docker exec) à sa droite (./ manage.py Shell)
Et ce n'est pas seulement une partie difficile, compte tenu de mettre toutes ces jonques dans un cycle de fabrication, ce qui signifie qu'elles ont besoin de devis aux deux extrémités. Cela rendra le tout très urgent.
fabric run:
run("docker exec container_Django {command to create Django super user}")
Je me bats toujours sur la façon de faire fonctionner au moins la camelote dans un tissu, mais je ne sais pas comment le faire.
Je recommande d'ajouter une nouvelle commande de gestion qui créera automatiquement un superutilisateur si aucun utilisateur n'existe.
Voir le petit exemple que j'ai créé sur https://github.com/dkarchmer/aws-eb-docker-Django . En particulier, voyez comment j'ai un python manage.py initadmin
qui s'exécute:
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')
(Voir Authentification/gestion/commandes).
Vous pouvez voir comment le Dockerfile exécute ensuite CMD vers runserver.sh qui fonctionne essentiellement
python manage.py migrate --noinput
python manage.py initadmin
python manage.py runserver 0.0.0.0:8080
Évidemment, cela suppose que les administrateurs modifient immédiatement leurs mots de passe une fois le serveur opérationnel. Cela peut ou peut ne pas être suffisant pour vous.
Obtenez l'ID de conteneur et exécutez la commande.
docker exec -it container_id python manage.py createsuperuser
Le stockage du texte en clair des mots de passe dans le Dockerfile n'est pas sûr car les mots de passe peuvent être extraits de l'image à tout moment et les Dockerfiles sont généralement validés pour le contrôle de version. Cependant, cette réponse ne concerne pas la sécurité des mots de passe, mais plutôt l'automatisation de la commande createsuperuser
; si vous cherchez un moyen approprié de stocker le mot de passe du superutilisateur, jetez un œil à cette SO question: Docker et sécurisation des mots de passe .
Je gère cela en évaluant la ligne de code python dans Dockerfile.
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')"
Notez que c'est différent d'appeler
User.objects.create_superuser('admin', '[email protected]', 'pass')
comme Django.contrib.auth.get_user_model
fonctionnera très bien avec modèle utilisateur personnalisé si vous devez en avoir (ce qui est assez courant), tandis qu'avec User.objects.create
vous créez uniquement une entité utilisateur standard, en ignorant tout modèle utilisateur personnalisé.
De plus, c'est le même appel que la commande createsuperuser
de Django le fait sous le capot , donc cela devrait être assez sûr.
Je suggérerais d'exécuter un Data Migration , donc lorsque vous démarrez vos services Docker (par exemple, app & db) via docker-compose up
, vous pouvez exécuter toutes les migrations une seule fois docker-compose exec web python code/manage.py migrate
Ainsi, votre migration ressemblerait à ceci (en supposant que vous stockiez les informations d'identification, etc. dans les variables d'environnement)
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),
]
Cela vous permet d'utiliser un conteneur intégré pour exécuter une base de données, qu'il s'agisse d'une base de données locale dans le même conteneur ou d'un service distinct. Et cela n'est pas fait à chaque fois que vous reconstruisez votre conteneur, mais uniquement lorsque la migration est nécessaire.
J'utilise cette commande lorsque j'utilise compose
docker-compose run <web> python manage.py createsuperuser
où <web>
est le nom du service docker (dans docker-compose.yml) https://docs.docker.com/compose/reference/run/
Lorsqu'il est exécuté avec Dockerfile
docker exec -it <container_id> python manage.py createsuperuser
Pourrait être plus simple de simplement assembler un script Python pour créer le Django superutilisateur pour vous, au lieu d'essayer de nourrir toutes ces commandes via manage.py Shell
. Pouvez-vous mettre vos commandes dans un fichier .py, disons yourfile.py
:
#!/usr/bin/env python
from Django.contrib.auth.models import User
User.objects.create_superuser('admin', '[email protected]', 'pass')
Et puis, après avoir fait chmod +x yourfile.py
:
fabric run:
run("docker exec container_Django yourfile.py")
Selon votre configuration, vous devrez peut-être vous assurer que le Django_SETTINGS_MODULE
la variable d'environnement est définie de manière appropriée pour cette commande run ().
Aucune des réponses n'avait fonctionné dans mon projet. Cela a fonctionné:
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')"
J'ai pris @ réponse de hoefling , et je l'ai un peu changé.
J'ai eu besoin de créer un super utilisateur [~ # ~] après [~ # ~] l'étape de construction. Je l'ai donc mis dans un script de superviseur. Cela signifie qu'il sera exécuté chaque fois que j'exécuterai le conteneur. J'ai donc ajouté un simple contrôle if/else pour vérifier si le superutilisateur est déjà créé. Cela réduit le temps d'exécution. Et nous devons définir Django_SETTINGS_MODULE
variable d'environnement également.
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...'"