DEV Community

Kiran Parajuli
Kiran Parajuli

Posted on • Updated on

Dockerizing Your Django Vue Application: A Step-by-Step Guide

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
Enter fullscreen mode Exit fullscreen mode

Dockerfile for Django Application

For the Django application, we'll make the following assumptions:

  1. Port to expose: 8000
  2. Serve using: gunicorn
  3. 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"
Enter fullscreen mode Exit fullscreen mode

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:

  1. Port to expose: 8000
  2. Serve using: Gunicorn
  3. Database: PostgreSQL
  4. 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"]
Enter fullscreen mode Exit fullscreen mode

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:

  1. Port to expose: 3000
  2. Serve using: Vite

To make it work with Docker, add the following to your package.json:

{
    "scripts": {
        "dev:docker": "vite --host"
    }
}
Enter fullscreen mode Exit fullscreen mode

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"]
Enter fullscreen mode Exit fullscreen mode

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:
Enter fullscreen mode Exit fullscreen mode

To break it down:

  1. We use depends_on and healthcheck to ensure dependent services are up and running before starting. PostgreSQL is used as the database for the Django application, so we ensure that the postgres service is operational before launching the backend service. A similar approach is used for the frontend service.
  2. 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.
  3. Ports are exposed to make container ports accessible from the host machine. In this configuration, we've mapped 8000 and 3000 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Conclusion

Congratulations, you've successfully dockerized your Django Vue application! Now, you can deploy it to your preferred cloud provider or use it for the development environment. Happy coding!

Top comments (1)

Collapse
 
queen_of_engineers42 profile image
Sarah Murray • Edited

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.
Image description

So I followed the recommendation in this thread to use a pnpm override in my package.json and now it's generating this error:
Image description

Any suggestions?