🧱 Lecture 10 : Dockerizing the Full Stack Application

Source: Dev.to | Dec 22, 2025 (UTC)

Series: From Code to Cloud: Building a Production-Ready .NET Application
By: Farrukh Rehman – Senior .NET Full Stack Developer / Team Lead
LinkedIn: https://linkedin.com/in/farrukh-rehman
GitHub: https://github.com/farrukh1212cs

Source Code Backend : https://github.com/farrukh1212cs/ECommerce-Backend.git

Source Code Frontend : https://github.com/farrukh1212cs/ECommerce-Frontend.git

🎯 Introduction
In modern software engineering, containerization is a fundamental skill for building portable, scalable, and DevOps-friendly applications. By packaging both the .NET 8 backend API and the Angular Admin Panel inside Docker containers, we ensure that the entire application stack can run consistently across any environment—local, QA, staging, or production—without dependency conflicts or manual setup.

This lesson focuses exclusively on:

  • Creating a Dockerfile for the .NET 8 E-Commerce API
  • Creating a Dockerfile for the Angular Admin App (using the Mantis free template)
  • Running both applications in isolated Docker containers
  • Configuring docker-compose to orchestrate both services together

After completing this lesson, you will be able to launch the entire backend + admin panel with one command:

docker-compose up --build -d

This is an essential step toward production readiness and CI/CD automation in future lessons.

Section 1 — Dockerizing the .NET 8 Backend API

FIRST OF ALL WE NEED TO UPDATE PROGRAM FILE FOR AUTO RUN MIGRATIONS

We will create a multi-stage Dockerfile that:

  1. Restores dependencies
  2. Publishes the project
  3. Runs the optimized build inside ASP.NET Core runtime

Step 1.1 — Create Dockerfile in your API project root

Location:
Path : “/ECommerce.API/Dockerfile”
Right-click the API project, select Add, and then choose Container Support to enable containerization for the service.

Lets Configure Docker Containers to connect each other.

First Create Docker Network
docker network create ecommerce-net

Lets Connect Postgres to this Network (ecommerce-net)
docker network connect ecommerce-net postgres

Now time to connect RabbitMQ to network (ecommerce-net)
docker network connect ecommerce-net rabbitmq

Its time to connect Redis with the network (ecommerce-net)

docker network connect ecommerce-net ecommerce-redis

Last setp lets verify Network

docker inspect ecommerce-net

All Containers are Connected with our network.now its time to work on api side.

  1. Copy all configuration values from appsettings.json into appsettings.Development.json

  2. Update appsettings.Development.json Replace localhost from ConnectionStrings:PostgreSQL to ContainerName (postgres)

  3. Update Redis localhost to ContainerName (ecommerce-redis)

  4. Update RabbitMQ localhost to ContainerName (rabbitmq)

Lets try to Build Image (make sure docker is running)

docker build -t ecommerce-api -f ECommerce.API/Dockerfile .

docker images

Run the API Container

docker run -p 5000:8080 --name ecommerce-api-container --network ecommerce-net -e ASPNETCORE_ENVIRONMENT=Development ecommerce-api

Its time to Test Swagger our container is accessable on port 5000

Lets start working on angular containerization
we need to create four files
Dockerfile,.dockerignore,nginx.conf,environment.prod.ts
Path: “ecommerce-backoffice\Dockerfile”

FROM node:20.19-alpine AS build WORKDIR /app # Install dependencies (use npm ci for reproducible installs) COPY package.json package-lock.json* ./ RUN npm ci --silent || npm install --silent # Copy source and build the Angular app COPY . . RUN npm run build -- --configuration=production FROM nginx:stable-alpine # Remove default nginx static assets RUN rm -rf /usr/share/nginx/html/* # Copy built Angular app from the builder stage COPY --from=build /app/dist/sakai-ng/browser /usr/share/nginx/html # Expose port 80 EXPOSE 80 # Start nginx in the foreground CMD ["nginx", "-g", "daemon off;"]

Enter fullscreen mode

Exit fullscreen mode

Path: “ecommerce-backoffice.dockerignore”
.dockerignore

node_modules dist .git .gitignore Dockerfile docker-compose*.yml docker-compose*.yaml README.md *.log .vscode .idea coverage tmp out-tsc # keep source files included so the build can run

Enter fullscreen mode

Exit fullscreen mode

Path: “ecommerce-backoffice\nginx.conf”
nginx.conf

server { listen 80; server_name localhost; # Serve the Angular app location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; add_header Cache-Control "no-cache, no-store, must-revalidate"; } # Proxy API requests to your backend location /api/ { proxy_pass https://host.docker.internal:7104; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; # Disable SSL verification (for self-signed certs in local dev) proxy_ssl_verify off; proxy_ssl_session_reuse on; } }

Enter fullscreen mode

Exit fullscreen mode

Path: “ecommerce-backoffice\src\environments\environment.prod.ts”
environment.prod.ts

export const environment = { production: true, // API requests are proxied through nginx to the backend baseUrl: 'http://localhost:7104/api' };

Enter fullscreen mode

Exit fullscreen mode

Its time to build Angular Image

docker build -t sakai-ng:latest .

docker images docker run --rm -p 80:80 sakai-ng:latest

Enter fullscreen mode

Exit fullscreen mode

Final Step Lets Write docker-compose.yml

networks: ecommerce-net: external: true services: postgres: image: postgres:15 container_name: postgres restart: unless-stopped environment: POSTGRES_DB: ECommerceDb POSTGRES_USER: postgres POSTGRES_PASSWORD: Admin123! ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data networks: - ecommerce-net rabbitmq: image: rabbitmq:3-management container_name: rabbitmq restart: unless-stopped ports: - "5672:5672" - "15672:15672" networks: - ecommerce-net redis: image: redis:7 container_name: ecommerce-redis restart: unless-stopped ports: - "6379:6379" networks: - ecommerce-net ecommerce-api: image: ecommerce-api container_name: ecommerce-api-container restart: unless-stopped ports: - "7104:8080" environment: ASPNETCORE_ENVIRONMENT: Development ConnectionStrings__PostgreSQL: Host=postgres;Port=5432;Database=ECommerceDb;Username=postgres;Password=Admin123! Redis__Host: redis RabbitMQ__Host: rabbitmq depends_on: - postgres - rabbitmq - redis networks: - ecommerce-net sakai-ng: image: sakai-ng:latest container_name: sakai-ng restart: unless-stopped ports: - "80:80" depends_on: - ecommerce-api networks: - ecommerce-net volumes: postgres_data:

Enter fullscreen mode

Exit fullscreen mode

Lets Test from UI

Next Lecture Preview
Lecture 11 : Continuous Integration with Jenkins

Creating CI/CD pipelines in Jenkins for automated build, test, and deployment workflows.

For further actions, you may consider blocking this person and/or reporting abuse

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Читайте також