[Open Source] #174 - Exercise Diary: Hệ thống nhật ký tập luyện "Single Binary" với Go, kiến trúc CGO-free và trực quan hóa Heatmap tối giản
Trong kỷ nguyên của các ứng dụng di động đầy quảng cáo và thu thập dữ liệu, việc sở hữu một hạ tầng tự lưu trữ (self-hosted) để theo dõi sức khỏe đang trở thành xu hướng của các "vọc sĩ" công nghệ. Exercise Diary xuất hiện như một giải pháp tinh gọn, cung cấp một giao diện nhật ký tập luyện trực quan với biểu đồ nhiệt (Heatmap) phong cách GitHub và biểu đồ theo dõi cân nặng. Điểm mạnh nhất của dự án nằm ở triết lý "một tệp thực thi duy nhất", cho phép triển khai lên bất kỳ máy chủ NAS hay Raspberry Pi nào chỉ trong vài giây.
Dưới góc độ kỹ thuật, Exercise Diary là một minh chứng xuất sắc về việc ứng dụng Go, kỹ thuật nhúng tài nguyên tĩnh (Embedding) và tư duy xây dựng hệ thống CGO-free để đạt tính di động tuyệt đối.
Github: https://github.com/v8u7/ExerciseDiary
🛠️ 1. Nền tảng công nghệ: Hiệu năng và Tính di động (Portable)
Exercise Diary chọn một ngăn xếp công nghệ ưu tiên sự gọn nhẹ và khả năng biên dịch chéo (cross-compile) mượt mà:
- Backend Core (Go 1.23+): Tận dụng hiệu năng thực thi của Go và framework Gin Gonic để xử lý các yêu cầu HTTP với độ trễ cực thấp.
- CGO-free Database (modernc.org/sqlite): Một lựa chọn kỹ thuật cực kỳ thông minh. Thay vì dùng SQLite truyền thống phụ thuộc vào thư viện C, dự án dùng bản SQLite thuần Go. Điều này cho phép lập trình viên build ứng dụng cho Windows, Linux, ARM... mà không cần cài đặt bộ máy biên dịch phức tạp.
- Server-Side Rendering (SSR): Sử dụng Go Templates kết hợp với Bootstrap 5. Cách tiếp cận này triệt tiêu sự phức tạp của các framework JS cồng kềnh, giúp trang web load tức thì ngay cả trên đường truyền mạng yếu.
- Precise Math (decimal): Sử dụng thư viện
shopspring/decimalđể lưu trữ cân nặng, đảm bảo độ chính xác tuyệt đối và tránh các sai số toán học dấu phẩy động (float64 error) thường gặp.
🏗️ 2. Trụ cột kiến trúc: Single Binary và Stateless Logic
Kiến trúc của dự án hướng tới việc đơn giản hóa tối đa quy trình vận hành:
- Binary Embedding (embed.FS): Toàn bộ giao diện (HTML/CSS/JS) được nén và nhúng trực tiếp vào tệp nhị phân Go. Kết quả cuối cùng là một file duy nhất chứa cả Server và giao diện, không cần thư mục tài nguyên đi kèm.
- Standard Project Structure: Tuân thủ cấu trúc
/cmdvà/internal. Toàn bộ logic nghiệp vụ (DB, Handlers, Models) được cô lập trong/internal, ngăn chặn việc truy cập trái phép và tăng tính bảo mật cho mã nguồn. - Auto-migration System: Hệ thống tự động kiểm tra và khởi tạo cấu trúc bảng SQLite ngay khi khởi động lần đầu, giúp người dùng "chạy là xong" (Zero-configuration).
🔄 3. Workflow: Luồng xử lý dữ liệu và Trực quan hóa (Sequence Diagram)
Sơ đồ mô tả quy trình từ khi người dùng nhập thông tin tập luyện đến khi biểu đồ Heatmap được render:

⚡ 4. Các kỹ thuật "Pro-level" trong mã nguồn
- Scratch Docker Image: Quy trình đóng gói sử dụng Multi-stage build. Sau khi biên dịch code Go ở Stage 1, file thực thi được chuyển sang một Image rỗng hoàn toàn (scratch) ở Stage 2. Điều này tạo ra một Docker Image có dung lượng "siêu mẫu" (chỉ vài MB) và bảo mật tuyệt đối vì không chứa bất kỳ công cụ hệ thống nào khác.
- Internal Node Fallback: Dự án hỗ trợ tham số
-nđể định nghĩa đường dẫn node-bootstrap. Kỹ thuật này cho phép ứng dụng chạy hoàn toàn Offline trong mạng nội bộ mà không cần tải thư viện CSS/JS từ các CDN công cộng. - Viper Configuration Orchestration: Sử dụng Viper để quản lý cấu hình đa nguồn. Hệ thống sẽ ưu tiên Flag dòng lệnh -> Biến môi trường -> File YAML, mang lại sự linh hoạt tối đa cho việc triển khai trên Kubernetes hoặc Docker Compose.
- Persistent Session via UUID: Thay vì dùng Session truyền thống dễ gây rò rỉ, hệ thống tạo ra các UUID ngắn hạn lưu trong SQLite và Cookie HttpOnly để xác thực, đảm bảo sự cân bằng giữa tính đơn giản và bảo mật.
⚖️ 5. So sánh chiến lược
| Tiêu chí | Exercise Diary | Strava / MyFitnessPal | Google Sheets |
|---|---|---|---|
| Quyền sở hữu dữ liệu | Tuyệt đối (Self-host) | Bị kiểm soát bởi nhà cung cấp | Tuyệt đối |
| Giá cả | Miễn phí vĩnh viễn | Thuê bao hàng tháng | Miễn phí |
| Triển khai | Single Binary / Docker | N/A (App) | Web |
| Dung lượng | < 15MB (Docker) | Hàng trăm MB | N/A |
| Tính riêng tư | Rất cao | Thấp | Trung bình |
✅ Kết luận: Tại sao Exercise Diary là bài học mẫu mực cho Go Developers?
Exercise Diary chứng minh rằng một ứng dụng hữu ích không cần phải phức tạp. Bằng cách sử dụng các kỹ thuật như CGO-free SQLite và Binary Embedding, dự án đã tạo ra một sản phẩm có tính ổn định cực cao và chi phí bảo trì gần như bằng không.
Đối với các lập trình viên Backend, nghiên cứu dự án này mang lại giá trị về:
- Kỹ thuật xây dựng Single Binary Web App.
- Cách tối ưu hóa Docker Image với
scratch. - Tư duy thiết kế Database thực dụng cho các ứng dụng cá nhân.
All rights reserved