1. Tạo Dockerfile cho ứng dụng SQLite tích hợp LiteFS
Chúng ta cần xây dựng một hình ảnh Docker (Docker image) đóng gói ứng dụng Python đơn giản truy cập SQLite, đồng thời cài đặt client LiteFS để mount filesystem vào container.
Mục đích là tạo một môi trường chạy ứng dụng mà dữ liệu SQLite được lưu trên volume đã được mount bởi LiteFS, đảm bảo ứng dụng không biết nó đang chạy trên Edge hay Primary.
Đảm bảo thư mục làm việc hiện tại đã có file app.py (ứng dụng ví dụ ghi dữ liệu vào SQLite).
Tạo file Dockerfile với nội dung hoàn chỉnh sau:
FROM python:3.12-slim
# Cài đặt LiteFS client và các công cụ cần thiết
RUN apt-get update && apt-get install -y \
curl \
sqlite3 \
&& curl -fsSL https://litestream.io/install | sh -s -- -b /usr/local/bin \
&& rm -rf /var/lib/apt/lists/*
# Đặt thư mục làm việc
WORKDIR /app
# Copy mã nguồn ứng dụng
COPY app.py .
# Tạo thư mục mount cho LiteFS
# Đây là nơi LiteFS sẽ mount filesystem vào container
RUN mkdir -p /var/lib/litfs
# Cài đặt dependencies Python (nếu có)
# RUN pip install --no-cache-dir -r requirements.txt
# Chạy ứng dụng
CMD ["python", "app.py"]
Kết quả mong đợi: File Dockerfile được tạo, sẵn sàng để build. Lưu ý dòng CURL tải LiteFS binary về /usr/local/bin và thư mục /var/lib/litfs được tạo để ánh xạ volume.
Verify Dockerfile
Build image để kiểm tra cú pháp và quá trình cài đặt:
docker build -t litfs-app:1.0 .
Kết quả: Docker build thành công, hiển thị dòng Successfully built ....
2. Cấu hình Docker Compose cho LiteFS và Ứng dụng
Bây giờ chúng ta sẽ viết file docker-compose.yml để orchestrate hai service: một service chạy LiteFS (mounter) và một service chạy ứng dụng (app).
Cấu trúc này mô phỏng môi trường thực tế: LiteFS chạy như một sidecar hoặc container riêng biệt, quản lý việc sync dữ liệu, còn container ứng dụng chỉ cần truy cập vào đường dẫn đã được mount.
Tạo file docker-compose.yml trong cùng thư mục với Dockerfile:
version: "3.8"
services:
# Service LiteFS: Chịu trách nhiệm mount filesystem và sync dữ liệu
litfs:
image: litfs/litfs:latest
container_name: litfs-edge-node
privileged: true # Bắt buộc để mount filesystem
volumes:
# Volume chứa dữ liệu gốc (nơi LiteFS sẽ mount vào)
- litfs-data:/var/lib/litfs
# Volume chứa config file của LiteFS
- ./litfs.yml:/etc/litfs/litfs.yml:ro
# Volume chứa thư mục mount target cho ứng dụng truy cập
- app-data:/app/data
environment:
- LITFS_NODE_ID=edge-node-01
- LITFS_MODE=replica
# Cấu hình Primary server (đã setup ở Phần 3)
- LITFS_PRIMARY_URL=http://primary:8080
command: ["litfs", "mount", "/var/lib/litfs", "/app/data"]
# Tắt auto-restart để dễ debug, hoặc bật khi production
restart: unless-stopped
# Service Ứng dụng: Chạy code Python truy cập SQLite
app:
build: .
container_name: litfs-app-instance
volumes:
# Mount volume app-data từ service litfs vào container app
# Đường dẫn trong container app phải khớp với nơi litfs mount vào
- app-data:/app/data
environment:
# Biến môi trường để ứng dụng biết đường dẫn DB
- SQLITE_DB_PATH=/app/data/mydb.sqlite
depends_on:
- litfs
# Chờ litfs mount xong trước khi app chạy (tùy chọn, cần script healthcheck nếu nghiêm ngặt)
restart: unless-stopped
volumes:
litfs-data:
driver: local
app-data:
driver: local
Kết quả mong đợi: File docker-compose.yml được tạo. Cấu hình này sử dụng shared volume app-data: Service litfs mount filesystem vào volume này, service app mount volume này vào container của nó. Ứng dụng sẽ thấy file SQLite nằm tại /app/data.
Verify Docker Compose Config
Kiểm tra cú pháp YAML:
docker-compose config
Kết quả: In ra nội dung config đã được chuẩn hóa, không có lỗi yaml hoặc docker.
3. Tạo file cấu hình LiteFS (litfs.yml) cho Edge Node
Docker Compose ở trên mount file config vào container LiteFS. Chúng ta cần tạo file này trên host để Docker Compose có thể copy vào.
File này định nghĩa node ID, chế độ Replica, và URL của Primary server (được cấu hình ở Phần 3).
Tạo file litfs.yml trong thư mục làm việc:
node:
id: edge-node-01
mode: replica
mounts:
- db: mydb.sqlite
dir: /app/data
primary:
url: http://primary:8080
node: primary-node
Kết quả mong đợi: File litfs.yml được tạo. Lưu ý đường dẫn dir: /app/data phải khớp với đường mount trong command của service litfs trong docker-compose.yml.
4. Khởi động và Kiểm tra tính nhất quán dữ liệu
Thực hiện lệnh start toàn bộ stack và kiểm tra luồng dữ liệu từ ứng dụng viết vào SQLite, sau đó được LiteFS sync về Primary.
Bước 1: Khởi động Docker Compose
docker-compose up -d
Kết quả: Hai container litfs-edge-node và litfs-app-instance được tạo và chạy trạng thái Running.
Bước 2: Kiểm tra log của LiteFS để đảm bảo nó đã mount thành công
docker logs litfs-edge-node | grep "mounted"
Kết quả mong đợi: Thấy dòng log litfs: mounted filesystem hoặc litfs: connected to primary. Nếu thấy lỗi permission denied, kiểm tra lại privileged: true trong compose.
Bước 3: Ghi dữ liệu từ ứng dụng
Giả sử ứng dụng app.py của bạn có hàm ghi dữ liệu. Chúng ta sẽ vào container app và thực hiện lệnh ghi trực tiếp bằng sqlite3 để test nhanh.
docker exec -it litfs-app-instance sqlite3 /app/data/mydb.sqlite "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT); INSERT INTO users (name) VALUES ('User_Edge_Test');"
Kết quả mong đợi: Lệnh chạy thành công, không báo lỗi No such file or directory. Dữ liệu đã được ghi vào file SQLite nằm trên volume đã mount.
Bước 4: Kiểm tra sự đồng bộ (Replication)
Trên container Primary (đã setup ở Phần 3), kiểm tra xem dữ liệu có xuất hiện không.
docker exec -it primary-node sqlite3 /var/lib/litfs/mydb.sqlite "SELECT * FROM users;"
Kết quả mong đợi: Trả về dòng dữ liệu 1|User_Edge_Test.
Bước 5: Verify tính nhất quán bằng LiteFS CLI
Chạy lệnh kiểm tra trạng thái replication trên Edge Node:
docker exec litfs-edge-node litfs status
Kết quả mong đợi: Thấy thông tin mode: replica, connected: true, và replication lag gần bằng 0.
Xử lý lỗi thường gặp
- Nếu app không ghi được file: Kiểm tra quyền
chmod 777 /app/data trên host trước khi chạy, hoặc đảm bảo volume app-data đã được tạo sạch.
- Nếu LiteFS không kết nối được Primary: Kiểm tra network trong docker-compose (cùng network default) và biến môi trường
LITFS_PRIMARY_URL.
- Nếu file SQLite bị corrupt: Đảm bảo ứng dụng đóng connection đúng cách (
conn.close()) trước khi LiteFS snapshot.
Điều hướng series:
Mục lục: Series: Triển khai Database Edge với LiteFS và Ubuntu 24.04
« Phần 4: Triển khai LiteFS cho chế độ Replication (Edge Nodes)
Phần 6: Xử lý xung đột dữ liệu và cân bằng tải trong mạng Edge »