Docker
What is Docker?
Docker is a platform for developing, shipping, and running applications in containers. Containers package an application with all its dependencies, ensuring it runs consistently across different environments.
Dockerfile
# Angular Application
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build --prod
FROM nginx:alpine
COPY --from=build /app/dist/my-app /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]# .NET Application
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "./"]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/publish .
EXPOSE 80
ENTRYPOINT ["dotnet", "MyApp.dll"]# Node.js Application
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]Docker Commands
# Build image
docker build -t myapp:latest .
# Run container
docker run -d -p 3000:3000 --name myapp myapp:latest
# List containers
docker ps
docker ps -a
# Stop container
docker stop myapp
# Remove container
docker rm myapp
# View logs
docker logs myapp
docker logs -f myapp # Follow
# Execute command in container
docker exec -it myapp sh
# Remove image
docker rmi myapp:latestMulti-Stage Builds
# Optimized build
FROM node:18 AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:18 AS build
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:18-alpine AS production
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=dependencies /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]Docker Compose
# docker-compose.yml
version: '3.8'
services:
# Angular frontend
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "4200:80"
depends_on:
- api
# .NET API
api:
build:
context: ./api
dockerfile: Dockerfile
ports:
- "5000:80"
environment:
- ConnectionStrings__DefaultConnection=Server=db;Database=myapp;User=sa;Password=YourPassword123
depends_on:
- db
# Node.js service
service:
build:
context: ./service
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:postgres@postgres:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
- postgres
- redis
# SQL Server
db:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=YourPassword123
ports:
- "1433:1433"
volumes:
- sqldata:/var/opt/mssql
# PostgreSQL
postgres:
image: postgres:15
environment:
- POSTGRES_PASSWORD=postgres
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
# MongoDB
mongodb:
image: mongo:6
ports:
- "27017:27017"
volumes:
- mongodata:/data/db
# Redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
sqldata:
pgdata:
mongodata:Docker Networking
# Create network
docker network create myapp-network
# Run containers on same network
docker run -d --name api --network myapp-network api:latest
docker run -d --name frontend --network myapp-network frontend:latest
# Containers can communicate using service names
# frontend can access: http://api:5000Environment Variables
# Dockerfile with env vars
FROM node:18-alpine
WORKDIR /app
COPY . .
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE ${PORT}
CMD ["node", "index.js"]# Run with env vars
docker run -e DATABASE_URL=postgresql://localhost/mydb \
-e API_KEY=secret123 \
myapp:latest
# Using env file
docker run --env-file .env myapp:latestVolumes
# Named volume
docker run -v mydata:/app/data myapp:latest
# Bind mount
docker run -v $(pwd)/data:/app/data myapp:latest
# Read-only mount
docker run -v $(pwd)/config:/app/config:ro myapp:latestHealth Checks
FROM node:18-alpine
WORKDIR /app
COPY . .
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node healthcheck.js
CMD ["node", "index.js"]// healthcheck.js
const http = require('http');
const options = {
host: 'localhost',
port: 3000,
path: '/health',
timeout: 2000
};
const request = http.request(options, (res) => {
if (res.statusCode === 200) {
process.exit(0);
} else {
process.exit(1);
}
});
request.on('error', () => process.exit(1));
request.end();Best Practices
# 1. Use specific versions
FROM node:18.17.0-alpine
# 2. Use .dockerignore
# .dockerignore
node_modules
.git
.env
*.log
# 3. Minimize layers
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
# 4. Use multi-stage builds
FROM node:18 AS build
# Build steps
FROM node:18-alpine AS production
# Production steps
# 5. Don't run as root
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs
# 6. Use COPY instead of ADD
COPY package*.json ./
# 7. Leverage build cache
COPY package*.json ./
RUN npm ci
COPY . .CI/CD Integration
# GitHub Actions with Docker
name: Docker Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: myapp:${{ github.sha }},myapp:latestInterview Tips
- Explain Docker: Containerization platform
- Show Dockerfile: Multi-stack examples
- Demonstrate commands: Build, run, manage
- Discuss Docker Compose: Multi-container apps
- Mention best practices: Multi-stage, security
- Show CI/CD: Integration with pipelines
Summary
Docker packages applications with dependencies into containers for consistent deployment across environments. Use Dockerfiles to define images. Docker Compose orchestrates multi-container applications. Supports all tech stacks including Angular, .NET, Node.js, and databases. Essential for modern DevOps and CI/CD pipelines.
Test Your Knowledge
Take a quick quiz to test your understanding of this topic.