How to Turbocharge Your Django Development Workflow with a Killer Makefile

Building and deploying a web application can be a daunting task, especially when you have to manage dependencies, configure the environment, and ensure that everything is working as expected. Fortunately, with the help of Makefiles, this process can be streamlined and automated. In this tutorial, we will explore a Makefile that simplifies building, running, and stopping a Dockerized web application.

Here's a simple Makefile to help you with your Django and Celery web application. It assumes that you have already written your code and configured your environment. Keep in mind that the make command must be installed on your system to use it. The Makefile includes the following targets:

.PHONY: help
help: ## Display his help
	@awk 'BEGIN {FS = ":.*?## "}; /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
	
.PHONY: build
build: ## Build the Dockerfile using Docker legacy building system
	docker build --progress=plain --no-cache -f Dockerfile.dev -t garupa-portal:latest .

.PHONY: buildx
buildx: ## Build the Dockerfile using buildx plugin to build multi-platform Docker images
	docker buildx build --progress=plain --no-cache -f Dockerfile.dev -t garupa-portal:latest . 

.PHONY: requirements
requirements: ## Generate the requirements.txt file
	poetry export -f requirements.txt --output requirements.txt --without-hashes

.PHONY: run
run: ## Run the docker-compose
	docker-compose up -d

.PHONY: stop
stop: ## Stop the docker-compose
	docker-compose down

We will examine this Makefile which was tailored for a web application built using Django and Celery. We'll go through each target in the Makefile, explaining what it does and how it can help simplify your development process. Whether you're new to Makefiles or an experienced user, this guide will give you a better understanding of how to use them to your advantage. Here's a brief overview of the targets:

  • build: Builds the Docker image for the application.
  • buildx: Builds the Docker image using Buildx, a Docker CLI plugin that enables cross-platform builds.
  • requirements: Generates the requirements.txt file for the application.
  • run: Starts the Docker containers for the application.
  • stop: Stops the Docker containers for the application.

Let's take a closer look at each of these targets and how they work.

Building the Docker image

The first two targets, build and buildx, are used to build the Docker image for the application. The build target uses the standard docker build command to build the image using the Dockerfile.dev file and tag it as myapp:latest. The --progress=plain flag disables the Docker build progress bar, and the --no-cache flag ensures that no cached layers are used during the build.

The buildx target uses the Docker Buildx plugin to build the image in a multi-platform environment, allowing you to build for multiple architectures and operating systems. This target uses the same options as the build target, but with the additional docker buildx build command and the --platform flag you can specify the target platform.

Generating the requirements.txt file

The requirements target generates the requirements.txt file for the application using the Poetry package manager. This file contains a list of all the Python packages required by the application, including their version numbers. This target uses the poetry export command to generate the requirements.txt file in the format expected by the application.

Running and stopping the Docker containers

The run target starts the Docker containers for the application using the docker-compose up -d command. This command starts the application in detached mode, allowing you to continue working in the terminal without being attached to the container. The docker-compose.yml file defines the services required for the application, including the app, queue, database, Redis, and Adminer services.

The stop target stops the Docker containers for the application using the docker-compose down command. This command stops and removes the containers, networks, and volumes created by the docker-compose up command.

Depending on your needs and requirements of your Django project, some additional targets that could be useful in a Django development Makefile include:

  • test: to run your test suite with a single command
  • migrate: to apply database migrations
  • createsuperuser: to create a Django superuser for testing and development purposes
  • shell: to open a Django shell
  • lint: to run code linters and formatters
  • clean: to remove any temporary files or directories created during development

When you type make help this is what the Makefile will look like:

Makefile help

Conclusion

Makefiles are a powerful tool for automating repetitive tasks and simplifying complex build processes. With the Makefile we've explored in this tutorial, you can easily build, run, and stop a Dockerized web application built using Django and Celery. By using Makefiles, you can save time and reduce the risk of errors, allowing you to focus on developing your application and delivering value to your users.