Shruti_Containerization_lab

Experiment 4: Docker Essentials


Part 1: Containerizing Applications with Dockerfile

Step 1: Create Project Folder

mkdir my-flask-app
cd my-flask-app

Step 2: Create Application Files

app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello from Docker!"

@app.route('/health')
def health():
    return "OK"

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

requirements.txt

Flask==2.3.3

Step 3: Create Dockerfile

FROM python:3.10-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["python", "app.py"]

Part 2: Using .dockerignore

Create .dockerignore

__pycache__/
*.pyc
*.pyo
*.pyd
.env
.venv
env/
venv/
.vscode/
.idea/
.git/
.gitignore
.DS_Store
Thumbs.db
*.log
logs/
tests/
test_*.py

Part 3: Building Docker Images

Step 1: Build Image

docker build -t my-flask-app .

Check images:

docker images

Step 2: Tagging Images

Tag with version:

docker build -t my-flask-app:1.0 .

Multiple tags:

docker build -t my-flask-app:latest -t my-flask-app:1.0 .

Custom registry:

docker build -t ss1234ss1234/my-flask-app:1.0 .

Tag existing image:

docker tag my-flask-app:latest my-flask-app:v1

Step 3: View Image Details

docker images
docker history my-flask-app
docker inspect my-flask-app

Part 4: Running Containers

Step 1: Run Container

docker run -d -p 5000:5000 --name flask-container my-flask-app

Test:

curl http://localhost:5000

Check:

docker ps
docker logs flask-container

Step 2: Manage Containers

docker stop flask-container
docker start flask-container
docker rm flask-container
docker rm -f flask-container

Part 5: Multi-stage Builds

Why Multi-stage?


Dockerfile.multistage

FROM python:3.9-slim AS builder

WORKDIR /app

COPY requirements.txt .
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.9-slim

WORKDIR /app

COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

COPY app.py .

RUN useradd -m -u 1000 appuser
USER appuser

EXPOSE 5000

CMD ["python", "app.py"]

Build and Compare

docker build -t flask-regular .
docker build -f Dockerfile.multistage -t flask-multistage .
docker images | grep flask-

Part 6: Publishing to Docker Hub

Step 1: Login and Tag

docker login
docker tag my-flask-app:latest ss1234ss1234/my-flask-app:1.0
docker tag my-flask-app:latest ss1234ss1234/my-flask-app:latest

Push:

docker push ss1234ss1234/my-flask-app:1.0
docker push ss1234ss1234/my-flask-app:latest

Step 2: Pull & Run

docker pull ss1234ss1234/my-flask-app:latest
docker run -d -p 5000:5000 ss1234ss1234/my-flask-app:latest

Part 7: Node.js Example

Step 1: Create Node App

mkdir my-node-app
cd my-node-app

app.js

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello from Node.js Docker!');
});

app.get('/health', (req, res) => {
  res.json({ status: 'healthy' });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

package.json

{
  "name": "node-docker-app",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "express": "^4.18.2"
  }
}

Step 2: Node Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install --only=production

COPY app.js .

EXPOSE 3000

CMD ["node", "app.js"]

Step 3: Build & Run

docker build -t my-node-app .
docker run -d -p 3000:3000 --name node-container my-node-app

Test:

curl http://localhost:3000

Final Conclusion

This experiment covered: