All Projects → nickjj → Docker Django Example

nickjj / Docker Django Example

Licence: mit
A production ready example Django app that's using Docker and Docker Compose.

Programming Languages

shell
77523 projects

Projects that are alternatives of or similar to Docker Django Example

Banking System
A banking System Created Using Django Python Web Framework
Stars: ✭ 105 (+22.09%)
Mutual labels:  redis, django, celery, tailwindcss
Docker Django
A complete docker package for deploying django which is easy to understand and deploy anywhere.
Stars: ✭ 378 (+339.53%)
Mutual labels:  redis, postgres, django, celery
Django Celery Docker Example
Example Docker setup for a Django app behind an Nginx proxy with Celery workers
Stars: ✭ 149 (+73.26%)
Mutual labels:  postgres, django, celery, docker-compose
Chain
链喵 CMDB 本项目已停止开发!因长时间未对代码进行维护,可能会造成项目在不同环境上无法部署、运行BUG等问题,请知晓!项目仅供参考!
Stars: ✭ 240 (+179.07%)
Mutual labels:  redis, django, celery
Django Channels React Multiplayer
turn based strategy game using django channels, redux, and react hooks
Stars: ✭ 52 (-39.53%)
Mutual labels:  redis, django, docker-compose
Dailyfresh B2c
dailyfresh mall based on B2C model
Stars: ✭ 177 (+105.81%)
Mutual labels:  redis, django, celery
Django School Management
Deployment Ready Developer to Developer Full-stack School Management System with payments, e-admission, result management, academic functionalities, and much more implemented in a simple way.
Stars: ✭ 151 (+75.58%)
Mutual labels:  redis, django, celery
Todolist Frontend Vuejs
Front-end application for Todolist Web application built with Laravel and Vue.js
Stars: ✭ 120 (+39.53%)
Mutual labels:  webpack, docker-compose, tailwindcss
Ecommerce website development
本项目基于Django1.8.2等来开发一个电商平台,可实现注册、登录、浏览、购买、支付等全部常用功能。
Stars: ✭ 246 (+186.05%)
Mutual labels:  redis, django, celery
Pychat
webchat via WebSockets/WebRTC that allows messaging/video call/screen sharing
Stars: ✭ 152 (+76.74%)
Mutual labels:  webpack, redis, django
Endoflife.date
Informative site with EoL dates of everything
Stars: ✭ 296 (+244.19%)
Mutual labels:  redis, postgres, django
Enferno
A Python framework based on Flask microframework, with batteries included, and best practices in mind.
Stars: ✭ 385 (+347.67%)
Mutual labels:  redis, celery, docker-compose
Docker Flask Celery Redis
Docker-Compose template for orchestrating a Flask app with a Celery queue using Redis
Stars: ✭ 165 (+91.86%)
Mutual labels:  redis, celery, docker-compose
Docker Compose
一些基础服务的docker-compose配置文件,方便在一台新电脑上快速开始工作
Stars: ✭ 163 (+89.53%)
Mutual labels:  redis, postgres, docker-compose
Website
django 开发的BBS博客项目, 此项目包含多用户注册,话题模块,发布文章,文章评论,课程、社区BBS以及消息提示,关注,采用邮箱注册,激活验证登录,以及QQ注册登录,招募作者发布教程在后台管理系统发布, pc采用模板渲染,cms采用vue drf前后分离,登录采用JWT认证登录、移动端采用react开发,
Stars: ✭ 217 (+152.33%)
Mutual labels:  redis, django, celery
Fastapi Celery
Minimal example utilizing fastapi and celery with RabbitMQ for task queue, Redis for celery backend and flower for monitoring the celery tasks.
Stars: ✭ 154 (+79.07%)
Mutual labels:  redis, celery, docker-compose
Django Project Template
Thorgate's Django project template - Django, React, Sass, optional Docker and more
Stars: ✭ 91 (+5.81%)
Mutual labels:  webpack, django, docker-compose
Docker Superset
Repository for Docker Image of Apache-Superset. [Docker Image: https://hub.docker.com/r/abhioncbr/docker-superset]
Stars: ✭ 86 (+0%)
Mutual labels:  redis, celery, docker-compose
Dailyfresh
Django-天天生鲜电商学习项目
Stars: ✭ 127 (+47.67%)
Mutual labels:  redis, django, celery
Docker Django Webpack Skeleton
Django Skeleton W/ Docker Dev & Production W/ Webpack 2 W/ BabelJS W/ Sass W/ PostgreSQL
Stars: ✭ 191 (+122.09%)
Mutual labels:  webpack, django, docker-compose

An example Django + Docker app

CI

You could use this example app as a base for your new project or as a guide to Dockerize your existing Django app.

The example app is minimal but it wires up a number of things you might use in a real world Django app, but at the same time it's not loaded up with a million personal opinions.

For the Docker bits, everything included is an accumulation of Docker best practices based on building and deploying dozens of assorted Dockerized web apps since late 2014.

This app is using Django 3.1.7 and Python 3.9.2. The screenshot doesn't get updated every time I bump the versions:

Screenshot

Table of contents

Tech stack

If you don't like some of these choices that's no problem, you can swap them out for something else on your own.

Back-end

Front-end

But what about JavaScript?!

Picking a JS library is a very app specific decision because it depends on which library you like and it also depends on if your app is going to be mostly Jinja templates with sprinkles of JS or an API back-end.

This isn't an exhaustive list but here's a few reasonable choices depending on how you're building your app:

On the bright side with Webpack being set up you can use any (or none) of these solutions very easily. You could follow a specific library's Webpack installation guides to get up and running in no time.

Personally I'm going to be using Hotwire Turbo + Stimulus in most newer projects.

Notable opinions and extensions

Django is an opinionated framework and I've added a few extra opinions based on having Dockerized and deployed a number of Django projects. Here's a few (but not all) note worthy additions and changes.

  • Packages and extensions:
    • gunicorn for an app server in both development and production
    • whitenoise for serving static files
  • Linting and testing:
    • flake8 is used to lint the code base
  • Django apps:
    • Add pages app with a / page and /up health check endpoint
  • Config:
    • Log to STDOUT so that Docker can consume and deal with log output
    • Extract a bunch of configuration settings into environment variables
    • src/hello/settings.py and the .env file handles configuration in all environments
  • Front-end assets:
    • assets/ contains all your CSS, JS, images, fonts, etc. and is managed by Webpack
    • Custom 502.html and maintenance.html pages
    • Generate favicons using modern best practices
  • Django defaults that are changed:
    • Use Redis as the default Cache back-end
    • Use signed cookies as the session back-end
    • public/ is the static directory where Django will serve static files from
    • public_collected/ is where collectstatic will write its files to

Besides the Django app itself:

  • Docker support has been added which would be any files having *docker* in its name
  • GitHub Actions have been set up
  • A requirements-lock.txt file has been introduced using pip3. The management of this file is fully automated by the commands found in the run file. We'll cover this in more detail when we talk about updating dependencies.

Running this app

You'll need to have Docker installed. It's available on Windows, macOS and most distros of Linux. If you're new to Docker and want to learn it in detail check out the additional resources links near the bottom of this README.

If you're using Windows, it will be expected that you're following along inside of WSL or WSL 2. That's because we're going to be running shell commands. You can always modify these commands for PowerShell if you want.

Clone this repo anywhere you want and move into the directory:

git clone https://github.com/nickjj/docker-django-example hellodjango
cd hellodjango

# Optionally checkout a specific tag, such as: git checkout 0.2.0

Copy a few example files because the real files are git ignored:

cp .env.example .env
cp docker-compose.override.yml.example docker-compose.override.yml

Build everything:

The first time you run this it's going to take 5-10 minutes depending on your internet connection speed and computer's hardware specs. That's because it's going to download a few Docker images and build the Python + Yarn dependencies.

docker-compose up --build

Now that everything is built and running we can treat it like any other Django app.

Did you receive an error about a port being in use? Chances are it's because something on your machine is already running on port 8000. Check out the docs in the .env file for the DOCKER_WEB_PORT_FORWARD variable to fix this.

Setup the initial database:

# You can run this from a 2nd terminal.
./run manage migrate 

We'll go over that ./run script in a bit!

Check it out in a browser:

Visit http://localhost:8000 in your favorite browser.

Not seeing any CSS? That means Webpack is still compiling. Give it a few more seconds and reload. It should self resolve.

Linting the code base:

# You should get no output (that means everything is operational).
./run flake8

Running the test suite:

# You should see all passing tests. Warnings are typically ok.
./run manage test

Stopping everything:

# Stop the containers and remove a few Docker related resources associated to this project.
docker-compose down

You can start things up again with docker-compose up and unlike the first time it should only take seconds.

Files of interest

I recommend checking out most files and searching the code base for TODO:, but please review the .env and run files before diving into the rest of the code and customizing it. Also, you should hold off on changing anything until we cover how to customize this example app's name with an automated script (coming up next in the docs).

.env

This file is ignored from version control so it will never be commit. There's a number of environment variables defined here that control certain options and behavior of the application. Everything is documented there.

Feel free to add new variables as needed. This is where you should put all of your secrets as well as configuration that might change depending on your environment (specific dev boxes, CI, production, etc.).

run

You can run ./run to get a list of commands and each command has documentation in the run file itself.

It's a shell script that has a number of functions defined to help you interact with this project. It's basically a Makefile except with less limitations. For example as a shell script it allows us to pass any arguments to another program.

This comes in handy to run various Docker commands because sometimes these commands can be a bit long to type. Feel free to add as many convenience functions as you want. This file's purpose is to make your experience better!

If you get tired of typing ./run you can always create a shell alias with alias run=./run in your ~/.bash_aliases or equivalent file. Then you'll be able to run run instead of ./run.

Making this app your own

The app is named hello right now but chances are your app will be a different name. Since the app is already created we'll need to do a find / replace on a few variants of the string "hello" and update a few Docker related resources.

You can do that from the command line without needing to install any extra dependencies by following the instructions below.

Remove the original Docker resources:

When the hello app was first upped with Docker Compose a new database, user and password was created automatically based on the values of certain environment variables.

Along with that a few Docker resources were created too. Those need to be updated. The easiest way to do that is by removing the old Docker resources and deleting the database. We can do all of that in 1 command.

Don't worry, you won't have to wait 5-10 minutes again when you up your newly named project. Docker still that information safely tucked away and it can be re-used in projects with different names.

# This removes the PostgreSQL database volume along with a few other Docker
# resources that were created and are associated to the hello app.
docker-compose down -v

Run these commands from the same directory as this git repo:

# Change hello to be whatever you want your app name to be.
#
# After renaming this value, paste this variable into your terminal.
lower=hello

# If you wanted a multi-word app name you could do:
# lower=my_app
#
# or:
#
# lower=myapp
#
# The choice is yours!

# Recursively replace hello using the values defined above.
#
# You don't need to edit this command before running it in your terminal.
find . -type f -exec perl -i -pe "s/(hellodjango|hello)/${lower}/g" {} + \
  && mv src/hello/ src/"${lower}"

If you're not comfortable running these commands or they don't work for whatever reason, you can also do a case sensitive find / replace within your code editor too. There's nothing special going on here. It's literally replacing "hellodjango" and "hello" with your lowercase app name and then renaming a directory.

Verify everything was changed successfully:

grep -ER --exclude-dir public/ --exclude-dir public_collected/ hello .

You should get back no output. That means all occurrences of hello were replaced.

grep -ER --exclude README.md --exclude-dir .git/ --exclude-dir .webpack_cache/ \
  --exclude-dir assets/node_modules/ \
  --exclude-dir public/ --exclude-dir public_collected/ "${lower}" .

You should get back a bunch of output showing you where your app name is referenced within the project.

Remove the .git directory and init a new git repo:

This project is not meant to be a long running fork. It's your freshly minted project that is ready for you to start modifying based on whatever cool app you want to build.

rm -rf .git/
git init

# Optionally use main as a branch instead of master. CI is configured to work
# with both main and master btw.
git symbolic-ref HEAD refs/heads/main

Start and setup the project:

We don't need to rebuild anything yet. Upping it is enough for Docker to re-create new resources with the new name. We'll also need to setup our database since a new one will be created for us by Docker.

docker-compose up

# Then in a 2nd terminal once it's up and ready.
./run manage migrate

Sanity check to make sure the tests still pass:

It's always a good idea to make sure things are in a working state before adding custom changes.

# You can run this from the same terminal as before.
./run flake8
./run manage test

If everything passes now you can optionally git add -A && git commit -m "Initial commit" and start customizing your app. Alternatively you can wait until you develop more of your app before committing anything. It's up to you!

Tying up a few loose ends:

You'll probably want to create a fresh CHANGELOG.md file for your project. I like following the style guide at https://keepachangelog.com/ but feel free to use whichever style you prefer.

Since this project is MIT licensed you should keep my name and email address in the LICENSE file to adhere to that license's agreement, but you can also add your name and email on a new line.

If you happen to base your app off this example app or write about any of the code in this project it would be rad if you could credit this repo by linking to it. If you want to reference me directly please link to my site at https://nickjanetakis.com. You don't have to do this, but it would be very much appreciated!

Updating dependencies

Let's say you've customized your app and it's time to make a change to your requirements.txt or package.json file.

Without Docker you'd normally run pip3 install -r requirements.txt or yarn install. With Docker it's basically the same thing and since these commands are in our Dockerfile we can get away with doing a docker-compose build but don't run that just yet.

In development:

You can run ./run pip3:outdated or ./run yarn:outdated to get a list of outdated dependencies based on what you currently have installed. Once you've figured out what you want to update, go make those updates in your requirements.txt and / or assets/package.json file.

Then to update your dependencies you can run ./run pip3:install or ./run yarn:install. That'll make sure any lock files get copied from Docker's image (thanks to volumes) into your code repo and now you can commit those files to version control like usual.

You can check out the run file to see what these commands do in more detail.

As for the requirements' lock file, this ensures that the same exact versions of every package you have (including dependencies of dependencies) get used the next time you build the project. This file is the output of running pip3 freeze. You can check how it works by looking at bin/pip3-install.

You should never modify the lock files by hand. Add your top level Python dependencies to requirements.txt and your top level JavaScript dependencies to assets/package.json, then run the ./run command(s) mentioned earlier.

In CI:

You'll want to run docker-compose build since it will use any existing lock files if they exist. You can also check out the complete CI test pipeline in the run file under the ci:test function.

In production:

This is usually a non-issue since you'll be pulling down pre-built images from a Docker registry but if you decide to build your Docker images directly on your server you could run docker-compose build as part of your deploy pipeline.

See a way to improve something?

If you see anything that could be improved please open an issue or start a PR. Any help is much appreciated!

Additional resources

Now that you have your app ready to go, it's time to build something cool! If you want to learn more about Docker, Django and deploying a Django app here's a couple of free and paid resources. There's Google too!

Learn more about Docker and Django

Official documentation

Courses / books

Deploy to production

I'm creating an in-depth course related to deploying Dockerized web apps. If you want to get notified when it launches with a discount and potentially get free videos while the course is being developed then sign up here to get notified.

About the author

I'm a self taught developer and have been freelancing for the last ~20 years. You can read about everything I've learned along the way on my site at https://nickjanetakis.com.

There's hundreds of blog posts and a couple of video courses on web development and deployment topics. I also have a podcast where I talk with folks about running web apps in production.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].