.env và những hệ lụy khi sử dụng

873

Bài viết được sự cho phép của tác giả Tống Xuân Hoài

Vấn đề

Có một lời khuyên là cấu hình nào có thể thay đổi tùy theo môi trường triển khai (deploy) thì nên đưa nó ra thành biến môi trường (Os Environment). Như vậy thì thông thường, chúng ta sẽ có một file .env để lưu trữ lại những biến đó, .env thường được nằm trong .gitignore và nó chỉ được tạo ra khi triển khai ứng dụng lên môi trường Internet hoặc khởi chạy trên máy local. Một tệp .env có thể trông giống như sau:

DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=password
...

Sau này, chúng ta cần .env linh hoạt hơn, có thể thay đổi tùy theo một biến môi trường truyền vào. Ví dụ như nó có thể thay đổi thông qua biến NODE_ENV. Lúc đó ta lại có .env.local, .env.development, .env.production… Mà khi khởi chạy, chỉ cần NODE_ENV=local node index.js thì .env.local sẽ tự động được sử dụng.

Một giải pháp khác so với cách dùng .env là lưu trữ lại cấu hình trong bất kì một tệp nào như là JavaScript, JSON, yml… cách dùng nó cũng tương tự như .env, có điều nó cho phép các cấu hình lồng nhau để dễ dàng phân vùng cấu hình một cách rõ ràng hơn. Nhưng chung quy lại, cả 2 vẫn là tạo ra các tệp lưu trữ biến môi trường.

Hiện tại, tôi vẫn đang sử dụng .env trong một số dự án mình tham gia, không thể phủ nhận được sự tiện lợi của .env. Tuy nhiên .env không phải là không có bất cập.

Đầu tiên là tính bảo mật. Các tệp .env không khác gì một file văn bản không mã hóa, vì thế bất kì ai cũng có thể đọc nó. Thậm chí mọi người thường hay sao chép hoặc gửi trực tiếp .env cho nhau thông qua một ứng dụng nhắn tin nào đó, khiến nội dung có thể bị lộ hoặc cố ý đẩy ra bên ngoài.

Các tệp .env không có phân quyền, nghĩa là bất kì ai cũng có thể truy cập vào được nếu xin phép, điều đó cũng vô tình tiết lộ tất cả nội dụng của tất cả các biến. Ví dụ, một bạn developer xin quyền khởi động project ở dưới máy local trỏ vào môi trường stagging, có thể chúng ta phải gửi toàn bộ nội dung .env ở môi trường stagging cho bạn ấy.

Vì .env là bí mật nên nó thường không được commit vào git. Nghĩa là lịch sử thay đổi các biến trong .env sẽ rất khó để có thể theo dõi thông qua công cụ này được. Hầu hết cách làm của chúng ta sẽ thêm một tệp gì đó như là .env.example để lưu lại những giá trị có thể có trong .env. Tuy nhiên cách làm này chỉ để biết được .env có gì chứ không quản lý được nội dung của .env. Nhiều lúc thêm một biến mới nhưng lại quên cập nhật trong các tệp môi trường khác lại khiến ứng dụng bị lỗi.

Thật tệ hại nếu như chúng ta lỡ tay commit .env vào trong dự án, hoặc quên mất trong .dockerignore… Đây là sai sót có yếu tố con người tuy nhiên lại là một trong những vấn đề gây ra rò rỉ thông tin bảo mật nếu không phát hiện sớm.

Vậy chúng ta có giải pháp nào tốt hơn không?

  Giới thiệu về RedisJSON - Mảnh ghép hoàn hảo cho RediSearch

  Bảo vệ thông tin nhạy cảm trong dự án sử dụng .env

Giải pháp thay thế .env truyền thống

Với những khuyến điểm tồn tại như ở trên, dĩ nhiên chúng ta sẽ có nhiều giải pháp thay thế để quản lý được các biến môi trường một cách hiệu quả hơn. Một trong số đó có thể kể đến như Azure Secrets Manager hay Vault. Tuy nhiên, các công cụ đó có vẻ phù hợp với cấu hình phức tạp và mở rộng hơn sau này. Nếu bạn cần một công cụ đơn giản hơn, chỉ đơn giản tập trung vào quản lý các biến bảo mật thì Infisical là một giải pháp dễ dàng mà tiết kiệm hơn nhiều.

Infisical là một giải pháp mã hóa đầu cuối mã nguồn mở, có thể sử dụng để đồng bộ hóa các biến môi trường trong nhóm và cơ sở hạ tầng. Bằng cách sử dụng Infisical, chúng ta có thể giải quyết được hầu hết các vấn đề nêu ra ở đầu bài viết.

Mã nguồn của Infisical có thể được tìm thấy tại Infisical Github, chúng ta có thể tự triển khai một máy chủ cho riêng mình bằng nhiều cách như sử dụng Docker, AWS, DigitalOcean… Hoặc nếu không, Infisical cung cấp dịch vụ Cloud hoàn toàn miễn phí với một số giới hạn. Bạn đọc quan tâm có thể đăng kí tại Infisical Signup.

Infisical

Infisical hỗ trợ rất nhiều dịch vụ Cloud như AWS, Vercel, Netlify… hoặc các Framework/Library như React, Vue, SvelteKit…

Ví dụ sử dụng trong Node: Sau khi thêm các biến môi trường vào Infisical, bạn có thể khởi động dự án Node.js bằng cách:

$ infisical init
$ infisical run -- npm start

Lúc này các biến môi trường sẽ được truyền vào trong ứng dụng Node.

Để xem đầy đủ các cách tích hợp cũng như sử dụng trong các Project khác, bạn đọc có thể xem tại Infisical Integrations.

Tổng kết

.env là một trong những cách giúp chúng ta quản lý biến môi trường trong triển khai ứng dụng lên nhiều môi trường khác nhau. Tuy nhiên, cách tiếp cận thông qua .env có phần lỗi thời và gây ra nhiều vấn đề cần phải được giải quyết. Infisical có thể được coi là một giải pháp đơn giản mà hiệu quả hơn so với Vault hay Azure Secrets Manager.

Bài viết gốc được đăng tải tại 2coffee.dev

Xem thêm:

Xem thêm việc làm CNTT hấp dẫn trên TopDev