{"id":13416248,"url":"https://github.com/amerkurev/django-docker-template","last_synced_at":"2025-04-13T00:46:47.614Z","repository":{"id":153546841,"uuid":"627622224","full_name":"amerkurev/django-docker-template","owner":"amerkurev","description":"Dockerized Django with Postgres, Gunicorn, and Traefik or Caddy (with auto renew Let's Encrypt)","archived":false,"fork":false,"pushed_at":"2025-04-11T09:25:20.000Z","size":677,"stargazers_count":205,"open_issues_count":3,"forks_count":38,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-13T00:46:39.186Z","etag":null,"topics":["caddy","django","django-application","django-framework","django-learning","django-project","docker","docker-compose","gunicorn","letsencrypt","traefik"],"latest_commit_sha":null,"homepage":"https://django-docker.dev","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amerkurev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-04-13T21:13:40.000Z","updated_at":"2025-04-10T22:10:27.000Z","dependencies_parsed_at":"2024-04-22T22:53:50.510Z","dependency_job_id":"7b0e81e7-df3d-4b86-9b59-c28643552206","html_url":"https://github.com/amerkurev/django-docker-template","commit_stats":{"total_commits":109,"total_committers":6,"mean_commits":"18.166666666666668","dds":"0.11926605504587151","last_synced_commit":"9f66e6064fde70a1728fd6a774564f9aa874098d"},"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amerkurev%2Fdjango-docker-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amerkurev%2Fdjango-docker-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amerkurev%2Fdjango-docker-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amerkurev%2Fdjango-docker-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amerkurev","download_url":"https://codeload.github.com/amerkurev/django-docker-template/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650434,"owners_count":21139672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caddy","django","django-application","django-framework","django-learning","django-project","docker","docker-compose","gunicorn","letsencrypt","traefik"],"created_at":"2024-07-30T21:00:56.006Z","updated_at":"2025-04-13T00:46:47.553Z","avatar_url":"https://github.com/amerkurev.png","language":"Python","funding_links":[],"categories":["Projects","Python"],"sub_categories":["Boilerplate"],"readme":"# Django + Docker = ❤️\n\u003cdiv markdown=\"1\"\u003e\n\n[![Build](https://github.com/amerkurev/django-docker-template/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/amerkurev/django-docker-template/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/amerkurev/django-docker-template/badge.svg)](https://coveralls.io/github/amerkurev/django-docker-template)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/amerkurev/django-docker-template/blob/master/LICENSE)\n\u003c/div\u003e\n\nThis simple Django project is an excellent template for your future projects. \nIt includes everything you need to quickly set up a quality technology stack and start developing your web application's business logic, skipping all the complex deployment issues at an early stage.\n\n## See in Action\nDeploying a Django Project in Production with Automatic Let's Encrypt HTTPS in Just 55 Seconds... 🏎️💨 ...🏁\n\n\u003ca href=\"https://asciinema.org/a/632218\" \u003e\u003cimg width=\"939\" alt=\"image\" src=\"https://github.com/amerkurev/django-docker-template/assets/28217522/6409c517-e868-4baf-8be6-18bb0d59e5f7\"\u003e\u003c/a\u003e\n\n*[Star this project if it's what you were looking for!](https://github.com/amerkurev/django-docker-template) ⭐️*\n\n## Technology stack\nThe technology stack used includes:\n\n- [`Python`](https://www.python.org) ver. 3.11\n- [`Django`](https://www.djangoproject.com) ver. 4.2\n- [`PostgreSQL`](https://www.postgresql.org) ver. 15\n- [`Gunicorn`](https://gunicorn.org) ver. 22.0\n- [`Traefik`](https://traefik.io/traefik/) ver. 2.9\n- [`Caddy`](https://caddyserver.com) ver. 2.7 *(instead of Traefik if you wish)*\n- [`Docker`](https://docs.docker.com/get-docker/) and [`Docker Compose`](https://docs.docker.com/compose/)\n\nNothing extra, only the essentials! You can easily add everything else yourself by expanding the existing configuration files:\n\n- [requirements.txt](https://github.com/amerkurev/django-docker-template/blob/master/requirements.txt)\n- [docker-compose.yml](https://github.com/amerkurev/django-docker-template/blob/master/docker-compose.yml)\n- [pytest.ini](https://github.com/amerkurev/django-docker-template/blob/master/website/pytest.ini)\n- and others...\n\n\u003e This project includes a simple Django application from the official Django tutorial - [\"a basic poll application\"](https://docs.djangoproject.com/en/4.2/intro/tutorial01/).\n\u003e You can safely delete this application at any time. This application is present in the project as an example, used for testing and debugging.\n\nSo, what do you get by using this project as a template for your project? Let's take a look.\n\n## Features\n- A well-configured Django project, with individual settings that can be changed using environment variables\n- Building and debugging a Django project in Docker\n- Integrated [pytest](https://docs.pytest.org) and [coverage](https://coverage.readthedocs.io) for robust testing and code quality assurance ✅\n- A ready-made docker-compose file that brings together Postgres - Django - Gunicorn - Traefik (or Caddy)\n- Serving static files (and user-uploaded files) with Nginx\n- Automatic database migration and static file collection when starting or restarting the Django container\n- Automatic creation of the first user in Django with a default login and password\n- Automatic creation and renewal of Let's Encrypt certificate 🔥\n- Minimal dependencies\n- Everything is set up as simply as possible - just a couple of commands in the terminal, and you have a working project 🚀\n\n## How to use\n\n### For development on your computer\n\n1. Clone the repository to your computer and go to the `django-docker-template` directory:\n```console\ngit clone https://github.com/amerkurev/django-docker-template.git\ncd django-docker-template\n```\n\n2. Build the Docker container image with Django:\n```console\ndocker build -t django-docker-template:master .\n```\n\n3. Create the first superuser:\n```console\ndocker run -it --rm -v sqlite:/sqlite django-docker-template:master python manage.py createsuperuser\n```\n\n4. Run the Django development server inside the Django container:\n```console\ndocker run -it --rm -p 8000:8000 -v sqlite:/sqlite -v $(pwd)/website:/usr/src/website django-docker-template:master python manage.py runserver 0.0.0.0:8000\n```\n\nNow you can go to [http://127.0.0.1:8000/admin/](http://127.0.0.1:8000/admin/) in your browser. Go to the Django admin panel and try updating the server code \"on the fly\".\nEverything works just like if you were running the Django development server outside the container.\n\n\u003e Note that we mount the directory with your source code inside the container, so you can work with the project in your IDE, and changes will be visible inside the container, and the Django development server will restart itself. \n\n\u003cdetails markdown=\"1\"\u003e\n\u003csummary\u003eSQLite Usage Details\u003c/summary\u003e\n\n\u003e Another important point is the use of SQLite3 instead of Postgres, because Postgres is not deployed until Django is run within a Docker Compose environment.\n\u003e In our example, we add a volume named `sqlite`. This data is stored persistently and does not disappear between restarts of the Django development server.\n\u003e However, if you have a second similar project, it would be better to change the volume name from `sqlite` to something else so that the second project uses its own copy of the database. For example:\n\u003e\n```console\ndocker run -it --rm -p 8000:8000 -v another_sqlite:/sqlite -v $(pwd)/website:/usr/src/website django-docker-template:master python manage.py runserver 0.0.0.0:8000\n```\n\u003e \n\u003e  To better understand how volumes work in Docker, refer to the official [documentation](https://docs.docker.com/storage/volumes/).\n\u003c/details\u003e\n\n5. Run tests with pytest and coverage ✅:\n```console\ndocker run --rm django-docker-template:master ./pytest.sh\n```\nThe [pytest.sh](https://github.com/amerkurev/django-docker-template/blob/master/website/pytest.sh) script runs tests using pytest and coverage. As a result, you will see an output like this in the terminal:\n```console\n================== test session starts =====================================\nplatform linux -- Python 3.11.7, pytest-7.4.4, pluggy-1.3.0\ndjango: version: 4.2.9, settings: website.settings (from ini)\nrootdir: /usr/src/website\nconfigfile: pytest.ini\nplugins: django-4.7.0\ncollected 10 items\n\npolls/tests.py .......... [100%]\n\n================== 10 passed in 0.19s ======================================\nName                                       Stmts   Miss  Cover   Missing\n------------------------------------------------------------------------\npolls/__init__.py                              0      0   100%\npolls/admin.py                                12      0   100%\npolls/apps.py                                  4      0   100%\npolls/migrations/0001_initial.py               6      0   100%\npolls/migrations/0002_question_upload.py       4      0   100%\npolls/migrations/__init__.py                   0      0   100%\npolls/models.py                               20      2    90%   15, 33\npolls/tests.py                                57      0   100%\npolls/urls.py                                  4      0   100%\npolls/views.py                                28      8    71%   39-58\nwebsite/__init__.py                            6      0   100%\nwebsite/settings.py                           52      2    96%   94, 197\nwebsite/urls.py                                6      0   100%\n------------------------------------------------------------------------\nTOTAL                                        199     12    94%\n```\n\n\u003e If you don't want to use pytest (for some reason), you can run the tests without pytest using the command below:\n```console\ndocker run --rm django-docker-template:master python manage.py test\n```\n\n6. Interactive shell with the Django project environment:\n```console\ndocker run -it --rm -v sqlite:/sqlite django-docker-template:master python manage.py shell\n```\n\n7. Start all services locally (Postgres, Gunicorn, Traefik) using docker-compose:\n```console\ndocker compose -f docker-compose.debug.yml up\n```\n\nEnjoy watching the lines run in the terminal 🖥️   \nAnd after a few seconds, open your browser at [http://127.0.0.1/admin/](http://127.0.0.1/admin/). The superuser with the login and password `admin/admin` is already created, welcome to the Django admin panel.\n\nDjango is still in Debug mode! You can work in your IDE, write code, and immediately see changes inside the container. However, you are currently using Traefik and Postgres.\nYou can also add Redis or MongoDB, and all of this will work in your development environment. This is very convenient.\n\n\u003e Between Docker Compose restarts, your database data and media files uploaded to the server will be preserved because they are stored in special volumes that are not deleted when containers are restarted.\n\nWant to delete everything? No problem, the command below will stop all containers, remove them and their images.\n```console\ndocker compose down --remove-orphans --rmi local\n```\n\nTo delete the Postgre database as well, add the `-v` flag to the command:\n```console\ndocker compose down --remove-orphans --rmi local -v\n```\n\n#### Django settings\n\nSome Django settings from the [`settings.py`](https://github.com/amerkurev/django-docker-template/blob/master/website/website/settings.py) file are stored in environment variables.\nYou can easily change these settings in the [`.env`](https://github.com/amerkurev/django-docker-template/blob/master/.env) file.\nThis file does not contain all the necessary settings, but many of them. Add additional settings to environment variables if needed.\n\n\u003e It is important to note the following: **never store sensitive settings such as DJANGO_SECRET_KEY or DJANGO_EMAIL_HOST_PASSWORD in your repository!**\n\u003e Docker allows you to override environment variable values from additional files, the command line, or the current session. Store passwords and other sensitive information separately from the code and only connect this information at system startup.\n\n### For deployment on a server\n\n#### Prerequisite\n\nFor the Let's Encrypt HTTP challenge you will need:\n\n- A publicly accessible host allowing connections on port `80` \u0026 `443` with docker \u0026 docker-compose installed. A virtual machine in any cloud provider can be used as a host.\n- A DNS record with the domain you want to expose pointing to this host.\n\n#### Steps on a server\n\n1. Clone the repository on your host and go to the `django-docker-template` directory:\n```console\ngit clone https://github.com/amerkurev/django-docker-template.git\ncd django-docker-template\n```\n\n2. Configure as described in the [Django settings](#django-settings) section or leave everything as is.\n\n3. Run, specifying your domain:\n```console\nMY_DOMAIN=your.domain.com docker compose -f docker-compose.yml -f docker-compose.tls.yml up -d\n```\n\nIt will take a few seconds to start the database, migrate, collect static files, and obtain a Let's Encrypt certificate. So wait a little and open https://your.domain.com in your browser. Your server is ready to work 🏆 \n\n\u003e Don't worry about renewing the Let's Encrypt certificate, it will happen automatically.\n\n4. After running the containers, you can execute [manage.py commands](https://docs.djangoproject.com/en/4.2/ref/django-admin/#available-commands) using this format:\n```console\ndocker compose exec django python manage.py check --deploy\n\ndocker compose exec django python manage.py shell\n```\n\n### Using Caddy Server Instead of Traefik\n\nTraefik is a great edge router, but it doesn't serve static files, which is why we pair it with [Nginx](https://github.com/amerkurev/django-docker-template/blob/master/docker-compose.yml#L26) in our setup.\nIf you prefer a single tool that can handle everything, you might want to try [Caddy](https://caddyserver.com).\n\nCaddy can automatically handle the creation and renewal of Let's Encrypt certificates and also serve static files, which allows you to use just one server instead of two.\n\nHere's how to set up Caddy with your project:\n\n1. Ensure you have a [`Caddyfile`](https://github.com/amerkurev/django-docker-template/blob/master/Caddyfile) in your project directory. This file will tell Caddy how to deliver static and media files and how to forward other requests to your Django app.\n\n2. Swap out the `docker-compose.yml` and `docker-compose.tls.yml` with a single [`docker-compose.caddy.yml`](https://github.com/amerkurev/django-docker-template/blob/master/docker-compose.caddy.yml). This file is designed to set up Caddy with Django and Postgres, and it doesn't include Nginx, which makes the file shorter and easier to understand.\n\n3. To get your Django project up with Caddy, run the following command, making sure to replace `your.domain.com` with your actual domain:\n\n```console\nMY_DOMAIN=your.domain.com docker compose -f docker-compose.caddy.yml up -d\n```\n\nChoosing Caddy simplifies your setup by combining the functionalities of Traefik and Nginx into one. It's straightforward and takes care of HTTPS certificates for you automatically.\nEnjoy the ease of deployment with Caddy!\n\n## What's next?\n\nNow that you have a working project, you can extend it as you like, adding [dashboards for monitoring service health](https://doc.traefik.io/traefik/operations/dashboard/), [centralized log collection](https://www.fluentd.org), [secret storage](https://www.vaultproject.io), and of course, your own Django applications.\nAll of this is beyond the scope of the current description, as the idea of this project is minimalism and providing only the essentials. Good luck!\n\n## License\n\n[MIT](https://github.com/amerkurev/django-docker-template/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famerkurev%2Fdjango-docker-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famerkurev%2Fdjango-docker-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famerkurev%2Fdjango-docker-template/lists"}