Hướng Dẫn Thực Hành: Xây Dựng Và Triển Khai Ứng Dụng Sử Dụng Docker
Giới Thiệu
Bài thực hành này hướng dẫn bạn xây dựng và triển khai một ứng dụng ba tầng (three-tier application) sử dụng Docker. Ứng dụng mẫu là "Net Inventory" – một ứng dụng quản lý kho thiết bị mạng dựa trên Flask (Python), với cơ sở dữ liệu PostgreSQL. Cấu trúc bao gồm:
Bài lab dựa trên các thực hành DevOps từ Cisco (từ khóa học Implementing DevOps Solutions and Practices Using Cisco Platforms), nhưng được cập nhật để đảm bảo tính chính xác và khả thi dựa trên tài liệu Docker chính thức và các hướng dẫn thực tế (như từ Docker Hub, TestDriven.io, và các tutorial Flask-Postgres). Chúng ta sẽ sử dụng các image Docker mới hơn (python:3.12 và postgres:latest) để tránh các vấn đề bảo mật của phiên bản cũ như python:3.7. Ứng dụng sẽ chạy trên mạng bridge tùy chỉnh, và chúng ta sẽ tách biệt các biến môi trường nhạy cảm bằng env files để tuân thủ best practices bảo mật.
Lưu ý:
Giả sử mã nguồn bao gồm:
Tạo ba Dockerfile riêng biệt để tránh xung đột tên file. Sử dụng base image mới để đảm bảo tính tương thích và bảo mật.
Best Practice: Sử dụng rm -rf /var/lib/apt/lists/* để giảm kích thước image (từ Docker docs). Phần 2: Xây Dựng Các Image
Chạy từ thư mục net_inventory:
Kiểm tra: docker images – Nên thấy db, backend, frontend. Phần 3: Tạo Mạng Và Chạy Containers Với Env Files
Để tách biệt secrets (như password), tạo env files (từ Docker docs: sử dụng với --env-file).
Lưu ý: Sử dụng -d thay vì -itd để chạy background (best practice từ Docker docs). Nếu cần interactive, thêm -it. Phần 4: Xác Minh Và Kiểm Tra
Nếu lỗi kết nối DB: Đảm bảo SQLALCHEMY_DATABASE_URI dùng tên container netinv_db (Docker DNS tự resolve). Phần 5: Dọn Dẹp Và Best Practices
Bạn đã xây dựng thành công ứng dụng ba tầng với Docker, đảm bảo tính module hóa và bảo mật. Bài lab này có thể mở rộng bằng cách thêm Nginx làm reverse proxy (như trong hướng dẫn TestDriven.io) hoặc tích hợp CI/CD với GitLab. Nếu gặp lỗi, kiểm tra logs và tham khảo Docker docs. Thời gian hoàn thành: Khoảng 30-60 phút.
Giới Thiệu
Bài thực hành này hướng dẫn bạn xây dựng và triển khai một ứng dụng ba tầng (three-tier application) sử dụng Docker. Ứng dụng mẫu là "Net Inventory" – một ứng dụng quản lý kho thiết bị mạng dựa trên Flask (Python), với cơ sở dữ liệu PostgreSQL. Cấu trúc bao gồm:
- Tầng cơ sở dữ liệu (Database Tier): Sử dụng PostgreSQL để lưu trữ dữ liệu.
- Tầng back-end (Back-End Tier): Ứng dụng Flask xử lý logic kinh doanh và API.
- Tầng front-end (Front-End Tier): Ứng dụng Flask cung cấp giao diện người dùng, kết nối với back-end qua API.
Bài lab dựa trên các thực hành DevOps từ Cisco (từ khóa học Implementing DevOps Solutions and Practices Using Cisco Platforms), nhưng được cập nhật để đảm bảo tính chính xác và khả thi dựa trên tài liệu Docker chính thức và các hướng dẫn thực tế (như từ Docker Hub, TestDriven.io, và các tutorial Flask-Postgres). Chúng ta sẽ sử dụng các image Docker mới hơn (python:3.12 và postgres:latest) để tránh các vấn đề bảo mật của phiên bản cũ như python:3.7. Ứng dụng sẽ chạy trên mạng bridge tùy chỉnh, và chúng ta sẽ tách biệt các biến môi trường nhạy cảm bằng env files để tuân thủ best practices bảo mật.
Lưu ý:
- Bài lab giả định bạn có Docker đã cài đặt trên máy Linux (như Ubuntu). Nếu chưa, cài đặt theo hướng dẫn chính thức tại docs.docker.com.
- Mã nguồn ứng dụng được clone từ GitLab (nếu không tồn tại, bạn có thể tạo mã mẫu đơn giản dựa trên hướng dẫn).
- Kiểm tra tính khả thi: Các lệnh đã được xác nhận từ Docker docs và các tutorial tương tự (ví dụ: Dockerizing Flask with Postgres từ TestDriven.io và Level Up GitConnected).
- Hiểu cách tạo Dockerfile cho từng tầng ứng dụng.
- Xây dựng và chạy container Docker cho ứng dụng ba tầng.
- Sử dụng mạng Docker để kết nối các container.
- Tách biệt biến môi trường khỏi image để tăng tính bảo mật.
- Xác minh ứng dụng chạy đúng và có thể truy cập qua browser.
- Máy tính với Docker version 20.10+ (kiểm tra bằng docker --version).
- Git đã cài đặt.
- Visual Studio Code (VS Code) để chỉnh sửa file.
- Trình duyệt web (như Chrome) để kiểm tra ứng dụng.
- Không gian đĩa khoảng 2GB cho images và containers.
- Mở VS Code trên máy workstation.
- Mở terminal trong VS Code (Terminal > New Terminal).
- Tạo thư mục làm việc: mkdir -p ~/labs/lab04/net_inventory && cd ~/labs/lab04/net_inventory.
- Clone mã nguồn: git clone https://git.lab/cisco-devops/net_inventory (nếu repo không tồn tại, sử dụng mã mẫu Flask-Postgres từ GitHub như https://github.com/testdrivenio/flask-postgres-example và điều chỉnh).
Giả sử mã nguồn bao gồm:
- requirements.txt: Với các gói như flask, psycopg2, sqlalchemy.
- run.py: Script khởi động ứng dụng.
- net-inventory-config.yml: File config YAML (nếu cần).
Tạo ba Dockerfile riêng biệt để tránh xung đột tên file. Sử dụng base image mới để đảm bảo tính tương thích và bảo mật.
- Dockerfile cho Database (Dockerfile_db):
text
FROM postgres:latest
LABEL description="PostgreSQL database for Net Inventory Flask app"
LABEL maintainer="Cisco <noreply@cisco.com>"
LABEL version="0.1"
EXPOSE 5432/tcp- Giải thích: Base từ postgres:latest (Docker Hub khuyến nghị). Không cần ENV ở đây vì sẽ dùng env-file sau. Expose cổng 5432 cho kết nối.
- Dockerfile cho Back-End (Dockerfile_backend):
text
FROM python:3.12-slim
LABEL description="Net Inventory back-end Flask application"
LABEL maintainer="Cisco <noreply@cisco.com>"
LABEL version="0.1"
ADD ./ /net_inventory
WORKDIR /net_inventory
RUN apt-get update && apt-get install -y git vim && rm -rf /var/lib/apt/lists/*
RUN pip install --upgrade pip && pip install -r requirements.txt
EXPOSE 5001/tcp
ENTRYPOINT ["python", "run.py"]- Giải thích: Base từ python:3.12-slim (nhẹ, bảo mật hơn 3.7). Cài git/vim nếu cần (từ tutorial Flask-Docker). Install dependencies. Expose cổng 5001.
- Dockerfile cho Front-End (Dockerfile_frontend):
text
FROM python:3.12-slim
LABEL description="Net Inventory front-end Flask application"
LABEL maintainer="Cisco <noreply@cisco.com>"
LABEL version="0.1"
ADD ./ /net_inventory
WORKDIR /net_inventory
RUN apt-get update && apt-get install -y git vim && rm -rf /var/lib/apt/lists/*
RUN pip install --upgrade pip && pip install -r requirements.txt
EXPOSE 5000/tcp
ENTRYPOINT ["python", "run.py"]- Giải thích: Tương tự back-end, nhưng expose cổng 5000. Giả sử front-end gọi API back-end qua URL.
Best Practice: Sử dụng rm -rf /var/lib/apt/lists/* để giảm kích thước image (từ Docker docs). Phần 2: Xây Dựng Các Image
Chạy từ thư mục net_inventory:
- Xây dựng DB: docker build -t db -f Dockerfile_db .
- Xây dựng Back-End: docker build -t backend -f Dockerfile_backend .
- Xây dựng Front-End: docker build -t frontend -f Dockerfile_frontend .
Kiểm tra: docker images – Nên thấy db, backend, frontend. Phần 3: Tạo Mạng Và Chạy Containers Với Env Files
Để tách biệt secrets (như password), tạo env files (từ Docker docs: sử dụng với --env-file).
- Tạo env_file_db:
text
POSTGRES_DB=net_inventory
POSTGRES_USER=root
POSTGRES_PASSWORD=Cisco123
PGDATA=/var/lib/postgresql/data/pgdata - Tạo env_file_backend:
text
ENV=BACKEND
SECRET_KEY=aj8j6PIbaJpJXBS8jjvcylT84G+1UhxjXQFz6pJ PNuQ=
POSTGRES_DB=net_inventory
SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://root:Cisco123@netinv_db/net_inventory - Tạo env_file_frontend:
text
ENV=FRONTEND
URL=http://netinv_backend:5001 - Tạo mạng bridge: docker network create -d bridge services_bridge (cho phép containers giao tiếp bằng tên, từ Docker networking docs).
- Chạy containers:
- DB: docker run -d --env-file=env_file_db --network services_bridge --name netinv_db db
- Back-End: docker run -d --env-file=env_file_backend --network services_bridge -p 5001:5001 --name netinv_backend backend
- Front-End: docker run -d --env-file=env_file_frontend --network services_bridge -p 5000:5000 --name netinv_frontend frontend
Lưu ý: Sử dụng -d thay vì -itd để chạy background (best practice từ Docker docs). Nếu cần interactive, thêm -it. Phần 4: Xác Minh Và Kiểm Tra
- Kiểm tra containers: docker ps – Nên thấy ba containers đang chạy.
- Kiểm tra logs: docker logs netinv_db (kiểm tra Postgres khởi động).
- Kết nối back-end: Mở browser tại http://127.0.0.1:5001/api/docs (nếu có Swagger docs).
- Kết nối front-end: http://127.0.0.1:5000/ – Nên thấy giao diện ứng dụng.
- Kiểm tra kết nối: Từ front-end, thử chức năng gọi API back-end (qua mạng bridge).
Nếu lỗi kết nối DB: Đảm bảo SQLALCHEMY_DATABASE_URI dùng tên container netinv_db (Docker DNS tự resolve). Phần 5: Dọn Dẹp Và Best Practices
- Dừng và xóa: docker stop netinv_frontend netinv_backend netinv_db && docker rm netinv_frontend netinv_backend netinv_db && docker network rm services_bridge.
- Best Practices (từ tutorial TestDriven.io):
- Sử dụng volumes cho DB: Thêm -v pgdata:/var/lib/postgresql/data cho netinv_db để lưu dữ liệu.
- Chuyển sang Docker Compose cho production: Tạo docker-compose.yml để quản lý dễ hơn.
- Bảo mật: Không hardcode secrets; sử dụng Docker Secrets hoặc Kubernetes Secrets cho môi trường thực.
- Tối ưu: Sử dụng multi-stage build để giảm kích thước image (ví dụ: builder stage cho pip install).
Bạn đã xây dựng thành công ứng dụng ba tầng với Docker, đảm bảo tính module hóa và bảo mật. Bài lab này có thể mở rộng bằng cách thêm Nginx làm reverse proxy (như trong hướng dẫn TestDriven.io) hoặc tích hợp CI/CD với GitLab. Nếu gặp lỗi, kiểm tra logs và tham khảo Docker docs. Thời gian hoàn thành: Khoảng 30-60 phút.