Bài 8 trong loạt Vibe Code A to Z — hướng dẫn vibe code bằng Claude Code cho người Việt. Bài 7: đọc code mình không viết.
Trên máy bạn, mọi thứ chạy ngon. Bấm vào là ra, form gửi được, dữ liệu vào đúng chỗ. Bạn ngồi nhìn nó một lúc và thấy khá hài lòng.
Rồi bạn đưa nó lên mạng, mở link bằng điện thoại, và nhận về một trang trắng.
Khoảnh khắc đó gần như ai cũng gặp, và nó gây hoang mang hơn mức cần thiết — vì bạn vừa được dạy rằng thứ chạy trên máy mình không đảm bảo điều gì cả. Nhưng nhìn theo hướng khác thì đây là tin tốt: đó là lần đầu tiên dự án của bạn nói thật.
Máy của bạn là một môi trường được nuông chiều. Nó có sẵn mọi thứ bạn đã cài trong nhiều tháng, có sẵn mọi file bí mật bạn để đâu đó, có sẵn cả những thứ bạn quên là mình từng cài. Máy chủ thì không có gì cả ngoài đúng những thứ bạn khai báo.

Deploy thật ra là gì
Bỏ qua thuật ngữ, cơ chế rất đơn giản: bạn nối kho code của mình với một dịch vụ chạy sản phẩm. Từ đó trở đi, mỗi lần bạn đẩy code lên là một lần nó tự dựng lại sản phẩm từ đầu và thay bản đang chạy.
Với dự án của tôi, nhánh chính đã nối thẳng vào bản chạy thật. Đẩy code lên nhánh đó nghĩa là phát hành, không có bước xác nhận nào ở giữa. Tôi ghi hẳn dòng đó vào đầu tài liệu dự án — không phải để trang trí, mà vì đã có lần tôi quên mất điều này.
Bộ đôi tôi dùng, và cũng là bộ đôi tôi khuyên người mới bắt đầu: một chỗ chạy giao diện, một chỗ giữ dữ liệu. Chỗ chạy giao diện lo việc dựng và phục vụ trang web. Chỗ giữ dữ liệu lo cơ sở dữ liệu, tài khoản người dùng, đăng nhập. Cả hai đều có gói miễn phí đủ dùng cho sản phẩm đầu tiên, và cả hai đều nối được bằng vài cú bấm.
Điều đáng nói là bước này Claude Code làm hộ bạn được phần lớn: nó viết cấu hình, nó sinh cấu trúc cơ sở dữ liệu, nó nối hai bên với nhau. Phần bạn phải tự làm chỉ còn mấy việc mà không ai làm hộ được — đăng nhập, xác thực hai lớp, bấm nút đồng ý. Nên khoảng cách thật sự ở bài này không nằm ở kỹ thuật. Nó nằm ở chỗ biết cái gì dễ hỏng.
Thứ không bao giờ được đi cùng code
Đây là điều quan trọng nhất của cả bài, nên tôi tách riêng ra.
Dự án của bạn có một file chứa toàn bí mật: khóa truy cập cơ sở dữ liệu, khóa dịch vụ gửi email, mã bí mật để ký các đường link. File đó nằm trên máy bạn và không được đẩy lên kho code, kể cả kho riêng tư. Lý do không phải vì sợ người khác nhìn thấy — mà vì bí mật một khi đã vào lịch sử kho code thì nó nằm đó vĩnh viễn, kể cả sau khi bạn xóa file đi.
Vậy máy chủ lấy bí mật ở đâu? Bạn khai riêng, một lần, trong phần cấu hình của dịch vụ. Hai nơi, hai bản khai, cùng nội dung.
Và đây chính là chỗ sinh ra lỗi phổ biến nhất của người mới: thêm một biến vào máy mình, quên thêm nó vào máy chủ. Trên máy chạy ngon vì máy có. Trên mạng hỏng vì máy chủ không có. Thông báo lỗi thường vô thưởng vô phạt, và bạn sẽ đi tìm nguyên nhân ở mọi chỗ trừ chỗ đúng.
Tôi nói được điều này chắc chắn vì tôi đang mắc đúng lỗi đó. Website của tôi có một mã bí mật dùng để ký link hủy đăng ký email. Trên máy tôi có. Trên máy chủ, tôi chưa đặt — nó đang tạm dùng một khóa khác thay thế, chạy vẫn ra kết quả, nên chẳng có gì báo cho tôi biết. Tôi phát hiện ra trong một buổi rà soát, ghi vào mục việc-còn-lại của tài liệu dự án, và tính tới lúc viết bài này thì nó vẫn nằm nguyên trong danh sách đó.
Cách phòng, gọn trong một câu: thêm biến ở máy mình xong thì mở ngay bảng cấu hình máy chủ, thêm nốt. Cùng một lượt, không để lại sau. Việc để lại sau là việc không bao giờ được làm.
Ba thứ hay hỏng khác, và vì sao chúng chỉ hỏng trên máy chủ
Chữ hoa chữ thường trong tên file. Windows và macOS coi Anh-Bia.jpg với anh-bia.jpg là một. Máy chủ chạy Linux thì coi đó là hai file khác nhau. Ảnh mất, trang lỗi, và trên máy bạn thì vẫn hiện ra bình thường. Ở bài 6 tôi có kể chuyện một file skill của tôi đặt tên chữ thường — cùng một loại bẫy, khác chỗ phát nổ.
Thứ chạy được vì máy bạn có sẵn. Một chương trình bạn cài từ năm ngoái, một font chữ có sẵn trong máy, một biến hệ thống ai đó từng đặt hộ bạn. Code dùng đến chúng thì trên máy bạn chạy, lên máy chủ thì không.
Múi giờ. Máy chủ mặc định chạy theo giờ quốc tế, không theo giờ Việt Nam. Mọi thứ liên quan tới thời gian — lịch chạy tự động, dấu thời gian hiển thị, hạn dùng — đều lệch bảy tiếng nếu bạn không xử lý. Lỗi này đặc biệt khó chịu vì nó không làm hỏng gì cả, nó chỉ làm mọi thứ sai giờ.
Cái bẫy tôi thích kể nhất: giới hạn gói miễn phí
Chuyện này xảy ra với website của tôi, và tôi kể lại vì nó đại diện cho cả một loại lỗi.
Dịch vụ tôi dùng có gói miễn phí, và gói đó cho phép tối đa hai tác vụ chạy tự động theo lịch. Tôi đang có đúng hai: một cái kiểm tra sức khỏe hệ thống, một cái gửi email chăm sóc học viên.
Rồi tôi thêm một tác vụ thứ ba cho một chiến dịch mới.
Không có thông báo lỗi nào. Không có cảnh báo nào. Tác vụ gửi email chăm sóc học viên chỉ đơn giản là biến mất khỏi danh sách — và tôi không biết, vì thứ duy nhất báo cho bạn biết một email không được gửi là người lẽ ra phải nhận nó, mà người đó thì không biết là mình đáng lẽ được nhận.
Bài học kỹ thuật thì nhỏ: gộp cả ba việc vào một tác vụ duy nhất, xong. Bài học thật sự thì lớn hơn và nó không nằm ở kỹ thuật: giới hạn của gói miễn phí không báo lỗi, nó âm thầm cắt bớt. Trước khi thêm bất cứ thứ gì chạy tự động, hãy mở trang bảng giá ra đọc phần giới hạn — số tác vụ định kỳ, số lần chạy, dung lượng, băng thông. Mất năm phút, và nó tiết kiệm cho bạn cái loại lỗi khó phát hiện nhất: loại không gây ra triệu chứng nào.
Cơ sở dữ liệu là chỗ duy nhất không quay lui được
Code hỏng thì quay về bản trước, mất vài phút. Dữ liệu thì không.
Nên nguyên tắc ở phần này khác hẳn phần trên, và nó chỉ có ba dòng:
- Thay đổi cấu trúc cơ sở dữ liệu thì đọc kỹ trước khi chạy, mỗi lần một thay đổi, không gộp.
- Đừng bao giờ nối cơ sở dữ liệu thật vào phiên làm việc thường ngày. Câu "cho tôi xem thử dữ liệu người dùng" gõ ra rất nhanh, và nó không hỏi lại bạn đang trỏ vào bản nào.
- Bật sao lưu tự động ngay từ ngày đầu, trước cả khi có dữ liệu đáng để sao lưu. Ngày bạn cần đến nó là ngày đã quá muộn để bật.
Ở bài 7 tôi có nhắc một dòng nguyên tắc mà tôi ghi vào tài liệu dự án: trạng thái phải xác minh bằng thực tế, không tin báo cáo. Nguyên tắc đó sinh ra chính từ phần này. Claude báo đã áp xong thay đổi lên cơ sở dữ liệu — bạn mở cơ sở dữ liệu ra xem. Không phải vì nó hay nói dối, mà vì đây là chỗ sai thì không sửa lại được bằng một lần đẩy code.
Tài liệu tải về
Tôi gói thành một checklist deploy in ra được: các bước nối kho code với dịch vụ chạy, bảng liệt kê biến môi trường kèm chỗ đánh dấu đã-đặt-ở-máy-chủ-chưa, mười lỗi hay gặp ở lần deploy đầu kèm triệu chứng để nhận diện, phần giới hạn gói miễn phí cần đọc trước, và quy trình xử lý khi bản chạy thật bị hỏng — theo thứ tự bình tĩnh, không phải theo thứ tự hoảng loạn.
📥 Tải miễn phí
Checklist Deploy Sản Phẩm Đầu Tiên
Tài liệu do tôi biên soạn từ trải nghiệm thật, tham khảo tài liệu chính thức của các nhà cung cấp dịch vụ. Nền tảng thay đổi giao diện và giới hạn khá thường xuyên — khi có khác biệt, trang tài liệu của chính nhà cung cấp là nguồn đúng. Còn cách nghĩ về việc nào nên giao cho công cụ và việc nào phải tự tay giữ, nằm ở phần nền trong khóa AI Fluency.
Điều tôi nhận ra
Lần đầu đưa được một thứ mình làm lên mạng và gửi link cho người khác, cảm giác rất lạ. Nó không giống cảm giác làm xong việc. Nó giống cảm giác vừa mở cửa hàng.
Vì đúng là như vậy. Trên máy bạn, sản phẩm chỉ phải làm hài lòng một người, và người đó biết rõ chỗ nào không nên bấm. Trên mạng thì nó phải tự đứng được trước những người không có ai hướng dẫn, mở bằng máy khác, mạng khác, ở giờ bạn đang ngủ.
Và đây là chỗ tôi thấy nhiều người dừng lại lâu nhất, lâu hơn cả chỗ học code. Họ có sản phẩm chạy được, nhưng chưa dám mở cửa, vì mở cửa nghĩa là nhận về phản hồi thật. Tôi không có lời khuyên nào thông minh cho chuyện này. Chỉ có một quan sát: mọi thứ đáng làm mà tôi từng làm đều bắt đầu bằng một phiên bản tôi thấy chưa đủ tốt để đưa ra.
Đến đây thì bạn đã có một sản phẩm đang chạy thật trên mạng. Còn một câu hỏi mà tới lúc này mới thật sự cần trả lời, và nó là câu hầu hết các bài hướng dẫn vibe code trên mạng đều tránh: cái này tốn bao nhiêu tiền một tháng, và tiền chảy đi đâu. Đó là chuyện của bài sau.




