Hành trình xây dựng một dịch vụ Web - Phần 3: Đưa ứng dụng lên máy chủ
Ở phần trước, chúng ta đã chuẩn bị một máy chủ Linux có thể quản trị từ xa và được bảo vệ ở mức cơ bản. Tuy nhiên, máy chủ lúc này vẫn chỉ là một hệ điều hành trống. Để biến nó thành nơi cung cấp dịch vụ Web, chúng ta cần đưa ứng dụng đã xây dựng lên máy chủ và khởi động nó trong môi trường Docker.
Một trong những lợi ích của Docker là ứng dụng có thể được đóng gói cùng các thư viện và thành phần cần thiết. Nhờ đó, môi trường chạy trên máy chủ gần như giống với môi trường phát triển trên máy cá nhân. Chúng ta không phải cài đặt thủ công từng phiên bản thư viện hoặc lo lắng quá nhiều về sự khác biệt giữa các máy.
Trước hết, máy chủ cần được cài đặt Docker Engine và Docker Compose. Docker Engine chịu trách nhiệm tạo và chạy container, còn Docker Compose giúp mô tả nhiều dịch vụ trong cùng một tệp cấu hình. Một ứng dụng Web thực tế thường không chỉ có một container. Nó có thể gồm container ứng dụng, container cơ sở dữ liệu và sau này là reverse proxy hoặc các dịch vụ hỗ trợ khác.
Mã nguồn và cấu hình triển khai có thể được đưa lên máy chủ bằng nhiều cách: sao chép trực tiếp qua SSH, tải từ một kho mã nguồn hoặc lấy image đã xây dựng từ container registry. Với các dự án nhỏ, cách đơn giản là đưa tệp compose.yaml cùng những tệp cấu hình cần thiết lên máy chủ, sau đó yêu cầu Docker tải image và khởi động các dịch vụ.
Một cấu hình tối giản có thể mô tả hai dịch vụ:
services:
app:
image: example-web:1.0
ports:
- "8080:8080"
env_file:
- .env
depends_on:
- db
restart: unless-stopped
db:
image: postgres:16
volumes:
- db-data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
db-data:
Trong ví dụ này, dịch vụ app chạy ứng dụng Web và cho phép truy cập thông qua cổng 8080 của máy chủ. Dịch vụ db chạy cơ sở dữ liệu PostgreSQL nhưng chưa công khai cổng ra Internet. Dữ liệu cơ sở dữ liệu được lưu trong volume để không mất đi khi container bị dừng hoặc tạo lại.
Sau khi đưa cấu hình lên máy chủ, có thể khởi động hệ thống bằng các lệnh:
docker compose pull
docker compose up -d
docker compose ps
Lệnh đầu tiên tải các image cần thiết. Lệnh thứ hai tạo và khởi động container ở chế độ nền. Lệnh cuối cùng giúp kiểm tra trạng thái các dịch vụ. Nếu ứng dụng hoạt động bình thường, người dùng có thể thử truy cập:
http://SERVER_IP:8080
Ở giai đoạn này, ứng dụng đã chạy trên máy chủ nhưng chưa được truy cập bằng tên miền và cũng chưa có HTTPS. Việc sử dụng cổng 8080 chỉ phù hợp để kiểm tra ban đầu; khi triển khai hoàn chỉnh, yêu cầu từ người dùng sẽ được tiếp nhận qua cổng Web tiêu chuẩn và chuyển tiếp đến container ứng dụng.
Nếu dịch vụ không khởi động, cần kiểm tra trạng thái container và nhật ký hoạt động:
docker compose ps
docker compose logs app
Các lỗi thường gặp gồm image không tồn tại, biến môi trường chưa được khai báo, cổng bị sử dụng bởi dịch vụ khác hoặc ứng dụng không thể kết nối đến cơ sở dữ liệu.
Một điều đáng chú ý là hai container app và db phải giao tiếp với nhau qua mạng nội bộ của Docker. Trong ví dụ trên, Docker Compose tự động tạo mạng mặc định để kết nối các dịch vụ. Cơ chế này giúp ứng dụng sử dụng tên dịch vụ db thay cho địa chỉ IP cố định.
Ứng dụng hiện đã được đưa lên máy chủ, nhưng chúng ta mới chỉ sử dụng mạng Docker ở mức mặc định. Ở phần tiếp theo, chúng ta sẽ tìm hiểu Docker Network hoạt động như thế nào và cách các container giao tiếp với nhau bên trong hệ thống.