❤️ AZDIGI chính thức cập nhật hệ thống blog mới hoàn chỉnh. Tuy nhiên có thể một số bài viết bị sai lệch hình ảnh, hãy ấn nút Báo cáo bài viết ở cuối bài để AZDIGI cập nhật trong thời gian nhanh nhất. Chân thành cám ơn.
Ở Bài 9, bạn đã học cách quản lý environment variables trong Docker một cách bài bản, từ file .env, cú pháp biến nâng cao, multi-environment setup cho đến Docker secrets. Cuối bài, mình có nhắc: tất cả vẫn chạy qua IP và port, chưa có domain, chưa có HTTPS.

Bài này sẽ giải quyết đúng vấn đề đó. Bạn sẽ setup Nginx Proxy Manager : một reverse proxy có giao diện web, tích hợp SSL miễn phí , để mỗi container có domain riêng, HTTPS tự động, sẵn sàng cho production.
Vấn đề: Mỗi app một port
Khi chạy nhiều ứng dụng trên cùng một VPS bằng Docker, mỗi app sẽ expose một port khác nhau:
- WordPress:
http://your-ip:8080 - Uptime Kuma:
http://your-ip:3001 - Portainer:
http://your-ip:9443 - n8n:
http://your-ip:5678
Vấn đề rõ ràng nhận ra ngay:
- Khó nhớ port: ai mà nhớ nổi 8080 là WordPress, 3001 là Uptime Kuma?
- Không chuyên nghiệp: không lẽ sẽ sử dụng đường dẫn
http://103.45.67.89:8080gửi cho khách truy cập thì cũng kỳ - Không có HTTPS: trình duyệt hiện cảnh báo “Not Secure”, dữ liệu truyền không mã hoá
- Phải mở nhiều port trên firewall: mỗi app một port, tăng rủi ro bảo mật
Giải pháp? Dùng reverse proxy.
Reverse Proxy là gì?
Hãy hình dung VPS của bạn như một toà nhà văn phòng. Mỗi container là một phòng ban (phòng kế toán, phòng nhân sự, phòng kỹ thuật). Nếu không có lễ tân, khách đến phải tự tìm phòng, chạy lên tầng 3, sang phòng 301, rồi lại xuống tầng 2…
Reverse proxy chính là lễ tân. Tất cả khách (request) đều đến lễ tân (cổng 80/443) trước. Lễ tân hỏi: “Bạn cần gặp ai?”, rồi dẫn khách đúng phòng ban.
Trong kỹ thuật: reverse proxy là một server đứng phía trước các ứng dụng, nhận tất cả request đến, kiểm tra domain/path, rồi chuyển tiếp (forward) đến đúng container phía sau.
Trước và sau khi có reverse proxy
Không có reverse proxy:
Client → http://103.45.67.89:8080 → WordPress container
Client → http://103.45.67.89:3001 → Uptime Kuma container
Client → http://103.45.67.89:5678 → n8n container
Có reverse proxy:
Client → https://blog.example.com → Reverse Proxy → WordPress container
Client → https://status.example.com → Reverse Proxy → Uptime Kuma container
Client → https://n8n.example.com → Reverse Proxy → n8n container
Lợi ích của reverse proxy
- Domain thay port:
blog.example.comdễ nhớ hơn:8080 - SSL tập trung: chỉ cần cài SSL ở reverse proxy, tất cả app phía sau đều có HTTPS
- Bảo mật: các app không expose port ra internet, chỉ reverse proxy mới tiếp xúc bên ngoài
- Load balancing: phân tải khi có nhiều instance của cùng một app
- Firewall đơn giản: chỉ cần mở port 80 và 443
Nginx Proxy Manager – Reverse proxy cho người thích giao diện dễ dùng
Có nhiều reverse proxy phổ biến: Nginx, Traefik, Caddy, HAProxy… Mỗi cái đều mạnh, nhưng hầu hết yêu cầu bạn viết config file thủ công, dài dòng và dễ sai cú pháp.
Nginx Proxy Manager (NPM) giải quyết vấn đề đó bằng cách cung cấp một giao diện web để quản lý reverse proxy. Bạn không cần viết một dòng config Nginx nào, tất cả thao tác đều click trên trình duyệt.
Tại sao chọn Nginx Proxy Manager?
- GUI web-based: thêm domain, cấu hình proxy, quản lý SSL bằng vài cú click
- Tích hợp Let’s Encrypt: SSL miễn phí, tự động gia hạn, không cần chạy certbot thủ công
- Access Lists: giới hạn truy cập cho các trang admin
- Custom Nginx config: vẫn có thể thêm config Nginx tuỳ chỉnh khi cần
- Chạy bằng Docker: deploy trong 2 phút, không ảnh hưởng hệ thống host
Nói ngắn gọn: NPM biến việc quản lý reverse proxy từ “sửa config file, reload nginx, debug lỗi cú pháp” thành “điền form, bấm Save”.
Deploy Nginx Proxy Manager bằng Docker Compose
Trước tiên, tạo thư mục project:
mkdir -p ~/docker/nginx-proxy-manager
cd ~/docker/nginx-proxy-manager
Tạo file docker-compose.yml:
version: "3.8"
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "81:81" # Admin panel
volumes:
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
networks:
- proxy-network
networks:
proxy-network:
name: proxy-network
driver: bridge
volumes:
npm_data:
npm_letsencrypt:
Giải thích cấu hình
- Port 80: nhận traffic HTTP (sẽ redirect sang HTTPS)
- Port 443: nhận traffic HTTPS
- Port 81: giao diện admin của NPM: chỉ dùng để quản lý, sau khi setup xong có thể đóng port này trên firewall
- npm_data: lưu database (SQLite mặc định), cấu hình proxy hosts
- npm_letsencrypt: lưu SSL certificates từ Let’s Encrypt
- proxy-network: network dùng chung giữa NPM và các container app: quan trọng nhất, đừng quên!
Khởi chạy:
docker compose up -d
Kiểm tra container đã chạy:
docker compose ps
NAME STATUS PORTS
nginx-proxy-manager Up 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:81->81/tcp
Tuỳ chọn: Dùng MariaDB thay SQLite
Mặc định NPM dùng SQLite, đủ tốt cho hầu hết trường hợp. Nếu bạn quản lý nhiều proxy hosts (50+) hoặc muốn dùng database riêng, có thể chuyển sang MariaDB:
version: "3.8"
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81"
environment:
DB_MYSQL_HOST: npm-db
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: npm
DB_MYSQL_PASSWORD: npm_password_change_me
DB_MYSQL_NAME: npm
volumes:
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
networks:
- proxy-network
depends_on:
- npm-db
npm-db:
image: mariadb:10.11
container_name: npm-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root_password_change_me
MYSQL_DATABASE: npm
MYSQL_USER: npm
MYSQL_PASSWORD: npm_password_change_me
volumes:
- npm_db_data:/var/lib/mysql
networks:
- proxy-network
networks:
proxy-network:
name: proxy-network
driver: bridge
volumes:
npm_data:
npm_letsencrypt:
npm_db_data:
Với hầu hết người dùng, SQLite là đủ. Bạn không cần MariaDB trừ khi có lý do cụ thể.
Setup ban đầu Nginx Proxy Manager

Sau khi container chạy, mở trình duyệt và truy cập:
http://your-vps-ip:81
Đăng nhập bằng tài khoản mặc định:
- Email:
admin@example.com - Password:
changeme
Ngay khi đăng nhập lần đầu, NPM sẽ yêu cầu bạn:
- Đổi tên và email admin: nhập email thật của bạn
- Đổi password: chọn password mạnh, đây là tài khoản quản trị reverse proxy
Sau khi đổi password, bạn sẽ thấy dashboard chính của NPM, hiện tại còn trống vì chưa cấu hình gì. Mình sẽ thêm proxy hosts ở phần tiếp theo.

Deploy ứng dụng mẫu
Để demo reverse proxy, mình sẽ deploy 2 ứng dụng: WordPress và Uptime Kuma. Cả hai đều chạy trên cùng Docker network với NPM, đây là điều kiện bắt buộc để NPM forward request được.
App 1: WordPress
Tạo thư mục và file compose cho WordPress:
mkdir -p ~/docker/wordpress
cd ~/docker/wordpress
Tạo file docker-compose.yml:
version: "3.8"
services:
wordpress:
image: wordpress:latest
container_name: wordpress-app
restart: unless-stopped
environment:
WORDPRESS_DB_HOST: wordpress-db
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: wp_password_change_me
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
networks:
- proxy-network
wordpress-db:
image: mariadb:10.11
container_name: wordpress-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root_password_change_me
MYSQL_DATABASE: wordpress
MYSQL_USER: wp_user
MYSQL_PASSWORD: wp_password_change_me
volumes:
- wp_db_data:/var/lib/mysql
networks:
- proxy-network
networks:
proxy-network:
external: true
volumes:
wp_data:
wp_db_data:
Lưu ý quan trọng:
- Không có phần
ports:cho WordPress: container không expose port nào ra ngoài. Chỉ có NPM mới truy cập được qua Docker network. proxy-networklàexternal: true: vì network này đã được tạo bởi NPM compose file ở trên. Tất cả app muốn dùng reverse proxy đều phải join network này.
docker compose up -d
App 2: Uptime Kuma
Uptime Kuma là công cụ monitoring uptime, giao diện đẹp, nhẹ, rất phổ biến trong cộng đồng self-hosted.
mkdir -p ~/docker/uptime-kuma
cd ~/docker/uptime-kuma
Tạo file docker-compose.yml:
version: "3.8"
services:
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
restart: unless-stopped
volumes:
- kuma_data:/app/data
networks:
- proxy-network
networks:
proxy-network:
external: true
volumes:
kuma_data:
Tương tự WordPress, không expose port, chỉ join proxy-network.
docker compose up -d
Kiểm tra tất cả container đang chạy:
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
NAMES STATUS PORTS
nginx-proxy-manager Up 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:81->81/tcp
wordpress-app Up 80/tcp
wordpress-db Up 3306/tcp
uptime-kuma Up 3001/tcp
Để ý: WordPress và Uptime Kuma có port nhưng không có 0.0.0.0: phía trước, nghĩa là port chỉ mở bên trong Docker network, không expose ra internet. Đúng như mong muốn!
Trỏ domain về VPS
Trước khi cấu hình proxy host trong NPM, bạn cần trỏ domain về IP của VPS.
Với domain thật
Vào phần quản lý DNS của domain (Cloudflare, Route53, hoặc nhà đăng ký domain), tạo A record:
blog.example.com A 103.45.67.89
status.example.com A 103.45.67.89
Nếu dùng Cloudflare, tắt proxy (cloud icon màu cam) trong lúc setup để Let’s Encrypt có thể verify domain. Sau khi SSL hoạt động, bạn có thể bật lại.
Test không có domain? Dùng /etc/hosts
Nếu bạn chưa có domain hoặc chỉ muốn test local, sửa file /etc/hosts trên máy tính của bạn (không phải VPS):
Trên macOS/Linux:
sudo nano /etc/hosts
Trên Windows: mở Notepad as Administrator, mở file C:\Windows\System32\drivers\etc\hosts
Thêm dòng:
103.45.67.89 blog.example.com
103.45.67.89 status.example.com
Thay 103.45.67.89 bằng IP VPS của bạn. Sau đó bạn có thể truy cập blog.example.com từ trình duyệt, trình duyệt sẽ gửi request đến IP VPS thay vì tìm DNS trên internet.
Lưu ý: Với cách này, bạn sẽ không thể cài SSL bằng Let’s Encrypt vì Let’s Encrypt cần verify domain qua internet. Tuy nhiên, bạn vẫn có thể test proxy host mà không cần SSL.
Cấu hình Proxy Host trong NPM

Đây là phần chính, kết nối domain với container thông qua NPM.
Thêm Proxy Host cho WordPress

Trong giao diện NPM (http://your-vps-ip:81), vào Hosts → Proxy Hosts → Add Proxy Host.
Tab Details:
- Domain Names:
blog.example.com - Scheme:
http - Forward Hostname / IP:
wordpress-app(tên container) - Forward Port:
80(port bên trong container WordPress) - Block Common Exploits: ✅ bật
- Websockets Support: không cần cho WordPress
Tại sao dùng container name thay vì IP? Vì NPM và WordPress cùng network proxy-network, Docker DNS tự động resolve wordpress-app thành IP nội bộ của container. Không cần biết IP cụ thể là bao nhiêu.
Tab SSL (nếu có domain thật trỏ về VPS):
- SSL Certificate: chọn
Request a new SSL Certificate - Force SSL: ✅ bật: tự động redirect HTTP → HTTPS
- HTTP/2 Support: ✅ bật
- HSTS Enabled: ✅ bật (tuỳ chọn, bật nếu bạn chắc chắn luôn dùng HTTPS)
- Email Address for Let’s Encrypt: nhập email thật của bạn
- I Agree to the Let’s Encrypt ToS: ✅ đồng ý
Bấm Save. NPM sẽ tự động:
- Tạo cấu hình Nginx cho domain
blog.example.com - Request SSL certificate từ Let’s Encrypt
- Cấu hình auto-renew (tự động gia hạn trước khi hết hạn)
Truy cập https://blog.example.com: bạn sẽ thấy trang cài đặt WordPress. HTTPS, ổ khoá xanh, đầy đủ!

Thêm Proxy Host cho Uptime Kuma
Tương tự, thêm proxy host mới:
Tab Details:
- Domain Names:
status.example.com - Scheme:
http - Forward Hostname / IP:
uptime-kuma - Forward Port:
3001 - Block Common Exploits: ✅
- Websockets Support: ✅ bật: Uptime Kuma dùng WebSocket cho real-time updates
Tab SSL: cấu hình giống WordPress, Request new SSL, Force SSL, HTTP/2.
Save xong, truy cập https://status.example.com: Uptime Kuma hiện ra với HTTPS.
Cách hoạt động đằng sau
Để hiểu rõ hơn, hãy xem flow từ khi người dùng gõ URL đến khi nhận được trang web:
1. Người dùng gõ: https://blog.example.com
2. DNS resolve: blog.example.com → 103.45.67.89 (IP VPS)
3. Trình duyệt kết nối đến 103.45.67.89:443 (HTTPS)
4. NPM nhận request, đọc header "Host: blog.example.com"
5. NPM tìm proxy host match domain → forward đến wordpress-app:80
6. WordPress xử lý request, trả response cho NPM
7. NPM trả response lại cho trình duyệt
SSL Termination
Một khái niệm quan trọng: SSL termination. Khi NPM nhận kết nối HTTPS từ client, nó giải mã SSL tại đây, rồi forward request dưới dạng HTTP thông thường đến container phía sau.
Client ←→ [HTTPS] ←→ NPM ←→ [HTTP] ←→ WordPress container
Điều này có nghĩa:
- Container app không cần cài SSL: NPM lo hết
- Traffic giữa NPM và container là HTTP: nhưng vì cùng Docker network (không đi qua internet), điều này an toàn
- Nếu cần end-to-end encryption, bạn có thể đổi Scheme thành
httpstrong proxy host: nhưng hiếm khi cần thiết
Docker Network – Sợi dây kết nối
Lý do mọi thứ hoạt động là nhờ Docker network. Khi NPM và các app cùng join proxy-network:
- Docker tạo một mạng nội bộ riêng
- Mỗi container có thể gọi nhau bằng container name (Docker DNS tự resolve)
- NPM gọi
wordpress-app:80→ Docker DNS trả về IP nội bộ của container WordPress
Nếu bạn quên join proxy-network, NPM sẽ không thể kết nối đến container, bạn sẽ thấy lỗi 502 Bad Gateway.
Tips & Best Practices
1. Không expose port app ra ngoài
Đây là best practice quan trọng nhất. Khi dùng reverse proxy, chỉ NPM mới expose port 80/443 ra internet. Các app phía sau không cần (và không nên) expose port.
# ❌ Sai — expose port ra ngoài
services:
wordpress:
ports:
- "8080:80" # Ai cũng truy cập được qua :8080
# ✅ Đúng — không expose port
services:
wordpress:
# Không có phần ports:
networks:
- proxy-network # Chỉ truy cập qua NPM
Nếu bạn cần truy cập trực tiếp container để debug, dùng:
# Truy cập container trực tiếp qua Docker network
docker exec -it wordpress-app bash
# Hoặc expose port tạm thời chỉ trên localhost
ports:
- "127.0.0.1:8080:80" # Chỉ truy cập từ VPS, không từ internet
2. Access List cho admin panels
Một số trang (như admin panel của NPM, Portainer, phpMyAdmin) không nên public. NPM có tính năng Access Lists để giới hạn truy cập:
Trong NPM, vào Access Lists → Add Access List:
- Name:
Admin Only - Satisfy Any: chọn tuỳ nhu cầu
- Tab Authorization: thêm username/password
- Tab Access: cho phép IP cụ thể (ví dụ:
allow 1.2.3.4: IP nhà bạn)
Sau đó, khi tạo proxy host cho admin panel, chọn Access List là Admin Only. Ai không có password hoặc không từ IP cho phép sẽ bị chặn.
3. Custom Nginx config
NPM cho phép thêm custom Nginx config cho từng proxy host. Khi tạo/sửa proxy host, vào tab Advanced và thêm config:
# Tăng giới hạn upload file (mặc định Nginx chỉ cho 1MB)
client_max_body_size 100M;
# Custom headers
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cache static files
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
Đặc biệt với WordPress, bạn gần như chắc chắn cần tăng client_max_body_size vì WordPress hay upload media lớn.
4. Wildcard SSL Certificate
Nếu bạn có nhiều subdomain (blog.example.com, status.example.com, api.example.com…), thay vì tạo SSL riêng cho từng cái, dùng wildcard certificate: *.example.com.
Trong NPM, vào SSL Certificates → Add SSL Certificate → Let’s Encrypt:
- Domain Names:
*.example.comvàexample.com - Use a DNS Challenge: ✅ bật: bắt buộc cho wildcard
- DNS Provider: chọn provider (Cloudflare, DigitalOcean, Route53…)
- Credentials File Content: nhập API key/token của DNS provider
Ví dụ với Cloudflare:
dns_cloudflare_api_token = your_cloudflare_api_token_here
Sau khi tạo wildcard cert, bạn có thể chọn cert này khi tạo proxy host thay vì request cert mới mỗi lần.
5. Bảo vệ admin panel NPM
Port 81 (admin panel NPM) mặc định mở cho tất cả. Sau khi setup xong, bạn nên bảo vệ nó:
Cách 1: Chặn port 81 trên firewall, chỉ truy cập qua SSH tunnel:
# Trên VPS — chặn port 81 từ bên ngoài
sudo ufw deny 81
# Trên máy local — tạo SSH tunnel
ssh -L 8181:localhost:81 user@your-vps-ip
# Mở trình duyệt: http://localhost:8181
Cách 2: Tạo proxy host cho NPM admin luôn (ví dụ: npm.example.com), thêm Access List, rồi đóng port 81:
# Sửa docker-compose.yml của NPM, bỏ port 81 ra ngoài
ports:
- "80:80"
- "443:443"
# - "81:81" # Không expose nữa, truy cập qua proxy host
Thêm app mới – Quy trình chuẩn
Sau khi setup NPM xong, mỗi khi deploy app mới, bạn chỉ cần 3 bước:
- Deploy app: compose file với
proxy-network, không expose port - Trỏ DNS: tạo A record cho subdomain mới
- Thêm Proxy Host trong NPM: domain → container name + port → SSL
3 bước, 5 phút. Mỗi app mới đều có domain riêng, HTTPS tự động, không cần sửa config Nginx thủ công.
Troubleshooting thường gặp
502 Bad Gateway
Nguyên nhân phổ biến nhất: NPM không kết nối được đến container app.
- Kiểm tra container app đang chạy:
docker ps - Kiểm tra cùng network:
docker network inspect proxy-network - Kiểm tra forward port đúng (port bên trong container, không phải port expose)
- Kiểm tra container name đúng chính tả
SSL certificate lỗi
- Domain chưa trỏ về IP VPS: kiểm tra bằng
dig blog.example.comhoặcnslookup blog.example.com - Port 80 bị chặn trên firewall: Let’s Encrypt cần port 80 để verify
- Cloudflare proxy đang bật (cloud màu cam): tắt khi request cert
- Đã request quá nhiều cert: Let’s Encrypt có rate limit (50 cert/domain/tuần)
Redirect loop (ERR_TOO_MANY_REDIRECTS)
Thường xảy ra khi dùng Cloudflare proxy + NPM Force SSL. Cloudflare và NPM đều cố redirect HTTP → HTTPS → loop vô hạn.
Giải pháp: trong Cloudflare, đặt SSL mode là Full hoặc Full (Strict), không dùng Flexible.
📚 Serie Docker từ A đến Z
- Bài 1: Docker là gì? Tại sao nên dùng Docker trên VPS
- Bài 2: Cài đặt Docker và Docker Compose trên VPS Ubuntu
- Bài 3: Làm quen với Docker – Các lệnh cơ bản cần biết
- Bài 4: Docker Image & Dockerfile – Tự tạo Image riêng
- Bài 5: Docker Volume & Network – Quản lý dữ liệu và mạng
- Bài 6: Docker Compose là gì? Cài đặt và cú pháp cơ bản
- Bài 7: Deploy WordPress + MySQL + phpMyAdmin bằng Docker Compose
- Bài 8: Deploy LEMP Stack (Nginx + PHP-FPM + MariaDB) bằng Docker Compose
- Bài 9: Biến môi trường & file .env trong Docker Compose
- Bài 10: Reverse Proxy với Nginx Proxy Manager + SSL tự động (đang đọc)
- Bài 11: Deploy ứng dụng Node.js / Python với Docker Compose
- Bài 12: Backup & Restore dữ liệu Docker Volume
- Bài 13: Monitoring Docker với Portainer, Uptime Kuma và cAdvisor
- Bài 14: Docker Logging – Quản lý log hiệu quả
- Bài 15: Bảo mật Docker trên VPS
- Bài 16: CI/CD đơn giản – Auto deploy với Webhook + Docker Compose
- Bài 17: Docker Compose trong thực tế – Tổng hợp project mẫu
Tổng kết
Qua bài này, bạn đã:
- Hiểu reverse proxy là gì và tại sao cần nó khi chạy nhiều app trên 1 VPS
- Deploy Nginx Proxy Manager bằng Docker Compose
- Deploy các app mẫu (WordPress, Uptime Kuma) không expose port, chỉ truy cập qua reverse proxy
- Cấu hình proxy host + SSL tự động từ Let’s Encrypt
- Hiểu cách hoạt động: DNS → NPM → Docker network → Container
- Best practices: không expose port, Access List, custom Nginx config, wildcard SSL
Đến đây, bạn đã có một VPS chạy Docker khá “pro” rồi: build image, compose, volumes, networks, env vars, và giờ là reverse proxy + SSL. Tất cả container đều có domain riêng, HTTPS tự động, sẵn sàng cho production.
Nhưng Docker không chỉ để chạy WordPress hay các tool có sẵn. Trong Bài 11, mình sẽ hướng dẫn bạn deploy ứng dụng Node.js và Python bằng Docker, viết Dockerfile cho app của chính bạn, tối ưu image size, kết hợp với Nginx Proxy Manager để serve app lên production. Hẹn gặp bạn ở bài tiếp theo! 🚀
👈 Bài trước: Biến môi trường & file .env trong Docker Compose
👉 Bài tiếp: Deploy ứng dụng Node.js / Python với Docker Compose
Có thể bạn cần xem thêm
Về tác giả
Thạch Phạm
Đồng sáng lập và Giám đốc điều hành của AZDIGI. Có hơn 15 năm kinh nghiệm trong phổ biến kiến thức liên quan đến WordPress tại thachpham.com, phát triển website và phát triển hệ thống.