Okay, so we have dockerized our django app and we need to run a manage.py
command for some task. How do we do that? Simple, we have to locate the container that runs the django app, login and then run the command.
Locate The Container
It’s very likely that our app uses multiple containers to compose the entire system. For exmaple, I have one container running MySQL, one container running Redis and another running the actual Django app. If we want to run manage.py
commands, we have to login to the one that runs Django.
While our app is running, we can find the running docker containers using the docker ps
command like this:
1 2 3 4 5 6 |
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 308f40bba888 crawler_testscript "/sbin/my_init" 31 hours ago Up 3 seconds 5000/tcp crawler_testscript_1 3a5ccc872215 crawler_web "bash run_web.sh" 31 hours ago Up 4 seconds 0.0.0.0:8000->8000/tcp crawler_web_1 14f0e260fb2c redis:latest "/entrypoint.sh redis" 31 hours ago Up 4 seconds 0.0.0.0:6379->6379/tcp crawler_redis_1 252a7092870d mysql:latest "/entrypoint.sh mysql" 31 hours ago Up 4 seconds 0.0.0.0:3306->3306/tcp crawler_mysql_1 |
In my case, I am using Docker Compose and I know my Django app runs using the crawler_web
image. So we note the name of the container. In the above example, that is – crawler_web_1
.
Nice, now we know which container we have to login to.
Logging Into The Container
We use the name of the container to login to it, like this:
1 |
docker exec -it crawler_web_1 bash |
The command above will connect us to the container and land us on a bash shell. Now we’re ready to run our command.
Running the command
We cd
into the directory if necessary and then run the management command.
1 2 |
cd /project python manage.py <command> |
Summary
docker ps
to list running containers and locate the onedocker exec -it [container_name] bash
to login to the bash shell on that containercd
to the django project and runpython manage.py [command]
3 replies on “Django: Running management commands inside a Docker container”
Why not just run your command with exec?
That can be done if I need to run it once. I often need to run
collectstatic
,migrate
and other tasks. Instead of running with exec, I prefer running them from a bash shell.It’s probably best to run collectstatic and migrations and anything else in a separate container, with it’s own command.
create a directory with the various scripts you wanna run.
init
,init_static
,init_celery
, etc…Then your logs become much cleaner.
docker run --name my_app_static foo/bar /path/to/scripts/init_static.sh
Then you know when the the process is done by looking at the exit code of the container. Exit 0, everything was perfect, exit anyting else, error look at the log and figure out what happened.
Also you wanna think about the stability of your app, by deploying code that depends on a migration before you’ve deployed the migration. This way you deploy your migrations first, then you can roll release your app containers slowly starting new containers and shutting down the old ones.