In this comprehensive guide, we will walk you through the process of dockerizing your Django and Vue applications.
Prerequisites
- Docker (version 20.x.x or higher)
- Docker-compose (version 2.x.x or higher)
- Django application (Django + Gunicorn)
- Vue application (Vue + Vite)
Folder Structure
To facilitate this guide, we assume the following folder structure for your project. You can customize it as needed, but remember to adjust the commands accordingly:
.
├── backend (Django application)
│ ├── Dockerfile
├── frontend (vue application)
│ ├── Dockerfile
├── docker-compose.yml
Dockerfile for Django Application
For the Django application, we'll make the following assumptions:
- Port to expose:
8000
- Serve using:
gunicorn
- Database:
postgres
Gunicorn Configuration
workers = 4
max_requests = 1000
timeout = 30
bind = "0.0.0.0:8000"
preload_app = True
accesslog = "logs/gunicorn_access.log"
errorlog = "logs/gunicorn_error.log"
Note: We use 0.0.0.0
for binding to allow access from outside the container.
Dockerfile for Backend
In this section, we'll prepare the playground for your Django application. We will use Docker Compose to run the application. Here are the assumptions:
- Port to expose:
8000
- Serve using:
Gunicorn
- Database:
PostgreSQL
- Dependencies Listed in:
requirements.txt
FROM python:3.10
WORKDIR /app
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8000
CMD ["gunicorn", "backend.wsgi:application", "--config", "gunicorn.py"]
Note: We won't copy all files to the container; instead, we'll use volumes to mount files from Docker Compose to preserve hot-reloading functionality.
Dockerfile for Frontend
Similarly, we'll prepare the playground for your Vue application. We will use Docker Compose to run the application. For Vue, we'll assume:
- Port to expose:
3000
- Serve using:
Vite
To make it work with Docker, add the following to your package.json
:
{
"scripts": {
"dev:docker": "vite --host"
}
}
Note: We use vite
with the --host
flag to make it accessible from outside the container.
FROM node:20-alpine3.17
WORKDIR /app
COPY package.json pnpm-lock.yaml /app/
RUN npm install -g pnpm
RUN pnpm install
EXPOSE 3000
CMD ["pnpm", "dev:docker"]
Just like with the Django application, we won't copy all files to the container, relying on Docker Compose volumes for file mounting to maintain hot-reloading.
Docker compose
Now, let's dive into Docker Compose to run your application.
version: '3.8'
services:
postgres:
container_name: db
image: postgres:16.0-alpine
restart: always
environment:
POSTGRES_USER: einstein
POSTGRES_PASSWORD: relativity
POSTGRES_DB: einstein
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: [ "CMD", "pg_isready", "-U", "einstein" ]
interval: 5s
timeout: 5s
retries: 5
ports:
- "5433:5432"
backend:
container_name: backend
build:
context: ./backend
volumes:
- ./backend/:/app
- ./backend/.env.docker:/app/.env
- ./backend/logs:/app/logs
depends_on:
postgres:
condition: service_healthy
ports:
- "8000:8000"
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8000/healthcheck" ]
interval: 5s
timeout: 5s
retries: 5
frontend:
container_name: web
build:
context: ./frontend
volumes:
- ./frontend:/app
- ./frontend/.env.example:/app/.env
depends_on:
backend:
condition: service_healthy
ports:
- "3000:3000"
volumes:
pgdata:
media:
static:
To break it down:
- We use
depends_on
andhealthcheck
to ensure dependent services are up and running before starting. PostgreSQL is used as the database for the Django application, so we ensure that thepostgres
service is operational before launching thebackend
service. A similar approach is used for thefrontend
service. - Volumes are employed to mount files from the host machine to the container. We mount backend and frontend folders to their respective containers and include the
.env.docker
file containing environment variables. - Ports are exposed to make container ports accessible from the host machine. In this configuration, we've mapped
8000
and3000
from the backend and frontend containers, respectively. Additionally, PostgreSQL's port is mapped to 5433 on the host to avoid conflicts.
Running the application
With everything set up, it's time to run your application:
docker compose up
This command will spin up PostgreSQL with the specified database and user. It will also start the backend and frontend services. Access your application at http://localhost:3000
.
To run migrations, execute the following command:
docker compose exec backend python manage.py migrate
The choice to run migrations after the application is up allows for easy updates to models without manual migration execution.
To create a superuser, run:
docker compose exec backend python manage.py createsuperuser
Avoid putting superuser creation in the Dockerfile to prevent errors if the superuser already exists.
To collect static files, use this command:
docker compose exec backend python manage.py collectstatic
Top comments (1)
I'm having an issue with vite/pnpm where it is refusing to find the
@rollup/linux
binary even though it's installed. Attached image of error below.So I followed the recommendation in this thread to use a pnpm override in my package.json and now it's generating this error:
Any suggestions?