Câu 1Trong ba giai đoạn của deploy, giai đoạn nào gom app.js và các file cần thiết về một dạng mà server công khai chạy được?
Deploy và biến môi trường — Từ chạy được ở máy bạn đến khi công khai
Bài viết này nằm trong khóa Kiến thức nền tảng về CNTT, xây dựng từ đầu những kiến thức CNTT thực tế tối thiểu mà bạn cần để lập trình và vibe coding.
Khi ở máy bạn thì chạy được nhưng công khai xong lại không chạy, nguyên nhân nằm ngoài mã nguồn. Các sơ đồ sẽ cho bạn thấy ba giai đoạn build, triển khai, công khai, và những biến môi trường đổi giá trị theo từng môi trường.
Bài viết này bàn về deploy, tức các bước đưa một ứng dụng đang chạy ở máy bạn ra công khai, và những biến môi trường đổi giá trị theo từng nơi chạy.
Cùng một app.js chạy ở hai nơi: máy tính của bạn và server công khai.
Khi ở máy bạn thì chạy được mà trên server công khai lại không, nguyên nhân nằm ngoài mã nguồn.
Khác biệt giữa hai nơi này chính là lý do công khai xong thì không chạy.
Deploy gồm ba giai đoạn: build, triển khai và công khai
Deploy là công việc đưa ứng dụng lên server công khai để bất kỳ ai cũng dùng được, và bên trong nó là ba giai đoạn: build, triển khai và công khai.
Giai đoạn thứ nhất là build (build: gom app.js và các file cần thiết về một dạng mà server công khai chạy được), và bộ file tạo ra là bản build (build output).
File cấu hình chỉ dùng ở máy bạn thì không vào bản build và ở lại máy bạn.
Thứ tới được server công khai chỉ là bản build đã gom xong.
Quay về bản build trước đó là rollback.
Từ deploy đôi khi chỉ nói tới giai đoạn triển khai, đôi khi nói tới cả ba giai đoạn.
Bạn cũng sẽ gặp cách nói CI/CD (Continuous Integration / Continuous Delivery: cơ chế tự động chạy ba giai đoạn này mỗi lần bạn ghi lại mã nguồn), nhưng chỉ phần tự động là mới, còn các giai đoạn thì vẫn thế.
Deploy là tên gọi chung cho ba việc
Deploy là làm liên tiếp ba việc: gom lại, gửi đi, và tiếp nhận.
Gom lại là build, gửi đi rồi khởi động là triển khai, tiếp nhận request đến URL là công khai, còn file cấu hình chỉ dùng ở máy bạn thì không nằm trong thứ được gom nên không tới được server công khai.
Môi trường phát triển và môi trường production — cùng một mã nguồn, nhưng thứ bao quanh thì khác
Khi app.js chạy được ở máy bạn mà không chạy trên server công khai, đó không phải vì mã nguồn đã đổi.
Đó là vì môi trường (environment: bộ gồm máy tính, hệ điều hành, môi trường chạy, cơ sở dữ liệu và các giá trị cấu hình được chuẩn bị để chạy app.js) thì khác nhau.
Trong bài "Môi trường phát triển là gì", môi trường phát triển là tổ hợp các công cụ; còn ở đây nó là nơi bạn chạy mọi thứ bằng những công cụ đó.
- app.js bạn chạy là cùng một file ở cả hai môi trường
- node do bạn tự cài
- Cơ sở dữ liệu nằm trong cùng máy tính đó
- Cấu hình in chi tiết lỗi ra màn hình
- node đã cài sẵn trên server
- Cơ sở dữ liệu nằm trên một server khác
- Cấu hình không in lỗi ra màn hình mà ghi vào log
Bên trong khung ngoài có hai môi trường, và app.js chúng chạy là cùng một file.
Chỉ mã nguồn là giống nhau; URL bạn mở, nơi đặt cơ sở dữ liệu và API key đều khác.
| Giả định đúng ở máy bạn | Trên server công khai | Điều xảy ra khi công khai |
|---|---|---|
| Kết nối tới localhost:5432 | Không có cơ sở dữ liệu tên đó | Lỗi khi thao tác lưu |
| API key là key thử nghiệm | Key thử nghiệm không được chấp nhận | Dịch vụ bên ngoài từ chối |
| In lỗi ra màn hình | Hiện nguyên vẹn trên màn hình người dùng | Người ta nhìn thấy chi tiết |
| Nội dung của app.js | Vẫn là app.js đó | Chạy y như vậy |
Ba dòng trên là những giả định chỉ đúng ở máy bạn.
Khi công khai xong mà không chạy, hãy nghi phần bên ngoài trước khi nghi mã nguồn.
Nếu bạn vào server công khai và sửa tay bản build hay cấu hình, lần deploy sau sẽ ghi đè và những sửa đổi đó biến mất.
Hãy sửa app.js trong môi trường phát triển, và sửa xong thì deploy thêm một lần nữa.
Chỉ mã nguồn là giống nhau
Môi trường là toàn bộ những thứ được chuẩn bị xung quanh app.js để nó chạy được.
Máy tính của bạn là môi trường phát triển, server công khai là môi trường production, và ngay cả khi hai bên có những thứ cùng vai trò thì nơi kết nối lẫn key vẫn mang giá trị khác nhau, nên khi công khai xong mà không chạy, hãy bắt đầu kiểm tra từ phần bên ngoài này.
Biến môi trường đổi giá trị theo từng môi trường mà không phải sửa mã nguồn
Việc đặt giá trị ra ngoài mã nguồn và để mã nguồn chỉ đọc tên chính là biến môi trường (environment variable: giá trị được đặt bên ngoài chương trình và được đọc theo tên lúc chạy).
Thứ bạn viết trong app.js chỉ là tên, còn ở máy bạn thì bạn viết giá trị vào .env (file liệt kê tên và giá trị của các biến môi trường).
- app.js — chỉ viết tên DATABASE_URL
- .env — viết giá trị, DATABASE_URL=localhost:5432
- .env không vào bản build và cũng không ghi vào Git
- app.js — tới nơi mà bên trong vẫn chỉ có cái tên
- Đăng ký DATABASE_URL=db.example.com
- app.js đang chạy đọc giá trị này theo tên
.env ở máy bạn chỉ được đọc bên trong chính máy tính bạn đặt nó.
Vì .env chứa API key nên nó không được ghi vào Git, và cũng không nằm trong bản build nên không tới được môi trường production.
Khi tài liệu hướng dẫn nói "hãy thiết lập biến môi trường cho production", đó là đăng ký đúng những cái tên ấy ở phía server công khai.
| Nơi khởi động | Giá trị lấy từ đâu | Giá trị của DATABASE_URL | Kết quả kết nối |
|---|---|---|---|
| Máy tính của bạn | .env ở máy bạn | localhost:5432 | Tới cơ sở dữ liệu ở máy bạn |
| Server công khai, đã đăng ký | Cấu hình nơi deploy | db.example.com | Tới cơ sở dữ liệu production |
| Server công khai, quên đăng ký | Không có ở đâu cả | Vẫn rỗng | Không kết nối được, dừng với lỗi |
Vẫn là app.js đó, nhưng giá trị nó đọc thay đổi theo nơi khởi động.
Giá trị được đọc vào lúc khởi động, nên đổi giá trị xong thì bạn khởi động lại.
Thứ đang chạy trong khung trái và khung phải là cùng một app.js.
Chỉ khác nhau ở những giá trị đặt bên ngoài nó.
Tên nằm trong mã nguồn, giá trị nằm ở môi trường
Biến môi trường là giá trị được đặt bên ngoài mã nguồn và được gọi ra theo tên.
Ở máy bạn thì bạn viết nó vào file tên là .env, còn trên server công khai thì bạn đăng ký đúng cái tên đó như một cấu hình của server ấy, nên khi công khai xong mà không chạy, hãy xem trước tiên là bạn có quên bước đăng ký này không.
Thông tin bí mật chỉ đặt trong biến môi trường, không đưa vào mã nguồn và bản build
Trong các giá trị bạn đặt vào biến môi trường, thứ cần để ý nhất là thông tin bí mật (secret: chuỗi ký tự mà người khác biết được thì mạo danh bạn được), tiêu biểu là API key và mật khẩu.
Với biến môi trường mà frontend đọc, giá trị được ghi thẳng vào bản build ngay lúc build.
Giá trị đã ghi vào đó sẽ tới nguyên vẹn thiết bị của bất kỳ ai mở URL.
Thông tin bí mật chỉ đặt trong biến môi trường production, thứ không vào bản build, và bạn đăng ký chúng ở màn hình cấu hình của nơi deploy.
Giá trị đã đăng ký không nằm trong bản build; server công khai truyền nó vào lúc khởi động app.js.
Nếu bạn quên đăng ký, nó khởi động với cái tên có sẵn nhưng không có giá trị.
Giá trị đã đăng ký chỉ tồn tại ở phía server công khai, và giá trị đó không được chép sang bản build hay .env ở máy bạn.
Sau khi công khai, bản thân giá trị chỉ tồn tại ở đúng một nơi.
- API_KEY chứa giá trị dùng cho production
- Chỉ app.js đang chạy và người thao tác được trên server mới đọc được
- Trong app.js chỉ có cái tên API_KEY
- Bản thân giá trị thì không được viết ở đó
- Thứ tới nơi chỉ là HTML và JavaScript của màn hình
- Không chứa giá trị của thông tin bí mật
Giá trị chỉ nằm trong biến môi trường production, không nằm trong bản build và cũng không nằm trên thiết bị của người dùng.
Bài "Những điểm cần chú ý về bảo mật" sẽ bàn về cách nhìn xem mỗi chỗ đặt giá trị có bao nhiêu người đọc được.
Gom chỗ đặt giá trị về đúng một nơi
Thông tin bí mật là chuỗi ký tự mà nếu bị lộ thì người khác sẽ dùng được nó.
Viết nó vào mã nguồn thì build sẽ gom nó lại và đưa tới tận thiết bị của người dùng, nên thay vì viết giá trị, bạn hãy đăng ký nó như một cấu hình trên server công khai và chỉ viết cái tên trong mã nguồn.
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2my-app chạy được ở máy bạn, nhưng công khai xong thì dừng với lỗi. Nguyên nhân nào nêu trong bài là đúng?
Câu 3Nơi đặt thông tin bí mật như API key hay mật khẩu cơ sở dữ liệu, chỗ nào đúng với phần bài đã trình bày?