Trước đây mình có đọc một bài của 1 anh dev nước ngoài, đại để là nên đẩy code lên môi trường production càng sớm càng tốt, như vậy thì sẽ dễ cấu hình và điều chỉnh app hơn và đặc biệt là không cần phải chuyển đổi 1 project chạy tốt trên localhost => chạy trên server (cái này khá là mất thời gian và cũng chẳng vui vẻ gì).

Vì vậy hôm nay mình sẽ làm 1 bài ngắn, giới thiệu cách đóng gói Flask app + uWSGI + Nginx lên container và chạy được production luôn (ở mức cơ bản thôi nhen). Có update code gì thì cũng có khuôn mẫu để up, ko sợ phải điều chỉnh nhiều khi deploy.

Cũng tính làm 1 bài về setup mấy flask + uwsgi + nginx bằng tay, nhưng lười quá nên thôi làm bài container này. Về mặt lý thuyết thì mỗi container 1 process, nhưng lười thì nhét chung vô 1 con :P.

Lưu ý: Chỉ nên với những những dụng Flask nào scale nhỏ, all-in-one thì mình sẽ đóng gói lại chung 1 container trong docker cho dễ quản lý. Còn với những project lớn thì nên tách ra cho dễ scale lên

 

Workflow cơ bản cho bài này

Người dùng sẽ kết nối tới Nginx ở port 80, sau đó request sẽ được đẩy tới cho uwsgi (trong cùng 1 container) và cuối cùng là đẩy tới Flask để xử lý.

Cấu trúc của project

Hướng dẫn chạy project

Source full ở đây: GitHub

  1. Tải project về
  2. Chạy file build_docker.sh
  3. Chạy file run_docker.sh

Cách hoạt động cơ bản

Ở đây, để demo cách hoạt động cơ bản, mình có viết sẵn 1 file main.py đóng vai trò là 1 API server.

API này sẽ nhận 1 HTTP POST Request và thực hiện một tác vụ tương ứng trên server. Tác vụ này có thể là clean DB, đồng bộ thư mục, xóa file cũ… tùy theo bạn định nghĩa trong biến COMMAND.

Server sẽ check POST request nếu có đủ 3 field là time, user và sign => kiểm tra tiếp sign này (tạm gọi là sign_1 do client gởi lên). Với sign_2 do server tự tạo dựa trên time, user và SecretKey  (SecretKey này đã gởi riêng cho client trước đó). Nếu sign_1 == sign_2 thì mới thực hiện chạy lệnh

File main.py sẽ có dạng như vầy, demo một ứng dụng cơ bản

Tạo một file Dockerfile như sau để build image. Ở đây, mình dựa trên image tiangolo/uwsgi-nginx-flask:python3.6 để chạy

Chạy script build_docker.sh

Chạy script run_docker.sh

Ở đây, ta đã bind trực tiếp port 80 của máy host với port 80 của container, bạn có thể dùng trình duyệt truy cập vào IP của máy host để kiểm tra container đã hoạt động dc hay chưa, ở đây IP của máy ảo mình cài là 192.168.11.130

dong-goi-ung-dung-flask-voi-docker-2

Ta đã truy cập thành công tới web service trên container.

Kiểm tra hoạt động của API

Tiếp theo, ta cần kiểm tra tiếp xem API đã hoạt động ổn định chưa, dùng file client.py, để test thử API.

Chạy lệnh python client.py để test gởi request tới server. Trên container, ta sử dụng lệnh docker logs để kiểm tra các request được gởi tới:

Mở rộng API

Trên đây là một ví dụ cơ bản về 1 Flask API chạy trong container, bạn có thể mở rộng thêm bằng nhiều cách như sử dụng thêm database, sử dụng thêm queue để chứa các request được gởi đến.

Dưới đây là một cách tổ chức project mẫu, phân chia thành nhiều module (tham khảo thêm tại: https://github.com/tiangolo/uwsgi-nginx-flask-docker)

Đọc thêm

  • Hướng dẫn cài đặt Python và virtualenv
  • Hướng dẫn xây dựng REST API cơ bản với Flask (đang viết)
  • Hướng dẫn xây dựng API với Djano (đang viết)
  • Hướng dẫn deploy ứng dụng web Django (đang viết)

Tham khảo

https://github.com/tiangolo/uwsgi-nginx-flask-docker

LEAVE A REPLY

Please enter your comment!
Please enter your name here