Bỏ qua để đến nội dung

Sự cố thường gặp

Triệu chứngNguyên nhân thường gặpCách kiểm tra / xử lý
docker compose up chạy nhầm code cũDùng nhầm docker-compose.yml (dev) thay vì docker-compose.prod.ymlLuôn chỉ định rõ -f docker-compose.prod.yml
Backend crash-loop lúc startSai DATABASE_URL/POSTGRES_PASSWORD, hoặc migration lỗidocker compose -f docker-compose.prod.yml logs backend
Ngay sau deploy/rollback/restore, web trả 502 (Cloudflare) dù backend healthy; log nginx có connect() failed (111: Connection refused) while connecting to upstreamnginx giữ IP của container backend/frontend cũ (chỉ phân giải tên lúc khởi động, không được tạo lại khi chỉ đổi image). Các script từ v1.2.1 đã tự reload nginxdocker compose -f docker-compose.prod.yml exec nginx nginx -s reload (hoặc restart nginx)
Backend crash-loop, log 0041_gold_gem_currencies stopped: unsupported currency rows foundCòn dữ liệu dùng mã tiền tệ khác GOLD/GEM (thiết kế cố ý dừng)Xử lý từng dòng trong danh sách theo §8.5, rồi restart backend
Backend không khởi động, lỗi PUBLIC_ASSET_BASE_URL must be an absolute https:// URL hoặc SERVE_MEDIA_LOCALLY must be falseThiếu biến Phase N trong .envThêm 3 biến ở §3.1
Upload ảnh báo lỗi 500, log Permission denied: '/data/media/...'Volume ảnh tạo trước khi image có chown, đang thuộc rootLệnh chown ở §8.4 bước 2
Icon trong game không hiện, curl /media/... trả 404Nginx chưa có location /media/ (deploy thiếu nginx/ mới) hoặc chưa mount volume ảnhĐối chiếu nginx/nginx.conf.template và docker-compose.prod.yml, docker compose ... restart nginx
/guide/ trả 404 hoặc có shell nhưng thiếu nội dungGói deploy thiếu guide-site/, build chưa được copy hoặc thư mục mount saiKiểm tra /opt/web_admin/guide-site/index.html, volume ./guide-site:/usr/share/nginx/guide:ro, rồi đóng gói/copy lại và restart nginx
/guide/ chuyển về /login liên tục dù vừa đăng nhậpCookie access_token không được gửi tới /guide/ (path/domain/Secure) hoặc phiên đã hết hạnDùng HTTPS cùng host Portal, kiểm tra cookie có Path=/, đăng nhập lại; sau login mở lại /guide/ vì next chưa tự tiếp tục
Sản phẩm có trong Shop nhưng không hiện trong cửa hàng của gameSản phẩm đang để “Không bán” (Phase R), vật phẩm chưa có icon (cửa hàng tự ẩn), sản phẩm chưa published, hoặc là sản phẩm tiền thật khi flag iap tắtPortal → Shop (bật bán, thêm icon, publish) / Feature flags
Game nhận 422 khi kết thúc màn (/runs/{id}/finish)App dùng SDK cũ hơn v0.3.0, không gửi result.duration_msNâng SDK lên v0.3.0 (§13)
/sync trả 409 server_authoritative_modeGame đã chuyển chế độ server nhưng app còn gửi số dư kiểu cũBình thường với app cũ — gate cập nhật sẽ chặn; app mới không gọi /sync số dư
Mua tiền thật trả 403 iap_disabledFlag iap của game đang tắt§8.5 “Bật IAP”
Mua tiền thật trả 409 account_mismatchToken mua thuộc tài khoản người chơi khácBình thường (chống dùng lại token); app phải mua bằng đúng player_uid
rollback_to_version.sh từ chối, báo migrationImage cũ không có migration DB đang ở; qua Phase O thì 0043–0045 không lùi được, qua Phase Q/R thì 0051/0052 từ chối downgrade§7 “Migration không lùi được”: restore backup trước deploy
Backup báo không đủ dung lượngĐĩa chứa /opt/backups còn ít hơn max(2 × bản gần nhất, 1 GiB)Dọn hoặc tăng đĩa; ./scripts/backup_database.sh --dry-run để xem các bản sẽ bị dọn
Backup/restore báo backup lock timeoutMột backup hoặc restore khác đang giữ /opt/backups/.lock quá 30 phútChờ job kia xong (ps aux | grep -E "backup|restore"), rồi chạy lại
restore.sh báo Required backend image ... is not loaded (hoặc frontend)Image ghi trong manifest không còn trên máyload_images.sh đúng version đó, hoặc truyền --backend-image/--frontend-image
restore.sh báo FAILED khi kiểm SHA256, hoặc archive structure validation failedFile backup đã chọn bị hỏng/bị sửa, hoặc sai khóa ageChưa có gì thay đổi; chọn bản khác (--db-file hoặc thư mục ngày khác), kiểm lại BACKUP_AGE_IDENTITY_FILE
restore.sh báo Row-count differences hoặc Alembic revision mismatchDump restore ra không khớp manifestApp vẫn tắt, DB đang dở dang; restore bản khác
Nginx không lên được, báo lỗi thiếu certChưa chạy init_letsencrypt.sh, hoặc chạy khi DNS chưa trỏ đúngKiểm tra dig portal.tinysoft.io.vn trỏ đúng IP VPS trước khi chạy lại
curl từ máy ngoài báo Connection refused ở port 80/443 dù container đang chạy và ss -tlnp trên VPS thấy có LISTENFirewall tầng cloud (Security Group/NSG/Firewall rules) chưa mở port 80/443 — mặc định nhiều provider chỉ mở sẵn port 22Vào console nhà cung cấp cloud, kiểm tra inbound rules; xem §1
Certbot báo too many failed authorizations (5) for "<domain>"Đã thử xin cert nhiều lần thất bại trong 1 giờ cho cùng domain (thường do thử lại khi port 80 chưa mở) — giới hạn tính theo domain, đổi email không giúp gìĐợi đúng thời điểm ghi trong thông báo lỗi (retry after ...) rồi thử lại
Certbot báo live directory exists for <domain> khi chạy lạiThư mục /etc/letsencrypt/live/<domain> từ lần chạy trước (dummy cert hoặc lần fail trước) chưa được dọn sạchXóa live/, archive/, renewal/<domain>.conf trước khi chạy lại certonly — xem cuối §4
Trình duyệt báo cảnh báo chứng chỉDomain trong .env (DOMAIN) không khớp domain thật đang truy cậpĐối chiếu lại .env và DNS
Cookie không được set khi đăng nhậpCOOKIE_SECURE=true nhưng đang truy cập qua http:// thay vì https://Luôn test qua domain HTTPS thật, không test qua IP/http
docker compose ... down -vKhông bao giờ chạy lệnh này trên production — xóa volume certbot_certs (gây rate-limit Let’s Encrypt khi xin lại), admin_portal_pgdata_prod (mất toàn bộ dữ liệu) và admin_portal_media_prod (mất toàn bộ ảnh)—
export_images.sh/deploy_local.sh báo “Image … not found”Chưa build image đúng tag đã khai trong docker-compose.prod.yml (máy dev), hoặc chưa load_images.sh (VPS)docker images | grep admin_portal, đối chiếu tag với docker-compose.prod.yml
App game nhận 401 khi link, log backend identity verification failedGame chưa cấu hình OAuth web client Play Games trên Portal (§8.1 bước 4), hoặc app build thiếu PLAY_GAMES_WEB_CLIENT_IDGame Registry → biểu tượng khiên phải ở trạng thái “Đã cấu hình”; kiểm tra env/prod.json của app
App game nhận 404 ở mọi request /api/v2/...Portal trên VPS còn là bản trước Phase KKiểm tra version ở §5; deploy bản mới trước khi phát hành app
/sync trả 422 currency_not_syncableTiền app gửi lên không bật “Đồng bộ từ app” trên PortalPortal → Tiền tệ của game đó
Đổi remote config / bảo trì / Catalog nhưng app chưa thấybootstrap và cửa hàng cache 30 giây trong mỗi workerChờ 30 giây rồi mở lại app
Chạy ./scripts/create_super_admin.py báo Permission denied, chmod +x báo Operation not permittedScript được COPY vào image trước dòng USER appuser trong Dockerfile nên thuộc sở hữu user build (root); container production không có sudo, appuser không đủ quyền tự cấp bit thực thiKhông chạy trực tiếp bằng ./; luôn gọi qua python scripts/create_super_admin.py ... như §6

Áp dụng cho Portal v1.2.2