top of page

1. Quick overview — what we’ll do and why


What we’ll build (high level)Two small microservices (Python + Flask) that run in separate Docker containers and communicate over Docker’s network.


user-service — serves user info at


order-service — calls user-service and returns user + order info


We orchestrate both with Docker Compose so they start together and can discover each other by service name.


Why this exercise matters


Demonstrates key microservices concepts: service isolation, inter-service communication, service discovery (via Docker Compose DNS), and reproducible deployments.

Shows how Docker networks enable containers to call each other by service name rather than IP.


Prepares students for real-world systems where services are independent, scalable, and managed via orchestration tools (Compose/Kubernetes).


Related real-world examples


E-commerce: auth-service, product-service, order-service, payment-service.

Social app: user-profile, feed, notification.

Monitoring: a service pushing metrics to a separate ingestion API.


2. Learning objectives (what students should learn)

By the end of the lab students will be able to:


  1. Containerize a Python Flask app using a Dockerfile.

  2. Write a docker-compose.yml to run multiple containers together.

  3. Understand and test how containers communicate by service name.

  4. Debug common container-networking and dependency issues.

  5. Extend services (add DB, logging, scaling) as next steps.


3. Prerequisites & checklist (what must be installed)


Docker Desktop for Windows (or Docker Engine + docker-compose). If on Windows, enable WSL2 if prompted.


Basic familiarity with Python (creating a small Flask app).


A terminal (PowerShell or CMD).


Text editor (VS Code recommended).




4. Project structure (create this folder tree)


Create a folder C:\microservices-demo (or your preferred path) and inside create:

microservices-demo/
│
├── user-service/
│   ├── app.py
│   ├── requirements.txt
│   └── Dockerfile
│
├── order-service/
│   ├── app.py
│   ├── requirements.txt
│   └── Dockerfile
│
└── docker-compose.yml

You’ll paste the provided file contents below into these files.



5. File contents — copy these exactly

user-service/app.py

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/user')
def get_user():
    # Simple static data for the demo
    return jsonify({"id": 1, "name": "Sharon", "role": "Developer"})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001)

user-service/requirements.txt

flask==2.2.5

(pinning a minor version reduces differences during installs; not mandatory)


user-service/Dockerfile

# Use an official Python runtime as a parent image
FROM python:3.10-slim

# Set working directory
WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the app code
COPY . .

# Expose the port
EXPOSE 5001

# Start the app
CMD ["python", "app.py"]

order-service/app.py

from flask import Flask, jsonify
import requests

app = Flask(__name__)

@app.route('/order')
def get_order():
    # Call the user-service using the Docker Compose service name
    try:
        user_response = requests.get('http://user-service:5001/user', timeout=5)
        user = user_response.json()
    except Exception as e:
        # If user-service is not reachable, return an error message so students can debug
        return jsonify({"error": "Could not reach user-service", "details": str(e)}), 503

    order = {"order_id": 101, "item": "Laptop", "price": 55000}
    return jsonify({"user": user, "order": order})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5002)

order-service/requirements.txt

flask==2.2.5
requests==2.31.0

order-service/Dockerfile

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5002
CMD ["python", "app.py"]

docker-compose.yml (root of project)

version: '3.8'
services:
  user-service:
    build: ./user-service
    container_name: user-service
    ports:
      - "5001:5001"
    restart: unless-stopped

  order-service:
    build: ./order-service
    container_name: order-service
    ports:
      - "5002:5002"
    depends_on:
      - user-service
    restart: unless-stopped


Notes:

  • depends_on ensures Docker Compose starts user-service first, but it does not wait for the service to be "ready" — only for the container to start. We'll mention how to handle readiness later.

  • container_name is optional — included here to make container names predictable in the lab.


6. Step-by-step commands (build, run, test)


Open a terminal at the project root (C:\microservices-demo).


  1. Build containers

    docker-compose build


    Output: Docker will download base images and build both images. Look for Successfully built messages.

    ree
  2. Start services (foreground logging)

    docker-compose up

    • This will stream logs from both containers. You should see Flask starting messages for both services.

    • Press Ctrl+C to stop (or open a new terminal and run docker-compose down).


  3. Start services (detached)

    docker-compose up -d

    • Runs containers in background. Then check status:

    docker-compose ps

    • You should see both user-service and order-service with STATE Up.


  4. Test endpoints (use browser, curl, or Postman)

  5. View logs

    docker-compose logs --tail=100 docker-compose logs order-service


  6. Stop & remove containers

    docker-compose down

    This removes containers and network but keeps images locally.


7. Verify what happened

  • When order-service calls http://user-service:5001/user it uses the Compose service name (user-service) as a DNS name. Docker Compose creates an isolated network where service names resolve to container IPs.


  • This avoids hardcoding IP addresses and mirrors how service discovery works in production (DNS, Envoy, Kubernetes services, etc.).



 
 
 


Student Workflow

Each student will now perform these steps on their own computer.

ree

Step 1 — Clone Your Repository

💬 Explanation:This copies the instructor’s repository from GitHub to the student’s local computer.

ree

Step 2 — Create Their Own Branch

Each student should create a branch using your name, for example:

git branch feature-sharon
git switch feature-sharon

Explanation:They create their own workspace (branch) so they don’t overwrite others’ code.


Step 3 — Update the File

Open the file students_task.py and add one line like this:

print("Hello from Sharon!")

Each student replaces “Sharon” with their own name.

Step 4 — Stage and Commit Changes

git add students_task.py
git commit -m "Added my name print statement"

Explanation:

  • git add puts the changes into the staging area.

  • git commit saves their work in the branch history.


Step 5 — Push Their Branch to GitHub

git push origin feature-sharon

Explanation:This uploads the student’s branch to your GitHub repository under their own branch name.



Each branch represents a student’s submission!

 
 
 

You can use Docker to run and compile C++ code even if your local machine doesn’t have any compiler or build tools installed (like g++, clang, or make).



GOAL

You’ll:

  1. Pull a Docker image that already has a C++ compiler.

  2. Run a container from that image.

  3. Compile and execute a C++ program inside the container.

Step 1. Check Docker is working

Run:

docker --version
docker run hello-world

If you see “Hello from Docker!”, it means Docker is installed and running.


Step 2. Pull a C++-ready image

There are many Docker images that already include C++ compilers.The most common choices:

Image

Includes

gcc

GNU C/C++ compiler

ubuntu

Basic OS (you can install g++)

clang

LLVM/Clang compiler

For most uses:

docker pull gcc
ree

This downloads an image with g++ preinstalled.

Step 3. Run a container interactively

Start a container and enter its shell:

docker run -it gcc bash

You’ll now be inside a Linux shell that already has a C++ compiler.

Check the compiler:

g++ --version
ree

Step 4. Create a small C++ program

Inside the container, use any editor (like nano) or echo command:

echo '#include <iostream>
using namespace std;
int main() {
    cout << "Hello from Docker C++!" << endl;
    return 0;
}' > hello.cpp

ree

Step 5. Compile the code

Run:

g++ hello.cpp -o hello

That creates an executable file hello.

Step 6. Run the program

Execute it:

./hello

You should see:

Hello from Docker C++!
ree

 
 
 

© 2023 by newittrendzzz.com 

  • Facebook
  • Twitter
  • Instagram
bottom of page