Reputation: 190
I'm trying to make the installation procedure of a Django application easier. One of the steps is to run django-admin.py migrate
, is there any way this can be automatically run when the application is started with Gunicorn, uWSGI or mod_wsgi.
edit: Clearup up what I mean with startup.
edit2: This is an open-source application I co-maintain. I do not deploy it. It is being deployed by regular system admin's who often don't know anything about Django. One complaint is that the application is hard to deploy because all these manual manage steps needed. Asking them to create some scripts in their deployment tool does not make installation easier. What I want is that when then application is started it checks if there is a database and if not runs manage.py migrate
.
edit3: deployment is usually through pip
Upvotes: 3
Views: 4531
Reputation: 16661
This would normally go into your deployment script, depending on the routine with which you update the Django application in your target environment.
You not only need to run migrate, but probably a list of calls:
To allow the most flexibility in your setup, you can create a Django command called setup.py that can do all of that. This can also load DB fixtures if you need to initialize data.
Here is a snippet from what I do in setup.py:
def handle(self, *args, **options):
LOGGER.info('Setup: translations ...')
call_command('compilemessages', locale=['de'], verbosity=2)
LOGGER.info('Setup: translations ... DONE')
LOGGER.info('Setup: DB check and fixtures ...')
db_error = self.load_db(options)
if db_error:
if options['wait_db']:
while db_error:
LOGGER.warning('%s - retrying in 5 secs...', db_error)
time.sleep(5)
db_error = self.load_db(options)
else:
LOGGER.error(db_error)
LOGGER.info('Setup: DB check and fixtures ... %s', 'FAILED' if db_error else 'OK')
LOGGER.info('Setup: collectstatic to %s ...', settings.STATIC_ROOT)
cs_error = None
try:
call_command('collectstatic', '--clear', '--noinput')
except FileNotFoundError as fnfe:
cs_error = fnfe
LOGGER.warning('Error during "collectstatic": %s', fnfe)
LOGGER.info('Setup: collectstatic ... %s', 'WARN' if cs_error else 'OK')
def load_db(self, options):
try:
call_command('migrate')
if not User.objects.count():
call_command('loaddata', 'auth.json')
LOGGER.info('Setup: loaded fixture auth.json')
except DatabaseError as dbe:
return dbe
If you deploy via GIT you could use a GIT post_merge hook or similar that runs a bash script calling any manage.py commands that you need.
If you are deploying via Docker, you can put the call to ./manage.py setup
into the docker-entrypoint.sh script which is called whenever that Docker image is run.
Upvotes: 3
Reputation: 4154
It depends on what process manager you use, if you are starting it manually or via a script just run manage.py migrate before it, i use supervisor and just added it as a program in that like
[program:migrate]
command = python manage.py migrate
autorestart = false
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
Any process manager will be able to do it, just make sure you set it to not restart as the command dies after the migrations are done.
Upvotes: 0