Created
November 9, 2025 01:04
-
-
Save yeiichi/cf1760c2e8b0ec2e3f36cb4048620e7f to your computer and use it in GitHub Desktop.
Helper Makefile for Django + Docker Compose development
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # language: Makefile | |
| # ============================================================================== | |
| # Makefile.django-docker-helper | |
| # ------------------------------------------------------------------------------ | |
| # Helper Makefile for Django + Docker Compose development. | |
| # | |
| # PURPOSE: | |
| # - Simplify common Django and Docker workflows. | |
| # - Provide short aliases for build, run, migrate, backup, test, and more. | |
| # - Encourage consistent developer operations across environments. | |
| # | |
| # USAGE: | |
| # make <target> | |
| # e.g. make up, make migrate, make logs, make backup | |
| # | |
| # HIGHLIGHTS: | |
| # • Portable — works with any Django project using docker-compose (services: web, db) | |
| # • Safe — no destructive operations unless explicitly called (see `make reset`) | |
| # • Developer-side only — not used in production | |
| # | |
| # EXAMPLES: | |
| # $ make up # Start containers | |
| # $ make migrate # Apply migrations | |
| # $ make superuser # Create admin user | |
| # $ make backup # Dump database to ./backup.sql | |
| # $ make fmt # Auto-format code (ruff + black) | |
| # | |
| # AUTHOR: Eiichi YAMAMOTO | |
| # LICENSE: MIT License | |
| # VERSION: 2025.11 | |
| # URL: https://yeiichi.com | |
| # ============================================================================== | |
| # ---- Config ---- | |
| DC ?= docker compose | |
| WEB ?= web | |
| DB ?= db | |
| MANAGE ?= python manage.py | |
| DB_USER ?= appuser | |
| DB_NAME ?= appdb | |
| DB_HOST ?= db | |
| DB_PORT ?= 5432 | |
| # ---- Help (default) ---- | |
| .DEFAULT_GOAL := help | |
| .PHONY: help | |
| help: ## Show this help | |
| @awk 'BEGIN{FS":.*##"; printf "\nUsage: make <target>\n\nTargets:\n"} /^[a-zA-Z0-9_%-]+:.*?##/{printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | |
| # ---- Lifecycle ---- | |
| .PHONY: up | |
| up: ## Start containers (detached) | |
| $(DC) up -d | |
| .PHONY: down | |
| down: ## Stop and remove containers (keep volume) | |
| $(DC) down | |
| .PHONY: reset | |
| reset: ## Stop and remove everything (including DB volume) | |
| $(DC) down -v --remove-orphans | |
| .PHONY: rebuild | |
| rebuild: ## Rebuild web image and restart | |
| $(DC) build --pull --no-cache $(WEB) | |
| $(DC) up -d --no-deps $(WEB) | |
| .PHONY: logs | |
| logs: ## Tail logs (all services) | |
| $(DC) logs -f --tail=200 | |
| # ---- Django shortcuts ---- | |
| .PHONY: migrate | |
| migrate: ## Run Django migrations | |
| $(DC) exec $(WEB) $(MANAGE) migrate | |
| .PHONY: makemigrations | |
| makemigrations: ## Make migrations | |
| $(DC) exec $(WEB) $(MANAGE) makemigrations | |
| .PHONY: superuser | |
| superuser: ## Create Django superuser | |
| $(DC) exec $(WEB) $(MANAGE) createsuperuser | |
| .PHONY: shell | |
| shell: ## Open Django shell | |
| $(DC) exec $(WEB) $(MANAGE) shell | |
| .PHONY: run | |
| run: ## Run dev server on :8000 | |
| $(DC) exec $(WEB) $(MANAGE) runserver 0.0.0.0:8000 | |
| .PHONY: collectstatic | |
| collectstatic: ## Collect static files (non-interactive) | |
| $(DC) exec $(WEB) $(MANAGE) collectstatic --noinput | |
| .PHONY: check | |
| check: ## Django system checks | |
| $(DC) exec $(WEB) $(MANAGE) check --deploy | |
| # ---- Testing & linting (optional tools) ---- | |
| .PHONY: test | |
| test: ## Run tests | |
| $(DC) exec $(WEB) pytest -q | |
| .PHONY: fmt | |
| fmt: ## Format code (ruff/black if installed) | |
| $(DC) exec $(WEB) ruff check --fix . | |
| $(DC) exec $(WEB) black . | |
| .PHONY: lint | |
| lint: ## Lint only | |
| $(DC) exec $(WEB) ruff check . | |
| $(DC) exec $(WEB) black --check . | |
| # ---- Database ops ---- | |
| .PHONY: psql | |
| psql: ## Open psql in the DB container | |
| $(DC) exec -e PGPASSWORD=$$( $(DC) exec -T $(DB) printenv POSTGRES_PASSWORD ) \ | |
| $(DB) psql -U $(DB_USER) -d $(DB_NAME) | |
| .PHONY: dbshell | |
| dbshell: ## Django dbshell (uses DATABASE_URL) | |
| $(DC) exec $(WEB) $(MANAGE) dbshell | |
| .PHONY: dump | |
| dump: ## Dump a named app (APP=your_app) to fixtures/APP.json | |
| @test -n "$(APP)" || (echo "Usage: make dump APP=your_app"; exit 2) | |
| $(DC) exec $(WEB) $(MANAGE) dumpdata $(APP) --indent 2 > fixtures/$(APP).json | |
| .PHONY: load | |
| load: ## Load a fixture (FILE=fixtures/foo.json) | |
| @test -n "$(FILE)" || (echo "Usage: make load FILE=fixtures/foo.json"; exit 2) | |
| $(DC) exec -T $(WEB) $(MANAGE) loaddata $(FILE) | |
| .PHONY: backup | |
| backup: ## pg_dump to ./backup.sql | |
| $(DC) exec $(DB) pg_dump -U $(DB_USER) -d $(DB_NAME) > backup.sql | |
| @echo "Wrote ./backup.sql" | |
| .PHONY: restore | |
| restore: ## psql < backup.sql (requires ./backup.sql) | |
| @test -f backup.sql || (echo "backup.sql not found"; exit 2) | |
| $(DC) exec -T $(DB) psql -U $(DB_USER) -d $(DB_NAME) < backup.sql | |
| # ---- Utilities ---- | |
| .PHONY: sh | |
| sh: ## Shell into web container | |
| $(DC) exec $(WEB) sh -lc 'exec $$SHELL -l || sh' | |
| .PHONY: dbsh | |
| dbsh: ## Shell into db container | |
| $(DC) exec $(DB) sh -lc 'exec $$SHELL -l || sh' | |
| .PHONY: health | |
| health: ## Show container health/status | |
| $(DC) ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment