Skip to content

feat(deploy): Add Docker configuration for containerization#183

Open
arjav007 wants to merge 1 commit intoAnmol-TheDev:mainfrom
arjav007:feature/docker-support
Open

feat(deploy): Add Docker configuration for containerization#183
arjav007 wants to merge 1 commit intoAnmol-TheDev:mainfrom
arjav007:feature/docker-support

Conversation

@arjav007
Copy link

@arjav007 arjav007 commented Oct 14, 2025

This pull request resolves issue #177 by adding Docker support to the application.

Changes Made:

Added a multi-stage Dockerfile to build the Vite application and serve it with Nginx.

Added a docker-compose.yml for easy local development and startup.

Added a nginx.conf to correctly handle SPA routing.

How to Test:

Ensure Docker Desktop is running.

Run the command docker compose up --build -d.

Navigate to http://localhost:8080 in your browser.

Summary by CodeRabbit

  • New Features

    • Containerized frontend deployment using Docker and Docker Compose.
    • Production build served via Nginx with SPA routing fallback.
    • Application accessible at http://localhost:8080.
  • Chores

    • Multi-stage image build to reduce image size and improve build efficiency.
    • Automatic restart policy enabled for improved runtime stability.

This adds Dockerfile, docker-compose.yml, and an Nginx configuration to allow the application to be built and run in a container. Closes Anmol-TheDev#177.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

Warning

.coderabbit.yml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
end of the stream or a document separator is expected in ".coderabbit.yml" (17:1)

 14 | file_path_instructions:
 15 | - path: "src/**/*.{js,jsx,ts,tsx}"
 16 | instructions: |
 17 | - Components should be function ...
------^
 18 | - Use appropriate hooks for sta ...
 19 | - Implement proper loading stat ...
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

Introduces containerization for a frontend SPA: a two-stage Dockerfile builds with Node/pnpm and serves via Nginx, an Nginx config enables SPA routing, and a Docker Compose file defines a single service exposing the app on host port 8080 with restart policy.

Changes

Cohort / File(s) Summary of Changes
Docker orchestration
Docker-compose.yml
Adds Compose v3.8 config with service music-app-frontend: builds from current directory, names container music_app_container, maps 8080:80, sets restart: unless-stopped, with inline comments.
Image build pipeline
Dockerfile
Adds multi-stage build: Node 20-alpine builder installs pnpm, installs deps, builds Vite app to dist; final stage nginx:stable-alpine serves dist, copies custom nginx.conf, exposes 80.
Web server config
nginx.conf
Adds Nginx server block on 80 serving /usr/share/nginx/html with SPA fallback via try_files ... /index.html.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant DC as Docker Compose
  participant DF as Dockerfile (Node builder)
  participant NX as Nginx Container
  participant Br as Browser

  Dev->>DC: docker compose up --build
  DC->>DF: Build image (pnpm install, pnpm build)
  DF-->>DC: Produce image with /usr/share/nginx/html (dist)
  DC->>NX: Run container (port 80 exposed)
  NX-->>DC: Service ready on 80
  DC-->>Br: Host port 8080 forwards to container 80
  Br->>NX: GET /route
  NX->>NX: try_files $uri /index.html
  NX-->>Br: Serve index.html or static asset
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I built a burrow, neat and light,
With Docker drums and Nginx bright.
Vite winds whisk bits to dist,
Ports align—no fuss, no twist.
I thump my paw: “Compose, ignite!”
Now snacks and SPA serve through the night. 🥕🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the primary change of adding Docker configuration for containerization and follows conventional commit style, accurately reflecting the addition of Dockerfile, docker-compose, and related deployment settings without extraneous detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@Anmol-TheDev
Copy link
Owner

@arjav007 can you tell me a reason to Dockerize this project

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (8)
nginx.conf (1)

3-20: Add security headers and performance optimizations.

The basic SPA routing configuration is correct, but consider adding:

  1. Security headers to protect against common vulnerabilities:

    • X-Frame-Options to prevent clickjacking
    • X-Content-Type-Options to prevent MIME sniffing
    • Content-Security-Policy for XSS protection
    • Referrer-Policy to control referrer information
  2. Gzip compression to reduce bandwidth and improve load times

  3. Caching headers for static assets (JS, CSS, images) to improve performance

Apply this diff to enhance security and performance:

 server {
   # Listen on port 80, the standard HTTP port
   listen 80;
 
+  # Security headers
+  add_header X-Frame-Options "SAMEORIGIN" always;
+  add_header X-Content-Type-Options "nosniff" always;
+  add_header X-XSS-Protection "1; mode=block" always;
+  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+
+  # Enable gzip compression
+  gzip on;
+  gzip_vary on;
+  gzip_min_length 1024;
+  gzip_types text/plain text/css text/xml text/javascript application/javascript application/json;
+
   # The root directory where our static files are located
   root /usr/share/nginx/html;
 
   # The default file to serve
   index index.html;
 
   # This block is key for SPA routing (like with React Router)
   location / {
     # Try to serve the requested file ($uri), then a directory ($uri/),
     # and if neither is found, fall back to serving index.html.
     # This allows the client-side router to handle the URL.
     try_files $uri $uri/ /index.html;
   }
+
+  # Cache static assets
+  location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
+    expires 1y;
+    add_header Cache-Control "public, immutable";
+  }
 }
Dockerfile (4)

8-8: Pin the pnpm version for reproducibility.

Installing the latest version of pnpm may lead to inconsistent builds if breaking changes are introduced in future versions.

Apply this diff to pin the pnpm version:

-RUN npm install -g pnpm
+RUN npm install -g pnpm@9.15.0

Note: Check your local pnpm version with pnpm --version and use that version here for consistency.


11-21: Optimize Docker layer caching.

Copying the entire source code (line 17) before the build invalidates the cache whenever any source file changes, even if dependencies haven't changed. This works but could be more efficient.

Consider moving non-essential files to a later COPY step if you want to maximize cache hits, though for most projects the current approach is acceptable:

 # Copy package and lock files
 COPY package.json pnpm-lock.yaml ./
 
 # Install dependencies using pnpm
 RUN pnpm install
 
-# Copy the rest of the application source code
-COPY . .
+# Copy only necessary source files for the build
+COPY src ./src
+COPY public ./public
+COPY index.html vite.config.js tsconfig.json ./
 
 # Build the application for production
 # This creates a 'dist' folder with the static files
 RUN pnpm run build

Alternatively, create a .dockerignore file to exclude unnecessary files from the build context (recommended approach).


1-38: Add health check for container monitoring.

A health check allows Docker to verify that the Nginx server is responding correctly, which is useful for orchestration and monitoring.

Add this to the final stage:

 # Expose port 80 to the outside world
 EXPOSE 80
 
+# Health check to ensure nginx is serving correctly
+HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+  CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
+
 # The default command for the nginx image is to start the server,
 # so we don't need to specify a CMD.

1-21: Consider adding a .dockerignore file.

Without a .dockerignore file, all files in the build context are sent to the Docker daemon, including node_modules, .git, build artifacts, etc., which can slow down the build and increase the image size.

Do you want me to generate a recommended .dockerignore file for this project?

Docker-compose.yml (3)

4-8: Inconsistent naming convention.

The service name uses hyphens (music-app-frontend) while the container name uses underscores (music_app_container). For consistency and better readability, use the same naming pattern.

Apply this diff to align naming:

   music-app-frontend:
     # Build the Docker image from the Dockerfile in the current directory (.)
     build: .
     # A friendly name for the container
-    container_name: music_app_container
+    container_name: music-app-frontend

3-13: Add health check to Docker Compose configuration.

While health checks can be defined in the Dockerfile, specifying them in docker-compose.yml allows for environment-specific configuration and better monitoring in development.

Apply this diff to add a health check:

   music-app-frontend:
     # Build the Docker image from the Dockerfile in the current directory (.)
     build: .
     # A friendly name for the container
     container_name: music_app_container
     ports:
       # Map port 8080 on the host machine to port 80 in the container
       - "8080:80"
     # Restart the container automatically unless it is manually stopped
     restart: unless-stopped
+    healthcheck:
+      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
+      interval: 30s
+      timeout: 3s
+      retries: 3
+      start_period: 5s

3-13: Consider adding resource limits for production readiness.

Adding resource limits prevents the container from consuming excessive host resources and helps with capacity planning.

Apply this diff to add resource limits:

   music-app-frontend:
     # Build the Docker image from the Dockerfile in the current directory (.)
     build: .
     # A friendly name for the container
     container_name: music_app_container
     ports:
       # Map port 8080 on the host machine to port 80 in the container
       - "8080:80"
     # Restart the container automatically unless it is manually stopped
     restart: unless-stopped
+    deploy:
+      resources:
+        limits:
+          cpus: '0.5'
+          memory: 512M
+        reservations:
+          cpus: '0.25'
+          memory: 256M

Note: Adjust these values based on your application's actual resource needs.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db8c7a2 and a30b8b1.

📒 Files selected for processing (3)
  • Docker-compose.yml (1 hunks)
  • Dockerfile (1 hunks)
  • nginx.conf (1 hunks)

@arjav007
Copy link
Author

Hey @Anmol-TheDev my main motivation was to lower the barrier to entry for new and future contributors.

By containerizing the app, anyone can get a fully working development environment with a single command. This avoids the frustration of manual setup and ensures that everyone is building and testing in the exact same environment, which should make future contributions much smoother.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants