Introduction:
In today’s world, web applications need to scale to handle millions of users. A microservices architecture, when combined with Docker containers, can make this process much more efficient and flexible. In this project, I demonstrated how to build and deploy a simple, scalable web application using Docker containers. The app is divided into three microservices—Authentication, Payment, and Streaming—each responsible for specific tasks.
Project Overview:
Microservices Breakdown:
Our application consists of three independently deployable services, each responsible for a single, well-defined task:
Authentication Service: Handles user login and authentication.
Payment Service: Processes transactions and manages payment flows.
Streaming Service: Delivers video streaming content to users.
Each service communicates with others through REST APIs, but they can also be independently deployed, tested, and scaled based on demand.
Why Docker for Microservices?
Docker containers provide an isolated, consistent environment for each microservice. By using Docker, we can ensure that each service runs in the same environment regardless of where it’s deployed. This is crucial for maintaining reliability, simplifying deployment, and making the scaling process a breeze.
Key Concepts:
Microservices Architecture:
Microservices decompose the application into smaller, modular services that are each responsible for a specific business function. This approach brings several benefits:
Scalability: Scale individual services independently based on user demand.
Maintainability: Update and deploy each service independently without affecting others.
Resilience: Isolate failures within a single service, preventing the entire application from going down.
Docker Containers:
Docker ensures each microservice runs in its own container with its required environment, reducing conflicts and increasing portability. The containers can be run anywhere—from local machines to cloud platforms—without worrying about compatibility issues.
Scalability with Docker:
Docker containers can be easily replicated and scaled. For example, if the payment service receives a sudden surge of requests, we can spin up additional containers to handle the increased load, ensuring smooth operation even during traffic spikes.
Separation of Concerns:
Each service is focused on a specific business function. The Authentication Service handles login, the Payment Servicemanages transactions, and the Streaming Service takes care of video delivery. This separation makes it easier to manage, troubleshoot, and scale individual parts of the application.
Why Use Microservices with Docker?
Efficiency:
Docker simplifies the development and deployment process. With Docker, each service is encapsulated in its own container with all necessary dependencies, making development more efficient and consistent.
Scalability:
Docker, in combination with orchestration tools like Kubernetes or Docker Swarm, allows you to dynamically scale services based on demand. If more users are accessing the authentication service, Docker makes it easy to increase its capacity by adding more containers.
Maintainability:
Microservices architecture allows you to update or modify individual services without impacting the rest of the application. With Docker, each service is independent, so you can update and deploy new versions seamlessly.
Conclusion:
This project illustrates the power of microservices and Docker in building scalable, modular applications. By breaking down the application into smaller, focused services, and containerizing them with Docker, we ensure that our application is flexible, scalable, and easy to maintain.
The Docker containers allow for easy scaling, faster deployment, and reduced overhead, making it an ideal choice for modern application development. While this example is simplified for demonstration purposes, the same principles can be applied to real-world applications, ensuring that they can handle rapid growth and increasing complexity.
Step 1: Build the Services
Each service is a simple Go application that listens on specific routes and performs basic functions. Here’s the code for each service:
1. Authentication Service:
package main
import (
"fmt"
"net/http"
)
func welcomeHandler(w http.ResponseWriter, r *http.Request) {
// Respond with a simple welcome message
fmt.Fprintln(w, "Welcome to the login page")
}
func main() {
http.HandleFunc("/", welcomeHandler) // Root path for the service
fmt.Println("Auth Service is running on port 8081...")
http.ListenAndServe(":8081", nil)
}
2. Payment Service:
package main
import (
"encoding/json"
"net/http"
)
type PaymentRequest struct {
UserID string `json:"user_id"`
Amount float64 `json:"amount"`
}
func paymentHandler(w http.ResponseWriter, r *http.Request) {
var req PaymentRequest
json.NewDecoder(r.Body).Decode(&req)
// Simulate payment processing
w.WriteHeader(http.StatusOK)
w.Write([]byte("Payment successful"))
}
func main() {
http.HandleFunc("/pay", paymentHandler)
http.ListenAndServe(":8082", nil)
}
3. Streaming Service:
package main
import (
"net/http"
)
func streamHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Streaming content..."))
}
func main() {
http.HandleFunc("/stream", streamHandler)
http.ListenAndServe(":8083", nil)
}
The Streaming Service simulates video streaming, serving a static response at /stream
.
Step 2: Dockerize Each Service
To containerize these services, we’ll use Dockerfiles to define how each service should be built and run.
Dockerfile for Authentication Service (auth-service):
# Use Golang base image
FROM golang:1.23-alpine
# Set working directory inside the container
WORKDIR /app
# Copy only the Go module files first
COPY go.mod .
RUN go mod download
# Copy the application code
COPY main.go .
# Build the service
RUN go build -o auth-service .
# Expose the port the service will run on
EXPOSE 8081
# Command to run the executable
CMD ["./auth-service"]
Dockerfile for Payment Service (payment-service):
FROM golang:1.23-alpine
WORKDIR /app
# Copy only the Go module files first
COPY go.mod .
RUN go mod download
# Copy the application code
COPY main.go .
# Build the Go binary
RUN go build -o payment-service .
# Expose the service port
EXPOSE 8082
# Run the application
CMD ["./payment-service"]
Dockerfile for Streaming Service (streaming-service):
FROM golang:1.23-alpine
WORKDIR /app
# Copy only the Go module files first
COPY go.mod .
RUN go mod download
# Copy the application code
COPY main.go .
# Build the Go binary
RUN go build -o streaming-service .
# Expose the service port
EXPOSE 8083
# Run the application
CMD ["./streaming-service"]
Step 3: Docker Compose for Orchestration
Docker Compose allows you to manage multi-container applications easily. By defining the services in a single YAML file, you can start, stop, and scale them together.
What is Docker Compose?
Docker Compose is a tool used for defining and running multi-container Docker applications. Instead of manually managing each container separately, Docker Compose simplifies this process by allowing you to define all containers and their configurations in a docker-compose.yml
file.
Why Use Docker Compose?
Single Command: Start all services with a single command.
Simplified Scaling: Easily scale services up or down, depending on demand.
Portability: Docker Compose ensures that all containers are correctly configured and run consistently across different environments.
docker-compose.yml Example:
version: "3.9"
services:
auth-service:
build: ./auth-service
ports:
- "8081:8081"
payment-service:
build: ./payment-service
ports:
- "8082:8082"
streaming-service:
build: ./streaming-service
ports:
- "8083:8083"
Step 4: Running the Application
To bring up the services, use Docker Compose:
docker compose up -d
To bring down the services, use:
docker compose down
This will start all the services as separate containers, and you can access them at:
Authentication Service: localhost:8081/login
Payment Service: localhost:8082/pay
Streaming Service: localhost:8083/stream
With Docker Compose, you now have a fully orchestrated, scalable microservices architecture ready for development and deployment.
Source code:
GitHub:
https://github.com/nsahil992/Microservice-Docker-Project
Thank you for taking the time to read this. If you enjoy my work, consider subscribing to my newsletter to get updates as soon as I post a new blog. If you like the repository, consider giving it a ⭐️ and feel free to connect with me on my social media:
LinkedIn:
https://www.linkedin.com/in/nsahil992
Twitter/X:
https://twitter.com/nsahil992
GitHub:
https://github.com/nsahil992