[{"data":1,"prerenderedAt":1310},["ShallowReactive",2],{"search-posts-dataset":3,"post-detail-/posts/systemd-node-service":159,"all-published-articles-list":1249,"series-posts-/posts/systemd-node-service":1309},[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":89,"author":161,"body":162,"categories":1237,"date":95,"description":90,"draft":1238,"extension":1239,"image":1240,"meta":1241,"navigation":303,"path":88,"seo":1242,"series":1243,"series_order":1243,"slug":1244,"stem":1245,"tags":1246,"updated":1247,"__hash__":1248},"post/posts/systemd-node-service.md","Duong Thu",{"type":163,"value":164,"toc":1222},"minimal",[165,170,174,194,226,233,236,240,247,325,336,343,363,365,369,375,390,393,425,431,458,460,468,474,488,491,722,727,775,777,781,788,803,806,823,826,842,845,865,872,874,881,894,897,998,1000,1004,1007,1108,1110,1114,1205,1207,1211,1218],[166,167,169],"h2",{"id":168},"tại-sao-nên-dùng-systemd-thay-vì-pm2-hoặc-nohup","Tại sao nên dùng Systemd thay vì PM2 hoặc Nohup?",[171,172,173],"p",{},"Khi chạy ứng dụng backend (Node.js, Express, NestJS, Go, Python FastAPI...) trên máy chủ Linux, bạn cần đảm bảo ứng dụng luôn chạy ngầm, tự khởi động lại khi gặp lỗi crash và tự động bật lên mỗi khi máy chủ VPS khởi động lại.",[171,175,176,177,181,182,185,186,193],{},"Nhiều lập trình viên mới thường sử dụng lệnh ",[178,179,180],"code",{},"nohup node app.js &"," hoặc cài đặt công cụ quản lý ",[178,183,184],{},"PM2",". Tuy nhiên, trong các môi trường doanh nghiệp lớn, ",[187,188,189,192],"strong",{},[178,190,191],{},"Systemd"," (hệ thống khởi tạo và quản lí dịch vụ mặc định của Linux)"," mới là giải pháp tối ưu nhất:",[195,196,197,204,210,220],"ul",{},[198,199,200,203],"li",{},[187,201,202],{},"Không cần cài thêm thư viện phụ thuộc",": Systemd được tích hợp sẵn ở mức nhân hệ điều hành Linux (PID 1).",[198,205,206,209],{},[187,207,208],{},"Quản lý tài nguyên mạnh mẽ",": Tích hợp cgroups cho phép giới hạn trực tiếp CPU, RAM và số lượng tiến trình con (threads).",[198,211,212,215,216,219],{},[187,213,214],{},"Quản lý log tập trung",": Tích hợp trực tiếp với ",[178,217,218],{},"journald"," và tự động quay vòng file log (Log Rotation) chống tràn ổ đĩa.",[198,221,222,225],{},[187,223,224],{},"Độ tin cậy tuyệt đối",": Không bao giờ bị crash như các process manager tầng người dùng.",[171,227,228,229,232],{},"Trong bài viết này, chúng ta sẽ từng bước đóng gói một ứng dụng Node.js thành một dịch vụ ",[187,230,231],{},"Systemd Unit Service"," chuẩn Production.",[234,235],"hr",{},[166,237,239],{"id":238},"_1-chuẩn-bị-thư-mục-ứng-dụng-và-non-root-user","1. Chuẩn bị thư mục ứng dụng và non-root user",[171,241,242,243,246],{},"Không bao giờ chạy ứng dụng web trực tiếp dưới quyền ",[178,244,245],{},"root",". Chúng ta sẽ tạo một tài khoản dịch vụ hệ thống riêng (Service Account):",[248,249,254],"pre",{"className":250,"code":251,"language":252,"meta":253,"style":253},"language-bash shiki shiki-themes github-dark github-dark github-dark","# Tạo user hệ thống không có quyền đăng nhập shell trực tiếp (ví dụ: nodeapp)\nsudo useradd -r -s /bin/false -d /var/www/my-app nodeapp\n\n# Tạo thư mục chứa mã nguồn ứng dụng\nsudo mkdir -p /var/www/my-app\n","bash","",[178,255,256,265,298,305,311],{"__ignoreMap":253},[257,258,261],"span",{"class":259,"line":260},"line",1,[257,262,264],{"class":263},"sGGCZ","# Tạo user hệ thống không có quyền đăng nhập shell trực tiếp (ví dụ: nodeapp)\n",[257,266,268,272,276,280,283,286,289,292,295],{"class":259,"line":267},2,[257,269,271],{"class":270},"sb7EE","sudo",[257,273,275],{"class":274},"skqr8"," useradd",[257,277,279],{"class":278},"sKJT9"," -r",[257,281,282],{"class":278}," -s",[257,284,285],{"class":274}," /bin/",[257,287,288],{"class":278},"false",[257,290,291],{"class":278}," -d",[257,293,294],{"class":274}," /var/www/my-app",[257,296,297],{"class":274}," nodeapp\n",[257,299,301],{"class":259,"line":300},3,[257,302,304],{"emptyLinePlaceholder":303},true,"\n",[257,306,308],{"class":259,"line":307},4,[257,309,310],{"class":263},"# Tạo thư mục chứa mã nguồn ứng dụng\n",[257,312,314,316,319,322],{"class":259,"line":313},5,[257,315,271],{"class":270},[257,317,318],{"class":274}," mkdir",[257,320,321],{"class":278}," -p",[257,323,324],{"class":274}," /var/www/my-app\n",[171,326,327,328,331,332,335],{},"Giả sử file khởi động chính của ứng dụng nằm tại ",[178,329,330],{},"/var/www/my-app/dist/server.js"," hoặc ",[178,333,334],{},"index.js",".",[171,337,338,339,342],{},"Phân quyền sở hữu thư mục cho user ",[178,340,341],{},"nodeapp",":",[248,344,346],{"className":250,"code":345,"language":252,"meta":253,"style":253},"sudo chown -R nodeapp:nodeapp /var/www/my-app\n",[178,347,348],{"__ignoreMap":253},[257,349,350,352,355,358,361],{"class":259,"line":260},[257,351,271],{"class":270},[257,353,354],{"class":274}," chown",[257,356,357],{"class":278}," -R",[257,359,360],{"class":274}," nodeapp:nodeapp",[257,362,324],{"class":274},[234,364],{},[166,366,368],{"id":367},"_2-quản-lý-biến-môi-trường-env-an-toàn","2. Quản lý Biến môi trường (.env) an toàn",[171,370,371,372,342],{},"Tạo file chứa các biến môi trường cấu hình tại ",[178,373,374],{},"/var/www/my-app/.env.production",[248,376,378],{"className":250,"code":377,"language":252,"meta":253,"style":253},"sudo nano /var/www/my-app/.env.production\n",[178,379,380],{"__ignoreMap":253},[257,381,382,384,387],{"class":259,"line":260},[257,383,271],{"class":270},[257,385,386],{"class":274}," nano",[257,388,389],{"class":274}," /var/www/my-app/.env.production\n",[171,391,392],{},"Nội dung:",[248,394,398],{"className":395,"code":396,"language":397,"meta":253,"style":253},"language-ini shiki shiki-themes github-dark github-dark github-dark","NODE_ENV=production\nPORT=3000\nDATABASE_URL=postgres://pgadmin:SuperPass@127.0.0.1:5432/my_db\nREDIS_URL=redis://127.0.0.1:6379\nJWT_SECRET=super_secret_jwt_key_here\n","ini",[178,399,400,405,410,415,420],{"__ignoreMap":253},[257,401,402],{"class":259,"line":260},[257,403,404],{},"NODE_ENV=production\n",[257,406,407],{"class":259,"line":267},[257,408,409],{},"PORT=3000\n",[257,411,412],{"class":259,"line":300},[257,413,414],{},"DATABASE_URL=postgres://pgadmin:SuperPass@127.0.0.1:5432/my_db\n",[257,416,417],{"class":259,"line":307},[257,418,419],{},"REDIS_URL=redis://127.0.0.1:6379\n",[257,421,422],{"class":259,"line":313},[257,423,424],{},"JWT_SECRET=super_secret_jwt_key_here\n",[171,426,427,428,430],{},"Phân quyền bảo mật nghiêm ngặt (chỉ cho phép user ",[178,429,341],{}," được đọc file này):",[248,432,434],{"className":250,"code":433,"language":252,"meta":253,"style":253},"sudo chmod 600 /var/www/my-app/.env.production\nsudo chown nodeapp:nodeapp /var/www/my-app/.env.production\n",[178,435,436,448],{"__ignoreMap":253},[257,437,438,440,443,446],{"class":259,"line":260},[257,439,271],{"class":270},[257,441,442],{"class":274}," chmod",[257,444,445],{"class":278}," 600",[257,447,389],{"class":274},[257,449,450,452,454,456],{"class":259,"line":267},[257,451,271],{"class":270},[257,453,354],{"class":274},[257,455,360],{"class":274},[257,457,389],{"class":274},[234,459],{},[166,461,463,464,467],{"id":462},"_3-tạo-file-systemd-service-unit-my-appservice","3. Tạo file Systemd Service Unit (",[178,465,466],{},"my-app.service",")",[171,469,470,471,342],{},"Tạo file định nghĩa dịch vụ tại ",[178,472,473],{},"/etc/systemd/system/my-app.service",[248,475,477],{"className":250,"code":476,"language":252,"meta":253,"style":253},"sudo nano /etc/systemd/system/my-app.service\n",[178,478,479],{"__ignoreMap":253},[257,480,481,483,485],{"class":259,"line":260},[257,482,271],{"class":270},[257,484,386],{"class":274},[257,486,487],{"class":274}," /etc/systemd/system/my-app.service\n",[171,489,490],{},"Dán cấu hình chuẩn Production hoàn chỉnh dưới đây:",[248,492,494],{"className":395,"code":493,"language":397,"meta":253,"style":253},"[Unit]\nDescription=My Production Node.js Web API Service\nAfter=network.target postgresql.service redis.service\nWants=network-online.target\n\n[Service]\nType=simple\nUser=nodeapp\nGroup=nodeapp\nWorkingDirectory=/var/www/my-app\n\n# Đọc các biến môi trường từ file bảo mật\nEnvironmentFile=/var/www/my-app/.env.production\n\n# Lệnh thực thi ứng dụng (sử dụng đường dẫn tuyệt đối của node)\nExecStart=/usr/bin/node /var/www/my-app/dist/server.js\n\n# Tự động khởi động lại khi ứng dụng bị crash\nRestart=always\nRestartSec=5s\n\n# Giới hạn khởi động lại (tránh vòng lặp restart liên tục khi code có lỗi cú pháp)\nStartLimitIntervalSec=60s\nStartLimitBurst=5\n\n# Giới hạn tài nguyên phần cứng (Memory Limit)\nMemoryHigh=800M\nMemoryMax=1024M\nTasksMax=1000\n\n# Tối ưu giới hạn file mở (File Descriptors) cho Web Server chịu tải cao\nLimitNOFILE=65535\n\n# Tăng cường bảo mật Sandbox\nNoNewPrivileges=true\nProtectSystem=full\nProtectHome=true\n\n[Install]\nWantedBy=multi-user.target\n",[178,495,496,501,506,511,516,520,526,532,538,544,550,555,561,567,572,578,584,589,595,601,607,612,618,624,630,635,641,647,653,659,664,670,676,681,687,693,699,705,710,716],{"__ignoreMap":253},[257,497,498],{"class":259,"line":260},[257,499,500],{},"[Unit]\n",[257,502,503],{"class":259,"line":267},[257,504,505],{},"Description=My Production Node.js Web API Service\n",[257,507,508],{"class":259,"line":300},[257,509,510],{},"After=network.target postgresql.service redis.service\n",[257,512,513],{"class":259,"line":307},[257,514,515],{},"Wants=network-online.target\n",[257,517,518],{"class":259,"line":313},[257,519,304],{"emptyLinePlaceholder":303},[257,521,523],{"class":259,"line":522},6,[257,524,525],{},"[Service]\n",[257,527,529],{"class":259,"line":528},7,[257,530,531],{},"Type=simple\n",[257,533,535],{"class":259,"line":534},8,[257,536,537],{},"User=nodeapp\n",[257,539,541],{"class":259,"line":540},9,[257,542,543],{},"Group=nodeapp\n",[257,545,547],{"class":259,"line":546},10,[257,548,549],{},"WorkingDirectory=/var/www/my-app\n",[257,551,553],{"class":259,"line":552},11,[257,554,304],{"emptyLinePlaceholder":303},[257,556,558],{"class":259,"line":557},12,[257,559,560],{},"# Đọc các biến môi trường từ file bảo mật\n",[257,562,564],{"class":259,"line":563},13,[257,565,566],{},"EnvironmentFile=/var/www/my-app/.env.production\n",[257,568,570],{"class":259,"line":569},14,[257,571,304],{"emptyLinePlaceholder":303},[257,573,575],{"class":259,"line":574},15,[257,576,577],{},"# Lệnh thực thi ứng dụng (sử dụng đường dẫn tuyệt đối của node)\n",[257,579,581],{"class":259,"line":580},16,[257,582,583],{},"ExecStart=/usr/bin/node /var/www/my-app/dist/server.js\n",[257,585,587],{"class":259,"line":586},17,[257,588,304],{"emptyLinePlaceholder":303},[257,590,592],{"class":259,"line":591},18,[257,593,594],{},"# Tự động khởi động lại khi ứng dụng bị crash\n",[257,596,598],{"class":259,"line":597},19,[257,599,600],{},"Restart=always\n",[257,602,604],{"class":259,"line":603},20,[257,605,606],{},"RestartSec=5s\n",[257,608,610],{"class":259,"line":609},21,[257,611,304],{"emptyLinePlaceholder":303},[257,613,615],{"class":259,"line":614},22,[257,616,617],{},"# Giới hạn khởi động lại (tránh vòng lặp restart liên tục khi code có lỗi cú pháp)\n",[257,619,621],{"class":259,"line":620},23,[257,622,623],{},"StartLimitIntervalSec=60s\n",[257,625,627],{"class":259,"line":626},24,[257,628,629],{},"StartLimitBurst=5\n",[257,631,633],{"class":259,"line":632},25,[257,634,304],{"emptyLinePlaceholder":303},[257,636,638],{"class":259,"line":637},26,[257,639,640],{},"# Giới hạn tài nguyên phần cứng (Memory Limit)\n",[257,642,644],{"class":259,"line":643},27,[257,645,646],{},"MemoryHigh=800M\n",[257,648,650],{"class":259,"line":649},28,[257,651,652],{},"MemoryMax=1024M\n",[257,654,656],{"class":259,"line":655},29,[257,657,658],{},"TasksMax=1000\n",[257,660,662],{"class":259,"line":661},30,[257,663,304],{"emptyLinePlaceholder":303},[257,665,667],{"class":259,"line":666},31,[257,668,669],{},"# Tối ưu giới hạn file mở (File Descriptors) cho Web Server chịu tải cao\n",[257,671,673],{"class":259,"line":672},32,[257,674,675],{},"LimitNOFILE=65535\n",[257,677,679],{"class":259,"line":678},33,[257,680,304],{"emptyLinePlaceholder":303},[257,682,684],{"class":259,"line":683},34,[257,685,686],{},"# Tăng cường bảo mật Sandbox\n",[257,688,690],{"class":259,"line":689},35,[257,691,692],{},"NoNewPrivileges=true\n",[257,694,696],{"class":259,"line":695},36,[257,697,698],{},"ProtectSystem=full\n",[257,700,702],{"class":259,"line":701},37,[257,703,704],{},"ProtectHome=true\n",[257,706,708],{"class":259,"line":707},38,[257,709,304],{"emptyLinePlaceholder":303},[257,711,713],{"class":259,"line":712},39,[257,714,715],{},"[Install]\n",[257,717,719],{"class":259,"line":718},40,[257,720,721],{},"WantedBy=multi-user.target\n",[723,724,726],"h3",{"id":725},"giải-thích-các-tham-số-quan-trọng","Giải thích các tham số quan trọng:",[195,728,729,737,749,757],{},[198,730,731,736],{},[187,732,733],{},[178,734,735],{},"After=network.target postgresql.service",": Đảm bảo dịch vụ mạng và cơ sở dữ liệu đã sẵn sàng trước khi ứng dụng khởi chạy.",[198,738,739,748],{},[187,740,741,744,745],{},[178,742,743],{},"Restart=always"," & ",[178,746,747],{},"RestartSec=5s",": Nếu ứng dụng bị Unhandled Exception dẫn đến crash, Systemd sẽ tự động khởi động lại sau 5 giây.",[198,750,751,756],{},[187,752,753],{},[178,754,755],{},"MemoryMax=1024M",": Giới hạn tối đa 1GB RAM. Nếu ứng dụng vượt quá mức này, Systemd sẽ tự động kill và restart lại dịch vụ để bảo vệ máy chủ.",[198,758,759,764,765,768,769,768,772,335],{},[187,760,761],{},[178,762,763],{},"ProtectSystem=full",": Ngăn ứng dụng ghi đè lên các thư mục hệ điều hành quan trọng như ",[178,766,767],{},"/usr",", ",[178,770,771],{},"/boot",[178,773,774],{},"/etc",[234,776],{},[166,778,780],{"id":779},"_4-kích-hoạt-và-vận-hành-dịch-vụ","4. Kích hoạt và Vận hành Dịch vụ",[171,782,783,784,787],{},"Mỗi khi tạo mới hoặc chỉnh sửa file ",[178,785,786],{},".service",", bạn cần yêu cầu Systemd nạp lại cấu hình:",[248,789,791],{"className":250,"code":790,"language":252,"meta":253,"style":253},"sudo systemctl daemon-reload\n",[178,792,793],{"__ignoreMap":253},[257,794,795,797,800],{"class":259,"line":260},[257,796,271],{"class":270},[257,798,799],{"class":274}," systemctl",[257,801,802],{"class":274}," daemon-reload\n",[171,804,805],{},"Kích hoạt dịch vụ tự động khởi chạy cùng máy chủ:",[248,807,809],{"className":250,"code":808,"language":252,"meta":253,"style":253},"sudo systemctl enable my-app\n",[178,810,811],{"__ignoreMap":253},[257,812,813,815,817,820],{"class":259,"line":260},[257,814,271],{"class":270},[257,816,799],{"class":274},[257,818,819],{"class":274}," enable",[257,821,822],{"class":274}," my-app\n",[171,824,825],{},"Bắt đầu khởi chạy dịch vụ:",[248,827,829],{"className":250,"code":828,"language":252,"meta":253,"style":253},"sudo systemctl start my-app\n",[178,830,831],{"__ignoreMap":253},[257,832,833,835,837,840],{"class":259,"line":260},[257,834,271],{"class":270},[257,836,799],{"class":274},[257,838,839],{"class":274}," start",[257,841,822],{"class":274},[171,843,844],{},"Kiểm tra trạng thái hoạt động:",[248,846,848],{"className":250,"code":847,"language":252,"meta":253,"style":253},"sudo systemctl status my-app --no-pager\n",[178,849,850],{"__ignoreMap":253},[257,851,852,854,856,859,862],{"class":259,"line":260},[257,853,271],{"class":270},[257,855,799],{"class":274},[257,857,858],{"class":274}," status",[257,860,861],{"class":274}," my-app",[257,863,864],{"class":278}," --no-pager\n",[171,866,867,868,871],{},"Nếu màn hình hiển thị màu xanh lá cây ",[178,869,870],{},"Active: active (running)"," thì dịch vụ của bạn đã vận hành hoàn hảo!",[234,873],{},[166,875,877,878],{"id":876},"_5-theo-dõi-và-giám-sát-log-với-journalctl","5. Theo dõi và Giám sát Log với ",[178,879,880],{},"journalctl",[171,882,883,884,887,888,891,892,335],{},"Toàn bộ log ",[178,885,886],{},"console.log()"," và ",[178,889,890],{},"console.error()"," của ứng dụng Node.js sẽ được chuyển tiếp trực tiếp vào hệ thống quản lý log ",[178,893,218],{},[171,895,896],{},"Dưới đây là các lệnh theo dõi log thông dụng:",[248,898,900],{"className":250,"code":899,"language":252,"meta":253,"style":253},"# Xem log thời gian thực (giống tail -f)\nsudo journalctl -u my-app -f\n\n# Xem 100 dòng log gần nhất\nsudo journalctl -u my-app -n 100 --no-pager\n\n# Xem log ghi nhận trong ngày hôm nay\nsudo journalctl -u my-app --since today\n\n# Chỉ xem các log có mức độ cảnh báo hoặc lỗi (Warnings/Errors)\nsudo journalctl -u my-app -p err..emerg\n",[178,901,902,907,922,926,931,949,953,958,974,978,983],{"__ignoreMap":253},[257,903,904],{"class":259,"line":260},[257,905,906],{"class":263},"# Xem log thời gian thực (giống tail -f)\n",[257,908,909,911,914,917,919],{"class":259,"line":267},[257,910,271],{"class":270},[257,912,913],{"class":274}," journalctl",[257,915,916],{"class":278}," -u",[257,918,861],{"class":274},[257,920,921],{"class":278}," -f\n",[257,923,924],{"class":259,"line":300},[257,925,304],{"emptyLinePlaceholder":303},[257,927,928],{"class":259,"line":307},[257,929,930],{"class":263},"# Xem 100 dòng log gần nhất\n",[257,932,933,935,937,939,941,944,947],{"class":259,"line":313},[257,934,271],{"class":270},[257,936,913],{"class":274},[257,938,916],{"class":278},[257,940,861],{"class":274},[257,942,943],{"class":278}," -n",[257,945,946],{"class":278}," 100",[257,948,864],{"class":278},[257,950,951],{"class":259,"line":522},[257,952,304],{"emptyLinePlaceholder":303},[257,954,955],{"class":259,"line":528},[257,956,957],{"class":263},"# Xem log ghi nhận trong ngày hôm nay\n",[257,959,960,962,964,966,968,971],{"class":259,"line":534},[257,961,271],{"class":270},[257,963,913],{"class":274},[257,965,916],{"class":278},[257,967,861],{"class":274},[257,969,970],{"class":278}," --since",[257,972,973],{"class":274}," today\n",[257,975,976],{"class":259,"line":540},[257,977,304],{"emptyLinePlaceholder":303},[257,979,980],{"class":259,"line":546},[257,981,982],{"class":263},"# Chỉ xem các log có mức độ cảnh báo hoặc lỗi (Warnings/Errors)\n",[257,984,985,987,989,991,993,995],{"class":259,"line":552},[257,986,271],{"class":270},[257,988,913],{"class":274},[257,990,916],{"class":278},[257,992,861],{"class":274},[257,994,321],{"class":278},[257,996,997],{"class":274}," err..emerg\n",[234,999],{},[166,1001,1003],{"id":1002},"_6-quy-trình-triển-khai-code-mới-zero-downtime-deployment","6. Quy trình triển khai Code mới (Zero-Downtime Deployment)",[171,1005,1006],{},"Khi bạn đẩy code mới lên máy chủ, quy trình triển khai diễn ra cực kỳ đơn giản và nhanh gọn:",[248,1008,1010],{"className":250,"code":1009,"language":252,"meta":253,"style":253},"# 1. Chuyển vào thư mục mã nguồn\ncd /var/www/my-app\n\n# 2. Kéo code mới và build\ngit pull origin main\nnpm ci --production\nnpm run build\n\n# 3. Phân lại quyền cho user dịch vụ\nsudo chown -R nodeapp:nodeapp /var/www/my-app\n\n# 4. Khởi động lại dịch vụ mượt mà\nsudo systemctl restart my-app\n",[178,1011,1012,1017,1024,1028,1033,1046,1057,1067,1071,1076,1088,1092,1097],{"__ignoreMap":253},[257,1013,1014],{"class":259,"line":260},[257,1015,1016],{"class":263},"# 1. Chuyển vào thư mục mã nguồn\n",[257,1018,1019,1022],{"class":259,"line":267},[257,1020,1021],{"class":278},"cd",[257,1023,324],{"class":274},[257,1025,1026],{"class":259,"line":300},[257,1027,304],{"emptyLinePlaceholder":303},[257,1029,1030],{"class":259,"line":307},[257,1031,1032],{"class":263},"# 2. Kéo code mới và build\n",[257,1034,1035,1037,1040,1043],{"class":259,"line":313},[257,1036,140],{"class":270},[257,1038,1039],{"class":274}," pull",[257,1041,1042],{"class":274}," origin",[257,1044,1045],{"class":274}," main\n",[257,1047,1048,1051,1054],{"class":259,"line":522},[257,1049,1050],{"class":270},"npm",[257,1052,1053],{"class":274}," ci",[257,1055,1056],{"class":278}," --production\n",[257,1058,1059,1061,1064],{"class":259,"line":528},[257,1060,1050],{"class":270},[257,1062,1063],{"class":274}," run",[257,1065,1066],{"class":274}," build\n",[257,1068,1069],{"class":259,"line":534},[257,1070,304],{"emptyLinePlaceholder":303},[257,1072,1073],{"class":259,"line":540},[257,1074,1075],{"class":263},"# 3. Phân lại quyền cho user dịch vụ\n",[257,1077,1078,1080,1082,1084,1086],{"class":259,"line":546},[257,1079,271],{"class":270},[257,1081,354],{"class":274},[257,1083,357],{"class":278},[257,1085,360],{"class":274},[257,1087,324],{"class":274},[257,1089,1090],{"class":259,"line":552},[257,1091,304],{"emptyLinePlaceholder":303},[257,1093,1094],{"class":259,"line":557},[257,1095,1096],{"class":263},"# 4. Khởi động lại dịch vụ mượt mà\n",[257,1098,1099,1101,1103,1106],{"class":259,"line":563},[257,1100,271],{"class":270},[257,1102,799],{"class":274},[257,1104,1105],{"class":274}," restart",[257,1107,822],{"class":274},[234,1109],{},[166,1111,1113],{"id":1112},"bảng-tra-cứu-lệnh-systemd-thiết-yếu","Bảng tra cứu lệnh Systemd thiết yếu",[1115,1116,1117,1131],"table",{},[1118,1119,1120],"thead",{},[1121,1122,1123,1128],"tr",{},[1124,1125,1127],"th",{"align":1126},"left","Lệnh",[1124,1129,1130],{"align":1126},"Ý nghĩa",[1132,1133,1134,1145,1155,1165,1175,1185,1195],"tbody",{},[1121,1135,1136,1142],{},[1137,1138,1139],"td",{"align":1126},[178,1140,1141],{},"sudo systemctl start \u003Cservice>",[1137,1143,1144],{"align":1126},"Khởi động dịch vụ",[1121,1146,1147,1152],{},[1137,1148,1149],{"align":1126},[178,1150,1151],{},"sudo systemctl stop \u003Cservice>",[1137,1153,1154],{"align":1126},"Dừng dịch vụ",[1121,1156,1157,1162],{},[1137,1158,1159],{"align":1126},[178,1160,1161],{},"sudo systemctl restart \u003Cservice>",[1137,1163,1164],{"align":1126},"Khởi động lại dịch vụ",[1121,1166,1167,1172],{},[1137,1168,1169],{"align":1126},[178,1170,1171],{},"sudo systemctl reload \u003Cservice>",[1137,1173,1174],{"align":1126},"Nạp lại cấu hình mà không ngắt kết nối",[1121,1176,1177,1182],{},[1137,1178,1179],{"align":1126},[178,1180,1181],{},"sudo systemctl enable \u003Cservice>",[1137,1183,1184],{"align":1126},"Cho phép tự chạy khi bật máy",[1121,1186,1187,1192],{},[1137,1188,1189],{"align":1126},[178,1190,1191],{},"sudo systemctl disable \u003Cservice>",[1137,1193,1194],{"align":1126},"Tắt tính năng tự chạy",[1121,1196,1197,1202],{},[1137,1198,1199],{"align":1126},[178,1200,1201],{},"sudo systemctl is-active \u003Cservice>",[1137,1203,1204],{"align":1126},"Kiểm tra nhanh trạng thái (running/inactive)",[234,1206],{},[166,1208,1210],{"id":1209},"lời-kết","Lời kết",[171,1212,1213,1214,1217],{},"Sử dụng ",[187,1215,1216],{},"Systemd Service"," là giải pháp bản địa (native), nhẹ nhất, nhanh nhất và chuẩn mực nhất để đưa bất kỳ ứng dụng backend nào lên môi trường sản xuất Linux.",[1219,1220,1221],"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":253,"searchDepth":267,"depth":267,"links":1223},[1224,1225,1226,1227,1231,1232,1234,1235,1236],{"id":168,"depth":267,"text":169},{"id":238,"depth":267,"text":239},{"id":367,"depth":267,"text":368},{"id":462,"depth":267,"text":1228,"children":1229},"3. Tạo file Systemd Service Unit (my-app.service)",[1230],{"id":725,"depth":300,"text":726},{"id":779,"depth":267,"text":780},{"id":876,"depth":267,"text":1233},"5. Theo dõi và Giám sát Log với journalctl",{"id":1002,"depth":267,"text":1003},{"id":1112,"depth":267,"text":1113},{"id":1209,"depth":267,"text":1210},[9,10],false,"md",{"src":97,"alt":98},{},{"title":89,"description":90},null,"systemd-node-service","posts/systemd-node-service",[93,94,43,41],"2026-08-22","5CWr419RJn",[1250,1255,1260,1265,1270,1275,1280,1284,1289,1294,1299,1304],{"path":5,"title":6,"categories":1251,"tags":1252,"date":16,"draft":1238,"slug":1253,"description":7,"image":1254},[9,10],[12,13,14,15],"incident-checklist",{"src":18,"alt":19},{"path":21,"title":22,"categories":1256,"tags":1257,"date":31,"draft":1238,"slug":1258,"description":23,"image":1259},[25,26],[28,29,30,10],"backup-postgres-docker",{"src":33,"alt":34},{"path":36,"title":37,"categories":1261,"tags":1262,"date":44,"draft":1238,"slug":1263,"description":38,"image":1264},[25,10],[41,42,43],"docker-compose-production",{"src":46,"alt":47},{"path":49,"title":50,"categories":1266,"tags":1267,"date":58,"draft":1238,"slug":1268,"description":51,"image":1269},[9,10],[54,55,56,57],"monitoring-server-basics",{"src":60,"alt":61},{"path":63,"title":64,"categories":1271,"tags":1272,"date":71,"draft":1238,"slug":1273,"description":65,"image":1274},[9,67],[10,69,70],"nginx-reverse-proxy",{"src":73,"alt":74},{"path":76,"title":77,"categories":1276,"tags":1277,"date":83,"draft":1238,"slug":1278,"description":78,"image":1279},[9,14],[81,82,10],"how-to-secure-a-vps",{"src":85,"alt":86},{"path":88,"title":89,"categories":1281,"tags":1282,"date":95,"draft":1238,"slug":1244,"description":90,"image":1283},[9,10],[93,94,43,41],{"src":97,"alt":98},{"path":100,"title":101,"categories":1285,"tags":1286,"date":107,"draft":1238,"slug":1287,"description":102,"image":1288},[9,25],[105,10,106],"how-to-install-docker-on-ubuntu-server",{"src":109,"alt":110},{"path":112,"title":113,"categories":1290,"tags":1291,"date":118,"draft":1238,"slug":1292,"description":114,"image":1293},[9,14],[117,10,15],"ssh-key-authentication",{"src":120,"alt":121},{"path":123,"title":124,"categories":1295,"tags":1296,"date":131,"draft":1238,"slug":1297,"description":125,"image":1298},[9,14],[128,129,130,15],"ufw-firewall-basics",{"src":133,"alt":134},{"path":136,"title":137,"categories":1300,"tags":1301,"date":145,"draft":1238,"slug":1302,"description":138,"image":1303},[140,10],[142,143,144,30],"git-deploy-key",{"src":147,"alt":148},{"path":150,"title":151,"categories":1305,"tags":1306,"date":155,"draft":1238,"slug":1307,"description":152,"image":1308},[9],[106,105,15],"ubuntu-server-initial-setup",{"src":157,"alt":158},[],1789616168214]