Redis Labs làm bạn buồn 😭 Đã có Docker

Redis là một công nghệ hữu hiệu nhưng cũng rất đắt đỏ. Việc sử dụng gói miễn phí của Redis Labs đã làm mình xỉu up xỉu down. Cũng may là có Docker...nhưng cũng không hẳn.


Đôi lời tự sự

Gần đây thì mình có tham gia vào kha khá dự án nhưng hầu hết các dự án mình đều xin để đảm nhiệm vị trí backend. Có vẻ vì đã có một khoảng thời gian làm việc với frontend và mình cảm thấy việc thiết kế giao diện không còn cho mình cảm hứng nữa. Vậy nên mình chuyển xuống mảng backend để cải thiện thêm mảng kiến trúc hệ thống.

Khi làm việc với backend thì ngoài việc thiết kế API và kiến trúc hệ thống thì có một việc nữa rất quan trọng đó là deploy. Trước đây thì mình đa phần sử dụng các PaaS như Heroku hay Amazon để deploy. Tuy nhiên khi số lượng đội nhóm lớn hơn và các môi trường, hệ điều hành cũng khác nhau tỉ lệ thuận với số lượng ấy thì mình mới thấy được sự phức tạp trong việc thiết kế một hệ thống và dùng được cho mọi người.

Do đó mình tìm đến Docker và hiểu được thêm về khái niệm về Image, Container, Registry và cả Docker Compose là như thế nào.


Vì sao mình quyết định sử dụng Docker?

Để giải thích cho câu hỏi vì sao ở trên thì chúng ta sẽ cần đi qua một chút về dự án mình đang làm nhé. Trong dự án này, mình gánh vác trách nhiệm thiết kế API và máy chủ. Nhóm tech stack mà mình sử dụng là GraphQL cho API Gateway, PostgreSQL cho database, Redis cho In-memory database. Vậy với nhóm tech stack như vậy thì vấn đề của mình là gì?

Độ lớn nhân sự của dự án này không phải là quá lớn, chỉ ở mức 4 người. Tuy nhiên, vì đây là dự án nhỏ nên hầu hết mọi người đều vừa phải tương tác với backend và frontend. Vậy nên để mà setup môi trường cho tất cả mọi người trong team như là Redis server hay PostgreSQL server là rất tốn công. Vì vậy mình quyết định deploy lên một BaaS là Heroku.

Đến đây thì tưởng chừng mọi việc đã êm xui rồi, cho đến khi Redis Labs báo Max number of clients reached. Cho những bạn chưa biết thì đây không phải một lỗi mà là một tính năng...à không một hạn chế trong các gói điều khoản của Redis Labs. Do server của mình chạy free nên Redis Labs chỉ hạn chế 30 kết nối.

Tính năng được cung cấp bởi Redis Labs gói miễn phí

Các giải pháp mình nghĩ ra lúc này đó là tạo ra một standby database sẵn sàng backup cho server Redis chính khi đạt quá giới hạn hay đơn giản hơn là sử dụng redis connection pool để hạn chế việc leak connection.

Tuy nhiên, do chưa có nhiều kinh nghiệm, mình không thể đảm bảo được tính khả thi của các giải pháp trên. Điều đó sẽ ảnh hưởng rất lớn đến thời gian phát triển dự án.

Vậy nên, mình đã sử dụng một giải pháp khác đó là giữ cho các server của mọi người trong nhóm ở local, điều này sẽ giảm được sự quá tải giới hạn kết nối của Redis.

Vậy nên, do đã biết đến Docker trước đó nên mình quyết định nhảy vào vọc thử coi như đây là cơ hội tốt và cũng là để giải quyết luôn cả vấn đề trên khi team mình không có nhiều chi phí phát triển.


Hướng giải quyết bằng Docker

Docker là một công rất hữu ích cho việc đóng gói và deploy sản phẩm. Trước khi đi vào triển khai và áp dụng từ các nguồn mình học được, cụ thể là một số nguồn như

Video hướng dẫn của Ben Awad về fullstack app bằng PostgreSQL, GraphQL và React. Trong video này có bao gồm cách deploy lên DigitalOcean bằng Docker

Sau khi đã tham khảo qua các nguồn trên, mình tạo ngay một Dockerfile trong thư mục backend của dự án. Dockerfile được sử dụng giống như một guideline hướng dẫn hệ thống chạy chương trình của bạn thông qua các bước nhất định. Dự án mình cần đóng gói bao gồm Redis, PostgreSQL và API server. Dockerfile cho API server sẽ trông như thế này

Dockerfile cho API Server

Sau đó thì mình chạy lên

docker build -t <tên của image> .
Quá trình build image trên Terminal

Lúc này thì image đã được build hoàn tất, mình truy cập vào docker desktop để chạy image

Đây là image mình vừa build với tên là ramen/topping:1.0 trong đó 1.0 là tên tag

Chạy image này thì kết quả nhận được là

Màn hình Terminal báo lỗi

Có thể thấy được đây là một lỗi connection đến từ phía server, do API server hiện tại của mình đang kết nối với các database localhost nên khi chạy image, không có bất kì database đang chạy.

Vậy nên biện pháp để giải quyết vấn đề này là sử dụng Docker Compose


Vấn đề nối tiếp vấn đề với Docker Compose?

Docker Compose trong hệ sinh thái của Docker là một công cụ hỗ trợ chạy nhiều Docker Container cùng một lúc. Các thứ tự và môi trường của các container này sẽ được khai báo thông qua một file YAML.

Server mình cần compose bao gồm Redis, PostgreSQL và API Server ở trên. Sau khi đã có image của API server, mình sẽ bắt đầu khai báo Docker Compose thông qua file docker-compose.yml.

docker-compose.yml

Như đã thấy ở trên thì mình có tổng cộng là 3 con server, một server cho Redis, một cho Postgres và một cho API server. Giải thích sơ qua về các cú pháp thì ở đây 3 server sẽ tương ứng với 3 service. Service Redis sẽ tải về image tương ứng tên là redis chạy trên port 6379 và service Postgres sẽ tải về image postgres tương ứng trên port 5432. Service còn lại là API server sẽ sử dụng image "ramen/topping:1.0" mà chúng ta đã tạo ở trên.

docker-compose up
Chạy lệnh này để khởi động Docker Compose
Các container trong Docker Desktop

Vậy là chúng ta đã có một con server thay thế cho Redis Labs ban đầu. Nếu đúng theo trình tự thì mình sẽ deploy con compose này lên docker hub. NHƯNG. Mọi việc có vẻ không đơn giản như vậy.

Tuy nhiên vì đây là một bài tự sự nên mình cũng chia sẻ thêm, vấn đề thật sự chưa được giải quyết. Bởi, mặc dù đã mở các cổng cho Redis và Postgres nhưng API Server của mình vẫn không thể kết nối đến các server. Nếu anh em nào có cách giải quyết, cho tui xin một cánh tay 😥.

Góc Của Chung

Góc Của Chung