[{"data":1,"prerenderedAt":1034},["ShallowReactive",2],{"search-posts-dataset":3,"post-detail-/posts/git-deploy-key":159,"all-published-articles-list":973,"series-posts-/posts/git-deploy-key":1033},[4,20,35,48,62,75,87,99,111,122,135,149],{"path":5,"title":6,"description":7,"categories":8,"tags":11,"date":16,"image":17},"/posts/incident-checklist","Checklist xử lí sự cố máy chủ Linux: Phục hồi sau thảm họa","Qui trình phản ứng và xử lí sự cố máy chủ Linux khi hệ thống bị sập, tràn RAM/HDD hoặc nghi ngờ bị xâm nhập: Các bước chuẩn đoán, cô lập, phân tích log và khôi phục.",[9,10],"linux","devops",[12,13,14,15],"incident","troubleshooting","security","sysadmin","2026-08-15T00:00:00.000Z",{"src":18,"alt":19},"/img/incident-response.webp","Xử lí sự cố máy chủ Linux",{"path":21,"title":22,"description":23,"categories":24,"tags":27,"date":31,"image":32},"/posts/backup-postgres-docker","Sao lưu tự động PostgreSQL trong Docker với cron job và gzip","Hướng dẫn xây dựng script tự động backup database PostgreSQL chạy trong Docker container: gzip, cron hàng ngày, tự động xóa bản sao lưu cũ và kiểm thử phục hồi.",[25,26],"docker","database",[28,29,30,10],"postgresql","backup","automation","2025-10-20T00:00:00.000Z",{"src":33,"alt":34},"/img/postgres-backup.webp","Sao lưu tự động PostgreSQL Docker",{"path":36,"title":37,"description":38,"categories":39,"tags":40,"date":44,"image":45},"/posts/docker-compose-production","Thiết kế Docker compose chuẩn Production","Hướng dẫn thực chiến xây dựng docker-compose.yml hoàn chỉnh cho Production: healthchecks, restart policies, resource limits, quản lí .env và Persistent Volumes",[25,10],[41,42,43],"production","compose","backend","2025-10-15T00:00:00.000Z",{"src":46,"alt":47},"/img/docker-compose.webp","Docker Compose Production Best Practices",{"path":49,"title":50,"description":51,"categories":52,"tags":53,"date":58,"image":59},"/posts/monitoring-server-basics","Giám sát server Linux từ cơ bản đến nâng cao: htop, ncdu, prometheus và Uptime Kuma","Cẩm nang toàn diện về giám sát hiệu năng máy chủ Linux: Khai thác công cụ CLI thời gian thực (Htop, Btop, Ncdu), thiết lập hệ thống cảnh báo sự cố Uptime Kuma qua Telegram và thu thập chỉ số với Prometheus & Grafana.",[9,10],[54,55,56,57],"monitoring","grafana","prometheus","uptime","2024-10-18T00:00:00.000Z",{"src":60,"alt":61},"/img/monitoring.webp","Giám sát máy chủ Linux",{"path":63,"title":64,"description":65,"categories":66,"tags":68,"date":71,"image":72},"/posts/nginx-reverse-proxy","Hướng dẫn cấu hình Nginx Reverse Proxy với SSL Certbot và Docker chuẩn Production","Cẩm nang toàn diện cấu hình Nginx Reverse Proxy trên Ubuntu: Tích hợp chứng chỉ SSL Let's Encrypt miễn phí qua Certbot, hỗ trợ WebSockets, HTTP/2, nén Brotli/Gzip và Rate Limiting chống DDoS.",[9,67],"nginx",[10,69,70],"ssl","webserver","2024-10-10T00:00:00.000Z",{"src":73,"alt":74},"/img/nginx.webp","Nginx Reverse Proxy với SSL",{"path":76,"title":77,"description":78,"categories":79,"tags":80,"date":83,"image":84},"/posts/how-to-secure-a-vps","Bảo mật máy chủ Linux VPS: Cẩm nang toàn diện 8 bước chống tấn công","Hướng dẫn thực chiến từng bước thiết lập bảo mật máy chủ Linux VPS mới: Vô hiệu hóa mật khẩu SSH, thiết lập SSH Key Ed25519, cấu hình Fail2ban, tường lửa UFW và cập nhật tự động Unattended-Upgrades.",[9,14],[81,82,10],"vps","hardening","2024-10-05T00:00:00.000Z",{"src":85,"alt":86},"/img/linux-security.webp","Bảo mật máy chủ Linux VPS",{"path":88,"title":89,"description":90,"categories":91,"tags":92,"date":95,"image":96},"/posts/systemd-node-service","Quản lí ứng dụng Node.js trong Production với Systemd Service và Journalctl","Hướng dẫn triển khai ứng dụng Node.js, Go hoặc Python dưới dạng Systemd Service trên Linux: Tự động khởi động lại khi crash, quản lý biến môi trường, giới hạn bộ nhớ RAM và theo dõi log thời gian thực với Journalctl.",[9,10],[93,94,43,41],"systemd","nodejs","2024-10-01T00:00:00.000Z",{"src":97,"alt":98},"/img/systemd.webp","Quản lý ứng dụng với Systemd Service",{"path":100,"title":101,"description":102,"categories":103,"tags":104,"date":107,"image":108},"/posts/how-to-install-docker-on-ubuntu-server","Hướng dẫn cài đặt Docker & Docker compose trên Ubuntu server","Hướng dẫn toàn diện cách cài đặt Docker Engine và Docker Compose V2 trên Ubuntu Server, cấu hình bảo mật non-root user, tối ưu daemon và xử lí xung đột tường lửa UFW",[9,25],[105,10,106],"beginner","ubuntu","2024-09-30T00:00:00.000Z",{"src":109,"alt":110},"/img/docker.webp","Cài đặt Docker trên Ubuntu Server",{"path":112,"title":113,"description":114,"categories":115,"tags":116,"date":118,"image":119},"/posts/ssh-key-authentication","Xác thực SSH Key từ cơ bản đến nâng cao: Ed25519, SSH Config và Bảo mật đa tầng","Cẩm nang toàn diện về xác thực SSH Key trên máy chủ Linux: So sánh Ed25519 vs RSA, cấu hình SSH Config quản lí hàng chục VPS, chuyển tiếp Agent Forwarding, và các qui tắc bảo mật chống lộ khóa.",[9,14],[117,10,15],"ssh","2024-09-25T00:00:00.000Z",{"src":120,"alt":121},"/img/ssh-keys.webp","Xác thực SSH Key Linux",{"path":123,"title":124,"description":125,"categories":126,"tags":127,"date":131,"image":132},"/posts/ufw-firewall-basics","Làm chủ tường lửa UFW trên Linux: Qui tắc, giới hạn kết nối và xử lí xung đột Docker","Hướng dẫn toàn diện làm chủ tường lửa UFW (Uncomplicated Firewall) trên Ubuntu: Thiết lập chính sách mặc định, mở cổng theo IP, giới hạn brute-force (Rate Limiting) và khắc phục lỗi Docker bypass tường lửa.",[9,14],[128,129,130,15],"ufw","firewall","networking","2024-09-20T00:00:00.000Z",{"src":133,"alt":134},"/img/ufw-firewall.webp","Cấu hình Tường lửa UFW Linux",{"path":136,"title":137,"description":138,"categories":139,"tags":141,"date":145,"image":146},"/posts/git-deploy-key","Tự động hóa triển khai với Git deploy keys: Thiết lập an toàn cho GitHub và GitLab","Hướng dẫn thiết lập Git Deploy Key chuẩn bảo mật để kéo mã nguồn tự động từ GitHub hoặc GitLab về máy chủ Production: Phân quyền Read-Only, cấu hình SSH Config và tích hợp Webhook tự động cập nhật.",[140,10],"git",[142,143,144,30],"github","gitlab","cicd","2024-09-18T00:00:00.000Z",{"src":147,"alt":148},"/img/git-deploy.webp","Git Deploy Keys cho máy chủ",{"path":150,"title":151,"description":152,"categories":153,"tags":154,"date":155,"image":156},"/posts/ubuntu-server-initial-setup","Qui trình thiết lập ban đầu cho Ubuntu Server: Swap, Timezone, User và Firewall","Hướng dẫn các bước thiết lập chuẩn mực ban đầu cho máy chủ Ubuntu Server mới: Cấu hình múi giờ Việt Nam (Asia/Ho_Chi_Minh), tạo phân vùng RAM ảo (Swap File), phân quyền Sudoer và kích hoạt tường lửa UFW.",[9],[106,105,15],"2024-09-15T00:00:00.000Z",{"src":157,"alt":158},"/img/ubuntu.webp","Thiết lập ban đầu Ubuntu Server",{"id":160,"title":137,"author":161,"body":162,"categories":961,"date":145,"description":138,"draft":962,"extension":963,"image":964,"meta":965,"navigation":677,"path":136,"seo":966,"series":967,"series_order":967,"slug":968,"stem":969,"tags":970,"updated":971,"__hash__":972},"post/posts/git-deploy-key.md","Duong Thu",{"type":163,"value":164,"toc":946},"minimal",[165,170,183,186,202,209,243,246,250,260,292,295,324,337,340,376,379,391,398,400,404,409,459,463,477,479,487,494,499,512,515,555,558,571,573,577,580,595,601,611,639,641,649,655,816,819,834,836,840,927,929,933,942],[166,167,169],"h2",{"id":168},"giới-thiệu-vấn-đề-bảo-mật-khi-tải-mã-nguồn-trên-máy-chủ-production","Giới thiệu: Vấn đề bảo mật khi tải mã nguồn trên máy chủ Production",[171,172,173,174,178,179,182],"p",{},"Khi triển khai ứng dụng lên máy chủ Linux, bạn cần kéo mã nguồn từ kho Git riêng (Private Repository) trên ",[175,176,177],"strong",{},"GitHub"," hoặc ",[175,180,181],{},"GitLab","...",[171,184,185],{},"Nhiều lập trình viên thường mắc phải một trong hai lỗi bảo mật nghiêm trọng sau:",[187,188,189,196],"ol",{},[190,191,192,195],"li",{},[175,193,194],{},"Sử dụng Personal Access Token (PAT) hoặc Mật khẩu cá nhân",": Nếu máy chủ bị xâm nhập, kẻ tấn công có thể dùng Token đó để truy cập vào TẤT CẢ các dự án khác thuộc tài khoản của bạn.",[190,197,198,201],{},[175,199,200],{},"Sao chép SSH Key cá nhân của bạn lên máy chủ",": Khóa cá nhân này có quyền Read & Write trên toàn bộ tổ chức hoặc tài khoản của bạn.",[171,203,204,205,208],{},"Giải pháp chuẩn mực quốc tế là sử dụng ",[175,206,207],{},"Git Deploy Key",":",[210,211,212,218,237],"ul",{},[190,213,214,217],{},[175,215,216],{},"Quyền hạn tối thiểu (Principle of Least Privilege)",": Deploy Key chỉ có quyền truy cập vào ĐÚNG DUY NHẤT một repository cụ thể.",[190,219,220,223,224,228,229,232,233,236],{},[175,221,222],{},"Chỉ đọc (Read-Only)",": Mặc định Deploy Key chỉ có quyền kéo code (",[225,226,227],"code",{},"git pull",", ",[225,230,231],{},"git clone","), không thể đẩy (",[225,234,235],{},"push",") hay can thiệp vào các nhánh mã nguồn.",[190,238,239,242],{},[175,240,241],{},"Độc lập hoàn toàn",": Nếu máy chủ bị tấn công, bạn chỉ cần xóa bỏ Deploy Key của repository đó mà không ảnh hưởng đến bất kỳ tài khoản hay dự án nào khác.",[244,245],"hr",{},[166,247,249],{"id":248},"_1-tạo-cặp-khóa-ssh-riêng-biệt-cho-deploy-key","1. Tạo cặp khóa SSH riêng biệt cho Deploy Key",[171,251,252,253,178,256,259],{},"Đăng nhập vào máy chủ VPS của bạn với tài khoản chạy ứng dụng (ví dụ: ",[225,254,255],{},"devadmin",[225,257,258],{},"nodeapp","):",[261,262,267],"pre",{"className":263,"code":264,"language":265,"meta":266,"style":266},"language-bash shiki shiki-themes github-dark github-dark github-dark","# Đăng nhập bằng user quản trị\nsu - devadmin\n","bash","",[225,268,269,278],{"__ignoreMap":266},[270,271,274],"span",{"class":272,"line":273},"line",1,[270,275,277],{"class":276},"sGGCZ","# Đăng nhập bằng user quản trị\n",[270,279,281,285,289],{"class":272,"line":280},2,[270,282,284],{"class":283},"sb7EE","su",[270,286,288],{"class":287},"skqr8"," -",[270,290,291],{"class":287}," devadmin\n",[171,293,294],{},"Tạo một cặp khóa SSH mới dành riêng cho dự án này:",[261,296,298],{"className":263,"code":297,"language":265,"meta":266,"style":266},"ssh-keygen -t ed25519 -C \"deploy-key-myapp-prod\" -f ~/.ssh/id_ed25519_myapp\n",[225,299,300],{"__ignoreMap":266},[270,301,302,305,309,312,315,318,321],{"class":272,"line":273},[270,303,304],{"class":283},"ssh-keygen",[270,306,308],{"class":307},"sKJT9"," -t",[270,310,311],{"class":287}," ed25519",[270,313,314],{"class":307}," -C",[270,316,317],{"class":287}," \"deploy-key-myapp-prod\"",[270,319,320],{"class":307}," -f",[270,322,323],{"class":287}," ~/.ssh/id_ed25519_myapp\n",[210,325,326],{},[190,327,328,329,332,333,336],{},"Nhấn ",[225,330,331],{},"Enter"," hai lần để ",[175,334,335],{},"không đặt Passphrase"," (vì tiến trình CI/CD và tự động hóa cần đọc khóa mà không bị dừng lại yêu cầu nhập mật khẩu).",[171,338,339],{},"Phân quyền bảo mật nghiêm ngặt cho file khóa:",[261,341,343],{"className":263,"code":342,"language":265,"meta":266,"style":266},"chmod 700 ~/.ssh\nchmod 600 ~/.ssh/id_ed25519_myapp\nchmod 644 ~/.ssh/id_ed25519_myapp.pub\n",[225,344,345,356,365],{"__ignoreMap":266},[270,346,347,350,353],{"class":272,"line":273},[270,348,349],{"class":283},"chmod",[270,351,352],{"class":307}," 700",[270,354,355],{"class":287}," ~/.ssh\n",[270,357,358,360,363],{"class":272,"line":280},[270,359,349],{"class":283},[270,361,362],{"class":307}," 600",[270,364,323],{"class":287},[270,366,368,370,373],{"class":272,"line":367},3,[270,369,349],{"class":283},[270,371,372],{"class":307}," 644",[270,374,375],{"class":287}," ~/.ssh/id_ed25519_myapp.pub\n",[171,377,378],{},"In nội dung khóa công khai ra màn hình để chuẩn bị thêm vào GitHub / GitLab:",[261,380,382],{"className":263,"code":381,"language":265,"meta":266,"style":266},"cat ~/.ssh/id_ed25519_myapp.pub\n",[225,383,384],{"__ignoreMap":266},[270,385,386,389],{"class":272,"line":273},[270,387,388],{"class":283},"cat",[270,390,375],{"class":287},[171,392,393,394,397],{},"Sao chép toàn bộ chuỗi ký tự hiển thị (dạng ",[225,395,396],{},"ssh-ed25519 AAAA... deploy-key-myapp-prod",").",[244,399],{},[166,401,403],{"id":402},"_2-thêm-deploy-key-vào-github-hoặc-gitlab","2. Thêm Deploy Key vào GitHub hoặc GitLab",[405,406,408],"h3",{"id":407},"thao-tác-trên-github","Thao tác trên GitHub:",[187,410,411,414,421,428,437,443,453],{},[190,412,413],{},"Truy cập vào Repository của bạn trên GitHub.",[190,415,416,417,420],{},"Vào ",[175,418,419],{},"Settings > Deploy Keys"," (ở thanh menu bên trái).",[190,422,423,424,427],{},"Nhấp nút ",[175,425,426],{},"Add deploy key",".",[190,429,430,433,434,397],{},[175,431,432],{},"Title",": Đặt tên gợi nhớ (ví dụ: ",[225,435,436],{},"Production Server - Singapore VPS",[190,438,439,442],{},[175,440,441],{},"Key",": Dán chuỗi Public Key vừa copy ở bước 1.",[190,444,445,448,449,452],{},[175,446,447],{},"Allow write access",": ",[175,450,451],{},"KHÔNG ĐƯỢC TÍCH CHỌN"," (giữ nguyên chế độ Read-Only an toàn).",[190,454,455,456,427],{},"Bấm ",[175,457,458],{},"Add key",[405,460,462],{"id":461},"thao-tác-trên-gitlab","Thao tác trên GitLab:",[187,464,465,470],{},[190,466,416,467,427],{},[175,468,469],{},"Settings > Repository > Deploy keys",[190,471,472,473,427],{},"Nhập tiêu đề và dán Public Key, đảm bảo tắt tùy chọn ",[474,475,476],"em",{},"Write access allowed",[244,478],{},[166,480,482,483,486],{"id":481},"_3-cấu-hình-file-sshconfig-trên-máy-chủ","3. Cấu hình file ",[225,484,485],{},"~/.ssh/config"," trên máy chủ",[171,488,489,490,493],{},"Để Git tự động nhận diện đúng file khóa ",[225,491,492],{},"id_ed25519_myapp"," mỗi khi thao tác với repository của dự án:",[171,495,496,497,208],{},"Mở file ",[225,498,485],{},[261,500,502],{"className":263,"code":501,"language":265,"meta":266,"style":266},"nano ~/.ssh/config\n",[225,503,504],{"__ignoreMap":266},[270,505,506,509],{"class":272,"line":273},[270,507,508],{"class":283},"nano",[270,510,511],{"class":287}," ~/.ssh/config\n",[171,513,514],{},"Thêm khối cấu hình bí danh (Host Alias):",[261,516,520],{"className":517,"code":518,"language":519,"meta":266,"style":266},"language-ini shiki shiki-themes github-dark github-dark github-dark","Host github-myapp\n    HostName github.com\n    User git\n    IdentityFile ~/.ssh/id_ed25519_myapp\n    IdentitiesOnly yes\n    StrictHostKeyChecking accept-new\n","ini",[225,521,522,527,532,537,543,549],{"__ignoreMap":266},[270,523,524],{"class":272,"line":273},[270,525,526],{},"Host github-myapp\n",[270,528,529],{"class":272,"line":280},[270,530,531],{},"    HostName github.com\n",[270,533,534],{"class":272,"line":367},[270,535,536],{},"    User git\n",[270,538,540],{"class":272,"line":539},4,[270,541,542],{},"    IdentityFile ~/.ssh/id_ed25519_myapp\n",[270,544,546],{"class":272,"line":545},5,[270,547,548],{},"    IdentitiesOnly yes\n",[270,550,552],{"class":272,"line":551},6,[270,553,554],{},"    StrictHostKeyChecking accept-new\n",[171,556,557],{},"Phân quyền cho file config:",[261,559,561],{"className":263,"code":560,"language":265,"meta":266,"style":266},"chmod 600 ~/.ssh/config\n",[225,562,563],{"__ignoreMap":266},[270,564,565,567,569],{"class":272,"line":273},[270,566,349],{"class":283},[270,568,362],{"class":307},[270,570,511],{"class":287},[244,572],{},[166,574,576],{"id":575},"_4-kiểm-tra-kết-nối-và-clone-mã-nguồn","4. Kiểm tra kết nối và Clone mã nguồn",[171,578,579],{},"Kiểm tra kết nối đến GitHub thông qua Host Alias:",[261,581,583],{"className":263,"code":582,"language":265,"meta":266,"style":266},"ssh -T git@github-myapp\n",[225,584,585],{"__ignoreMap":266},[270,586,587,589,592],{"class":272,"line":273},[270,588,117],{"class":283},[270,590,591],{"class":307}," -T",[270,593,594],{"class":287}," git@github-myapp\n",[171,596,597,598],{},"Nếu thành công, GitHub sẽ phản hồi thông điệp:\n",[225,599,600],{},"Hi username/repository! You've successfully authenticated, but GitHub does not provide shell access.",[171,602,603,604,607,608,259],{},"Bây giờ bạn có thể clone mã nguồn về thư mục đích (Lưu ý: Thay thế phần domain ",[225,605,606],{},"github.com"," bằng ",[225,609,610],{},"github-myapp",[261,612,614],{"className":263,"code":613,"language":265,"meta":266,"style":266},"# Thay vì: git clone git@github.com:mycompany/my-app.git\n# Hãy dùng:\ngit clone git@github-myapp:mycompany/my-app.git /var/www/my-app\n",[225,615,616,621,626],{"__ignoreMap":266},[270,617,618],{"class":272,"line":273},[270,619,620],{"class":276},"# Thay vì: git clone git@github.com:mycompany/my-app.git\n",[270,622,623],{"class":272,"line":280},[270,624,625],{"class":276},"# Hãy dùng:\n",[270,627,628,630,633,636],{"class":272,"line":367},[270,629,140],{"class":283},[270,631,632],{"class":287}," clone",[270,634,635],{"class":287}," git@github-myapp:mycompany/my-app.git",[270,637,638],{"class":287}," /var/www/my-app\n",[244,640],{},[166,642,644,645,648],{"id":643},"_5-viết-script-tự-động-cập-nhật-code-deploysh","5. Viết Script tự động cập nhật code (",[225,646,647],{},"deploy.sh",")",[171,650,651,652,208],{},"Tạo file script ",[225,653,654],{},"/var/www/my-app/deploy.sh",[261,656,658],{"className":263,"code":657,"language":265,"meta":266,"style":266},"#!/bin/bash\nset -e\n\necho \"=== BẮT ĐẦU CẬP NHẬT ỨNG DỤNG ===\"\ncd /var/www/my-app\n\n# Kéo mã nguồn mới nhất từ nhánh main\ngit fetch origin main\ngit reset --hard origin/main\n\n# Cài đặt thư viện phụ thuộc\nnpm ci --production\n\n# Build ứng dụng\nnpm run build\n\n# Khởi động lại dịch vụ qua Systemd hoặc Docker\nsudo systemctl restart my-app\n\necho \"=== CẬP NHẬT HOÀN TẤT THÀNH CÔNG ===\"\n",[225,659,660,665,673,679,687,694,698,704,718,732,737,743,755,760,766,777,782,788,803,808],{"__ignoreMap":266},[270,661,662],{"class":272,"line":273},[270,663,664],{"class":276},"#!/bin/bash\n",[270,666,667,670],{"class":272,"line":280},[270,668,669],{"class":307},"set",[270,671,672],{"class":307}," -e\n",[270,674,675],{"class":272,"line":367},[270,676,678],{"emptyLinePlaceholder":677},true,"\n",[270,680,681,684],{"class":272,"line":539},[270,682,683],{"class":307},"echo",[270,685,686],{"class":287}," \"=== BẮT ĐẦU CẬP NHẬT ỨNG DỤNG ===\"\n",[270,688,689,692],{"class":272,"line":545},[270,690,691],{"class":307},"cd",[270,693,638],{"class":287},[270,695,696],{"class":272,"line":551},[270,697,678],{"emptyLinePlaceholder":677},[270,699,701],{"class":272,"line":700},7,[270,702,703],{"class":276},"# Kéo mã nguồn mới nhất từ nhánh main\n",[270,705,707,709,712,715],{"class":272,"line":706},8,[270,708,140],{"class":283},[270,710,711],{"class":287}," fetch",[270,713,714],{"class":287}," origin",[270,716,717],{"class":287}," main\n",[270,719,721,723,726,729],{"class":272,"line":720},9,[270,722,140],{"class":283},[270,724,725],{"class":287}," reset",[270,727,728],{"class":307}," --hard",[270,730,731],{"class":287}," origin/main\n",[270,733,735],{"class":272,"line":734},10,[270,736,678],{"emptyLinePlaceholder":677},[270,738,740],{"class":272,"line":739},11,[270,741,742],{"class":276},"# Cài đặt thư viện phụ thuộc\n",[270,744,746,749,752],{"class":272,"line":745},12,[270,747,748],{"class":283},"npm",[270,750,751],{"class":287}," ci",[270,753,754],{"class":307}," --production\n",[270,756,758],{"class":272,"line":757},13,[270,759,678],{"emptyLinePlaceholder":677},[270,761,763],{"class":272,"line":762},14,[270,764,765],{"class":276},"# Build ứng dụng\n",[270,767,769,771,774],{"class":272,"line":768},15,[270,770,748],{"class":283},[270,772,773],{"class":287}," run",[270,775,776],{"class":287}," build\n",[270,778,780],{"class":272,"line":779},16,[270,781,678],{"emptyLinePlaceholder":677},[270,783,785],{"class":272,"line":784},17,[270,786,787],{"class":276},"# Khởi động lại dịch vụ qua Systemd hoặc Docker\n",[270,789,791,794,797,800],{"class":272,"line":790},18,[270,792,793],{"class":283},"sudo",[270,795,796],{"class":287}," systemctl",[270,798,799],{"class":287}," restart",[270,801,802],{"class":287}," my-app\n",[270,804,806],{"class":272,"line":805},19,[270,807,678],{"emptyLinePlaceholder":677},[270,809,811,813],{"class":272,"line":810},20,[270,812,683],{"class":307},[270,814,815],{"class":287}," \"=== CẬP NHẬT HOÀN TẤT THÀNH CÔNG ===\"\n",[171,817,818],{},"Cấp quyền thực thi cho script:",[261,820,822],{"className":263,"code":821,"language":265,"meta":266,"style":266},"chmod +x /var/www/my-app/deploy.sh\n",[225,823,824],{"__ignoreMap":266},[270,825,826,828,831],{"class":272,"line":273},[270,827,349],{"class":283},[270,829,830],{"class":287}," +x",[270,832,833],{"class":287}," /var/www/my-app/deploy.sh\n",[244,835],{},[166,837,839],{"id":838},"bảng-so-sánh-các-phương-thức-xác-thực-git-trên-máy-chủ","Bảng so sánh các phương thức xác thực Git trên máy chủ",[841,842,843,863],"table",{},[844,845,846],"thead",{},[847,848,849,854,857,860],"tr",{},[850,851,853],"th",{"align":852},"left","Phương thức",[850,855,856],{"align":852},"Mức độ bảo mật",[850,858,859],{"align":852},"Rủi ro rò rỉ",[850,861,862],{"align":852},"Đề xuất sử dụng",[864,865,866,883,897,912],"tbody",{},[847,867,868,874,877,880],{},[869,870,871],"td",{"align":852},[175,872,873],{},"Personal Access Token (PAT)",[869,875,876],{"align":852},"Kém",[869,878,879],{"align":852},"Lộ toàn bộ tài khoản cá nhân và các repo khác",[869,881,882],{"align":852},"❌ Không khuyến nghị",[847,884,885,890,892,895],{},[869,886,887],{"align":852},[175,888,889],{},"User SSH Key cá nhân",[869,891,876],{"align":852},[869,893,894],{"align":852},"Có quyền Write trên toàn bộ kho dự án",[869,896,882],{"align":852},[847,898,899,903,906,909],{},[869,900,901],{"align":852},[175,902,207],{},[869,904,905],{"align":852},"Rất cao",[869,907,908],{"align":852},"Chỉ ảnh hưởng 1 repo duy nhất, chỉ có quyền Read",[869,910,911],{"align":852},"✅ Khuyến nghị hàng đầu",[847,913,914,919,921,924],{},[869,915,916],{"align":852},[175,917,918],{},"GitHub App / CI Runner",[869,920,905],{"align":852},[869,922,923],{"align":852},"Token tạm thời tự hết hạn trong phiên chạy",[869,925,926],{"align":852},"✅ Phù hợp cho hạ tầng Enterprise lớn",[244,928],{},[166,930,932],{"id":931},"tổng-kết","Tổng kết",[171,934,935,936,938,939,941],{},"Bằng cách sử dụng ",[175,937,207],{}," kết hợp với cấu hình ",[225,940,485],{},", bạn đã thiết lập một luồng phân phối mã nguồn an toàn, tự động hóa cao và tuân thủ chặt chẽ các tiêu chuẩn an toàn thông tin doanh nghiệp.",[943,944,945],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sGGCZ, html code.shiki .sGGCZ{--shiki-default:#6A737D;--shiki-dark:#6A737D;--shiki-light:#6A737D}html pre.shiki code .sb7EE, html code.shiki .sb7EE{--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-light:#B392F0}html pre.shiki code .skqr8, html code.shiki .skqr8{--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-light:#9ECBFF}html pre.shiki code .sKJT9, html code.shiki .sKJT9{--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-light:#79B8FF}",{"title":266,"searchDepth":280,"depth":280,"links":947},[948,949,950,954,956,957,959,960],{"id":168,"depth":280,"text":169},{"id":248,"depth":280,"text":249},{"id":402,"depth":280,"text":403,"children":951},[952,953],{"id":407,"depth":367,"text":408},{"id":461,"depth":367,"text":462},{"id":481,"depth":280,"text":955},"3. Cấu hình file ~/.ssh/config trên máy chủ",{"id":575,"depth":280,"text":576},{"id":643,"depth":280,"text":958},"5. Viết Script tự động cập nhật code (deploy.sh)",{"id":838,"depth":280,"text":839},{"id":931,"depth":280,"text":932},[140,10],false,"md",{"src":147,"alt":148},{},{"title":137,"description":138},null,"git-deploy-key","posts/git-deploy-key",[142,143,144,30],"2026-08-26","fhW7TUihlH",[974,979,984,989,994,999,1004,1009,1014,1019,1024,1028],{"path":5,"title":6,"categories":975,"tags":976,"date":16,"draft":962,"slug":977,"description":7,"image":978},[9,10],[12,13,14,15],"incident-checklist",{"src":18,"alt":19},{"path":21,"title":22,"categories":980,"tags":981,"date":31,"draft":962,"slug":982,"description":23,"image":983},[25,26],[28,29,30,10],"backup-postgres-docker",{"src":33,"alt":34},{"path":36,"title":37,"categories":985,"tags":986,"date":44,"draft":962,"slug":987,"description":38,"image":988},[25,10],[41,42,43],"docker-compose-production",{"src":46,"alt":47},{"path":49,"title":50,"categories":990,"tags":991,"date":58,"draft":962,"slug":992,"description":51,"image":993},[9,10],[54,55,56,57],"monitoring-server-basics",{"src":60,"alt":61},{"path":63,"title":64,"categories":995,"tags":996,"date":71,"draft":962,"slug":997,"description":65,"image":998},[9,67],[10,69,70],"nginx-reverse-proxy",{"src":73,"alt":74},{"path":76,"title":77,"categories":1000,"tags":1001,"date":83,"draft":962,"slug":1002,"description":78,"image":1003},[9,14],[81,82,10],"how-to-secure-a-vps",{"src":85,"alt":86},{"path":88,"title":89,"categories":1005,"tags":1006,"date":95,"draft":962,"slug":1007,"description":90,"image":1008},[9,10],[93,94,43,41],"systemd-node-service",{"src":97,"alt":98},{"path":100,"title":101,"categories":1010,"tags":1011,"date":107,"draft":962,"slug":1012,"description":102,"image":1013},[9,25],[105,10,106],"how-to-install-docker-on-ubuntu-server",{"src":109,"alt":110},{"path":112,"title":113,"categories":1015,"tags":1016,"date":118,"draft":962,"slug":1017,"description":114,"image":1018},[9,14],[117,10,15],"ssh-key-authentication",{"src":120,"alt":121},{"path":123,"title":124,"categories":1020,"tags":1021,"date":131,"draft":962,"slug":1022,"description":125,"image":1023},[9,14],[128,129,130,15],"ufw-firewall-basics",{"src":133,"alt":134},{"path":136,"title":137,"categories":1025,"tags":1026,"date":145,"draft":962,"slug":968,"description":138,"image":1027},[140,10],[142,143,144,30],{"src":147,"alt":148},{"path":150,"title":151,"categories":1029,"tags":1030,"date":155,"draft":962,"slug":1031,"description":152,"image":1032},[9],[106,105,15],"ubuntu-server-initial-setup",{"src":157,"alt":158},[],1789616168260]