from flask import Flask
app = Flask(__name__) @app.route('/')
def hello(): return "Hello from Docker!" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
from flask import Flask
app = Flask(__name__) @app.route('/')
def hello(): return "Hello from Docker!" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
from flask import Flask
app = Flask(__name__) @app.route('/')
def hello(): return "Hello from Docker!" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
Flask==2.3.0
Flask==2.3.0
Flask==2.3.0
FROM ubuntu:latest RUN apt-get update
RUN apt-get install python3 COPY . /opt/app
RUN pip install -r requirements.txt USER root CMD python /opt/app/app.py
FROM ubuntu:latest RUN apt-get update
RUN apt-get install python3 COPY . /opt/app
RUN pip install -r requirements.txt USER root CMD python /opt/app/app.py
FROM ubuntu:latest RUN apt-get update
RUN apt-get install python3 COPY . /opt/app
RUN pip install -r requirements.txt USER root CMD python /opt/app/app.py
docker build -t broken-app .
docker build -t broken-app .
docker build -t broken-app .
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . /opt/app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . /opt/app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . /opt/app
FROM python:3.12-slim WORKDIR /opt/app COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 5000
CMD ["python", "app.py"]
FROM python:3.12-slim WORKDIR /opt/app COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 5000
CMD ["python", "app.py"]
FROM python:3.12-slim WORKDIR /opt/app COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 5000
CMD ["python", "app.py"]
# Run as non-root
USER 1001
# Run as non-root
USER 1001
# Run as non-root
USER 1001
docker run --read-only --tmpfs /tmp myapp:latest
docker run --read-only --tmpfs /tmp myapp:latest
docker run --read-only --tmpfs /tmp myapp:latest
docker run -d --name web-test -p 8080:80 nginx
docker run -d --name web-test -p 8080:80 nginx
docker run -d --name web-test -p 8080:80 nginx
docker exec -it web-test bash
echo "hello" > /usr/share/nginx/html/test.txt
docker exec -it web-test bash
echo "hello" > /usr/share/nginx/html/test.txt
docker exec -it web-test bash
echo "hello" > /usr/share/nginx/html/test.txt
docker stop web-test
docker rm web-test
docker run -d --name web-test2 -p 8080:80 nginx
docker stop web-test
docker rm web-test
docker run -d --name web-test2 -p 8080:80 nginx
docker stop web-test
docker rm web-test
docker run -d --name web-test2 -p 8080:80 nginx
docker volume create web-data docker run -d \ --name web-test \ -p 8080:80 \ -v web-data:/usr/share/nginx/html \ nginx
docker volume create web-data docker run -d \ --name web-test \ -p 8080:80 \ -v web-data:/usr/share/nginx/html \ nginx
docker volume create web-data docker run -d \ --name web-test \ -p 8080:80 \ -v web-data:/usr/share/nginx/html \ nginx
docker exec -it web-test bash
echo "persistent data" > /usr/share/nginx/html/test.txt
docker exec -it web-test bash
echo "persistent data" > /usr/share/nginx/html/test.txt
docker exec -it web-test bash
echo "persistent data" > /usr/share/nginx/html/test.txt
docker system prune -f
docker system prune -f
docker system prune -f
version: '3' services: web: build: . ports: - "5000:5000" environment: - DB_HOST=postgres depends_on: - postgres postgres: image: postgres:15 environment: - POSTGRES_PASSWORD=secret
version: '3' services: web: build: . ports: - "5000:5000" environment: - DB_HOST=postgres depends_on: - postgres postgres: image: postgres:15 environment: - POSTGRES_PASSWORD=secret
version: '3' services: web: build: . ports: - "5000:5000" environment: - DB_HOST=postgres depends_on: - postgres postgres: image: postgres:15 environment: - POSTGRES_PASSWORD=secret
docker compose up
docker compose up
docker compose up
postgres: image: postgres:15 environment: - POSTGRES_PASSWORD=secret healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 10
postgres: image: postgres:15 environment: - POSTGRES_PASSWORD=secret healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 10
postgres: image: postgres:15 environment: - POSTGRES_PASSWORD=secret healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 10
web: depends_on: postgres: condition: service_healthy
web: depends_on: postgres: condition: service_healthy
web: depends_on: postgres: condition: service_healthy
POSTGRES_PASSWORD=secret
POSTGRES_PASSWORD=secret
POSTGRES_PASSWORD=secret
environment: - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
environment: - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
environment: - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
FROM nginx:1.21.0
FROM nginx:1.21.0
FROM nginx:1.21.0
brew install aquasecurity/trivy/trivy
brew install aquasecurity/trivy/trivy
brew install aquasecurity/trivy/trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh
trivy image nginx:1.21.0
trivy image nginx:1.21.0
trivy image nginx:1.21.0
FROM nginx:1.25-bookworm
FROM nginx:1.25-bookworm
FROM nginx:1.25-bookworm
FROM nginx:alpine
FROM nginx:alpine
FROM nginx:alpine
trivy image nginx:1.25-bookworm
trivy image nginx:1.25-bookworm
trivy image nginx:1.25-bookworm
docker run -d \ --memory=256m \ --cpus=0.5 \ --read-only \ --tmpfs /tmp \ myapp:latest
docker run -d \ --memory=256m \ --cpus=0.5 \ --read-only \ --tmpfs /tmp \ myapp:latest
docker run -d \ --memory=256m \ --cpus=0.5 \ --read-only \ --tmpfs /tmp \ myapp:latest
docker exec -it <container_id> bash
touch /etc/test
# Permission denied β
docker exec -it <container_id> bash
touch /etc/test
# Permission denied β
docker exec -it <container_id> bash
touch /etc/test
# Permission denied β
docker stats
docker stats
docker stats
docker save -o myapp.tar myapp:latest
docker save -o myapp.tar myapp:latest
docker save -o myapp.tar myapp:latest
docker rmi myapp:latest
docker rmi myapp:latest
docker rmi myapp:latest
docker load -i myapp.tar
docker load -i myapp.tar
docker load -i myapp.tar
docker run myapp:latest
docker run myapp:latest
docker run myapp:latest - pip is never installed
- apt-get install is missing the -y flag (hangs waiting for input)
- COPY happens before dependency install β busting the cache on every change - β
Dockerfile debugging & optimization β fixing real build errors and shrinking image sizes
- β
Layer caching strategies β speeding up builds without reinstalling dependencies
- β
Volume persistence β understanding ephemeral vs. persistent storage
- β
Compose healthchecks β preventing race conditions between services
- β
Image vulnerability scanning β catching CVEs before they reach production
- β
Runtime security hardening β non-root users, read-only filesystems, resource limits
- β
Offline container portability β shipping containers without a registry