Tan Phat Media

Systemd Service Generator

Tạo file unit systemd để chạy ứng dụng nền trên Linux

Cấu hình Unit
nodeapp.service
[Unit]
Description=Node.js application service
After=network.target

[Service]
Type=simple
User=nodeapp
Group=nodeapp
WorkingDirectory=/opt/nodeapp
ExecStart=/usr/bin/node /opt/nodeapp/server.js
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5

# Biến môi trường
Environment="NODE_ENV=production"
Environment="PORT=3000"
EnvironmentFile=-/etc/nodeapp/.env

# Giới hạn tài nguyên
MemoryMax=512M
CPUQuota=80%

# Sandbox
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
NoNewPrivileges=true

# Log
StandardOutput=journal
StandardError=journal
SyslogIdentifier=nodeapp

[Install]
WantedBy=multi-user.target
Lệnh cài đặt
sudo nano /etc/systemd/system/nodeapp.service
sudo systemd-analyze verify /etc/systemd/system/nodeapp.service
sudo systemctl daemon-reload
sudo systemctl enable --now nodeapp.service
sudo systemctl status nodeapp.service
Xem log và điều khiển
journalctl -u nodeapp.service -f
journalctl -u nodeapp.service -n 100 --no-pager
journalctl -u nodeapp.service --since "1 hour ago"
journalctl -u nodeapp.service -p err -b
sudo systemctl restart nodeapp.service
sudo systemctl stop nodeapp.service && sudo systemctl disable nodeapp.service

Hợp tác ngay với Tấn Phát Digital

Chúng tôi không chỉ thiết kế website, mà còn giúp doanh nghiệp xây dựng thương hiệu số mạnh mẽ. Cung cấp dịch vụ thiết kế website trọn gói từ thiết kế đến tối ưu SEO. Hãy liên hệ ngay với Tấn Phát Digital để cùng tạo nên những giải pháp công nghệ đột phá, hiệu quả và bền vững cho doanh nghiệp của bạn tại Hồ Chí Minh.

Tạo file unit systemd: chạy ứng dụng nền, tự khởi động lại và ghi log vào journal

Công cụ dựng file unit systemd hoàn chỉnh với ba khối Unit, Service và Install từ các ô nhập trên trình duyệt. Có bốn mẫu dựng sẵn cho ứng dụng Node.js, ứng dụng Python, tệp nhị phân Go và tác vụ sao lưu định kỳ, kèm khung lệnh cài đặt và khung lệnh xem log journalctl chép được ngay.

Tính năng nổi bật

  • Ba khối Unit, Service và Install sinh đầy đủ với Description, After, Requires và WantedBy chọn từ danh sách
  • Bốn kiểu tiến trình simple, forking, oneshot và notify, chọn forking thì hiện thêm ô khai báo tệp PID
  • Ô User, Group và WorkingDirectory để chạy dịch vụ bằng tài khoản riêng thay vì tài khoản quản trị
  • ExecStart, ExecReload cùng chính sách Restart bốn mức và số giây chờ giữa hai lần khởi động lại
  • Bảng thêm biến môi trường không giới hạn dòng, cộng một ô EnvironmentFile trỏ tới tệp biến bên ngoài
  • Giới hạn tài nguyên bằng MemoryMax và CPUQuota, sandbox bằng ProtectSystem bốn mức, ProtectHome, PrivateTmp và NoNewPrivileges
  • Bốn mẫu dựng sẵn nạp một lần đủ cả cấu hình lẫn biến môi trường cho Node.js, Python, Go và tác vụ sao lưu
  • Công tắc sinh kèm tệp .timer với OnCalendar và Persistent, cùng hai khung lệnh cài đặt và xem log chép được ngay

Vì sao nên giao việc chạy nền cho systemd thay vì các cách tạm bợ

Cách chạy ứng dụng nền phổ biến nhất trên máy chủ mới dựng là mở phiên SSH rồi chạy lệnh kèm dấu và ở cuối, hoặc dùng một phiên terminal ảo để giữ tiến trình sống. Cả hai đều hỏng ở cùng một chỗ: khi máy chủ khởi động lại vì cập nhật nhân hệ điều hành hay vì mất điện, không có gì bật ứng dụng lên lại, và bạn chỉ biết khi khách hàng báo website chết. Khi tiến trình tự thoát vì hết bộ nhớ hoặc vì một lỗi chưa bắt, cũng không có gì bật lại. Log thì nằm rải rác trong tệp tự ghi hoặc bay mất theo phiên terminal. systemd giải quyết cả ba việc đó bằng một tệp văn bản duy nhất: nó khởi động dịch vụ theo đúng thứ tự phụ thuộc lúc máy lên, tự bật lại khi tiến trình chết theo chính sách bạn đặt, gom toàn bộ đầu ra vào journal có thể lọc theo thời gian và theo mức nghiêm trọng, đồng thời cô lập dịch vụ bằng các tham số sandbox để một ứng dụng bị chiếm quyền không đụng được tới phần còn lại của hệ thống. Điều duy nhất khiến nhiều người ngại là cú pháp có nhiều từ khóa cần nhớ, và đó chính là phần công cụ này làm thay.

Lợi ích khi sử dụng

  • Ứng dụng tự lên lại sau mỗi lần máy chủ khởi động, không cần ai vào SSH bật tay
  • Tiến trình chết được bật lại theo chính sách rõ ràng, kèm số giây chờ để tránh quay vòng liên tục
  • Toàn bộ đầu ra vào journal nên lọc được theo dịch vụ, theo mốc thời gian và theo mức nghiêm trọng
  • Trần bộ nhớ và trần CPU giữ cho một dịch vụ rò rỉ bộ nhớ không kéo sập các dịch vụ khác trên cùng máy
  • Bốn mẫu dựng sẵn tiết kiệm phần lớn thời gian gõ, chỉ còn việc sửa đường dẫn và tên tài khoản

Cách tạo file unit systemd bằng công cụ này

  1. 1Bấm một trong bốn mẫu dựng sẵn gần nhất với việc bạn cần, các ô sẽ được nạp đồng loạt để bạn sửa lại thay vì gõ từ đầu.
  2. 2Ở thẻ Unit, đổi tên unit thành tên dịch vụ của bạn, viết lại Description và khai báo Requires nếu ứng dụng bắt buộc phải có cơ sở dữ liệu chạy trước.
  3. 3Ở thẻ Service, chọn đúng kiểu tiến trình, điền ExecStart bằng đường dẫn tuyệt đối tới tệp thực thi, rồi chọn chính sách khởi động lại và số giây chờ.
  4. 4Ở thẻ Env, thêm từng biến môi trường cần thiết, hoặc trỏ EnvironmentFile tới tệp chứa khóa bí mật để không đưa chúng vào file unit.
  5. 5Ở thẻ Limits, đặt trần bộ nhớ và trần CPU, chọn mức ProtectSystem, bật công tắc tạo kèm .timer nếu đây là tác vụ chạy theo lịch, rồi tải hai tệp về và làm theo khung lệnh cài đặt bên dưới.

Ba khối trong file unit và vai trò khác nhau của chúng

Khối Unit chứa phần mô tả và quan hệ với các dịch vụ khác. Description là dòng chữ hiện ra khi bạn xem trạng thái, nên viết cho người đọc hiểu chứ đừng lặp lại tên tệp. After chỉ nói về thứ tự khởi động: nếu ghi network.target thì dịch vụ của bạn chỉ được bật sau khi lớp mạng đã dựng xong, nhưng nếu mục tiêu đó thất bại thì dịch vụ vẫn cứ chạy. Requires mới là quan hệ ràng buộc thật: nếu đơn vị được khai báo ở đây dừng hoặc hỏng thì dịch vụ của bạn cũng bị dừng theo. Đây là chỗ hay nhầm nhất, nhiều người ghi Requires cho cơ sở dữ liệu rồi ngạc nhiên khi khởi động lại cơ sở dữ liệu thì ứng dụng cũng tắt. Khối Service mô tả tiến trình chạy thế nào, gồm kiểu tiến trình, tài khoản chạy, thư mục làm việc, câu lệnh khởi động, chính sách khởi động lại, biến môi trường và các giới hạn. Khối Install chỉ có tác dụng khi bạn chạy lệnh bật dịch vụ, WantedBy quyết định dịch vụ được móc vào mục tiêu nào để tự chạy lúc máy lên, và multi-user.target là mục tiêu tương đương chế độ nhiều người dùng không giao diện đồ họa, phù hợp với hầu hết máy chủ.

Chọn đúng Type: simple, forking, oneshot hay notify

Chọn sai kiểu tiến trình là nguyên nhân hàng đầu khiến dịch vụ báo đã chạy mà thực ra chưa sẵn sàng, hoặc treo ở trạng thái đang khởi động cho tới lúc hết giờ. Kiểu simple dùng khi tiến trình bạn khởi động chạy luôn ở tiền cảnh và không tự tách ra nền, đây là trường hợp của hầu hết ứng dụng viết bằng Node.js, Go hay Java. Với kiểu này, systemd coi dịch vụ đã khởi động thành công ngay khi tiến trình được sinh ra, nên nếu ứng dụng cần vài giây để lắng nghe cổng thì trong khoảng đó trạng thái vẫn là đang chạy. Kiểu forking dùng cho các chương trình kiểu cũ tự tách mình ra nền rồi để tiến trình cha thoát, khi đó bạn phải khai báo tệp PID để systemd biết theo dõi tiến trình con nào, thiếu khai báo này thì systemd sẽ tưởng dịch vụ đã chết. Kiểu oneshot dùng cho tác vụ chạy một lần rồi kết thúc như tập lệnh sao lưu, systemd chờ tiến trình thoát hẳn mới coi là xong và không báo lỗi khi nó dừng. Kiểu notify dành cho chương trình biết tự gửi tín hiệu báo sẵn sàng, chính xác nhất nhưng đòi ứng dụng hỗ trợ, ví dụ điển hình là Gunicorn chạy kèm thư viện tương ứng.

Restart, RestartSec và cái bẫy quay vòng khởi động

Chính sách khởi động lại quyết định systemd làm gì khi tiến trình thoát. Mức no là không làm gì, phù hợp cho tác vụ oneshot vì tác vụ sao lưu chạy xong thoát là chuyện bình thường, đặt always ở đây sẽ khiến nó chạy lại liên tục. Mức on-failure chỉ bật lại khi tiến trình thoát với mã lỗi khác không hoặc bị hạ bởi tín hiệu, đây là lựa chọn hợp lý nhất cho phần lớn ứng dụng vì nó tôn trọng việc bạn chủ động dừng dịch vụ. Mức always bật lại trong mọi trường hợp kể cả khi tiến trình thoát sạch, dùng khi ứng dụng không bao giờ được phép tự tắt. Số giây chờ giữa hai lần bật lại quan trọng hơn vẻ ngoài của nó: nếu để bằng không và ứng dụng chết ngay khi khởi động vì thiếu biến môi trường, systemd sẽ quay vòng bật rồi chết hàng chục lần mỗi giây, làm ngập log và ngốn CPU. Đặt vài giây cho hệ thống thở, đồng thời systemd còn có cơ chế bảo vệ riêng đếm số lần bật lại trong một khoảng thời gian, vượt ngưỡng thì nó bỏ cuộc và đưa dịch vụ về trạng thái hỏng. Khi gặp trạng thái đó, bạn phải chạy lệnh đặt lại bộ đếm hoặc chờ hết khoảng đếm rồi mới bật lại được.

Sandbox và giới hạn tài nguyên: cô lập dịch vụ trên máy chủ chạy nhiều site

Các dòng ở phần cuối khối Service không đổi cách ứng dụng chạy nhưng thu hẹp đáng kể thiệt hại khi nó bị chiếm quyền. ProtectSystem mức true gắn các thư mục hệ thống thành chỉ đọc, mức full mở rộng thêm thư mục cấu hình, còn mức strict biến toàn bộ hệ thống tệp thành chỉ đọc trừ những đường dẫn bạn cấp phép riêng, mức này an toàn nhất nhưng dễ làm ứng dụng cần ghi tệp bị lỗi quyền, nên hãy thử ở môi trường thử nghiệm trước. ProtectHome che các thư mục cá nhân của người dùng khỏi tầm nhìn của dịch vụ. PrivateTmp cấp cho dịch vụ một thư mục tạm riêng, vừa tránh xung đột tên tệp giữa các dịch vụ vừa chặn kiểu tấn công lợi dụng tệp tạm dùng chung. NoNewPrivileges chặn tiến trình và mọi tiến trình con của nó leo thang quyền, kể cả qua tệp có cờ đặc quyền. Về tài nguyên, MemoryMax là trần cứng: vượt qua thì tiến trình bị hạ vì hết bộ nhớ, nhưng chỉ mình nó chết thay vì kéo cả máy chủ vào cảnh cạn bộ nhớ. CPUQuota tính theo phần trăm của một lõi, nên giá trị hai trăm phần trăm nghĩa là cho phép dùng trọn hai lõi. Trên một máy chủ chạy hàng chục site, hai con số này là ranh giới giữ cho sự cố của một dịch vụ không lan sang các dịch vụ còn lại.

Chạy theo lịch bằng timer, và vì sao công cụ này khác hai công cụ cấu hình web server

Khi bật công tắc tạo kèm tệp .timer, công cụ sinh thêm một đơn vị thứ hai cùng tên nhưng khác phần mở rộng, bên trong khai báo lịch chạy và trỏ về dịch vụ tương ứng. Lúc cài, bạn bật tệp timer chứ không bật tệp service, vì chính timer mới là thứ gọi service dậy đúng giờ. Tùy chọn Persistent giải quyết vấn đề mà cron không xử lý được: nếu máy chủ tắt đúng lúc tới hạn, cron bỏ qua luôn lượt đó, còn timer có Persistent sẽ chạy bù ngay khi máy lên lại. Ưu điểm khác so với cron là tác vụ chạy qua timer cũng ghi log vào journal và cũng chịu mọi giới hạn tài nguyên cùng tham số sandbox mà bạn đã đặt trong file service. Cần phân biệt rõ công cụ này với hai công cụ cấu hình web server cạnh bên: cấu hình Nginx tại /vi/tools/nginx-config-generator quyết định máy chủ web nhận yêu cầu HTTP rồi trả về cái gì, tệp .htaccess tại /vi/tools/htaccess-generator làm việc tương tự trên Apache theo từng thư mục, còn file unit ở trang này không liên quan gì tới giao thức HTTP. Nó chỉ lo việc một tiến trình được bật lên, sống bao lâu, chết thì có được bật lại không. Trên thực tế ba thứ thường đi cùng nhau: unit giữ cho ứng dụng luôn chạy ở một cổng nội bộ, còn cấu hình web server chuyển tiếp yêu cầu từ bên ngoài vào cổng đó.

Câu hỏi thường gặp (FAQ)

Đặt file unit vào thư mục nào cho đúng?

Đặt vào /etc/systemd/system nếu đây là dịch vụ do bạn tự viết cho máy chủ này. Thư mục /lib/systemd/system hay /usr/lib/systemd/system dành cho unit do các gói phần mềm cài vào, đừng sửa trực tiếp ở đó vì bản cập nhật gói sẽ ghi đè. Sau khi thêm hoặc sửa tệp, luôn chạy lệnh nạp lại cấu hình systemd.

Dịch vụ báo trạng thái active nhưng ứng dụng không phản hồi, vì sao?

Thường do chọn kiểu simple cho một chương trình cần thời gian khởi động, hoặc cho một chương trình tự tách ra nền. Với kiểu simple, systemd coi là thành công ngay khi sinh được tiến trình chứ không kiểm tra ứng dụng đã lắng nghe cổng chưa. Nếu chương trình tự tách nền, hãy đổi sang kiểu forking và khai báo tệp PID.

ExecStart báo lỗi không tìm thấy lệnh dù chạy tay thì được?

Vì systemd không chạy qua shell nên không có biến PATH như phiên đăng nhập của bạn, phải dùng đường dẫn tuyệt đối tới tệp thực thi. Ngoài ra các ký hiệu của shell như dấu chuyển hướng, dấu ống hay dấu và đều không hoạt động, muốn dùng thì phải bọc câu lệnh vào một tập lệnh riêng rồi trỏ ExecStart vào tập lệnh đó.

Có nên để dịch vụ chạy bằng tài khoản quản trị không?

Không nên. Hãy tạo một tài khoản hệ thống riêng không có shell đăng nhập, cấp cho nó quyền đọc ghi đúng những thư mục cần thiết rồi điền vào ô User và Group. Khi ứng dụng bị khai thác, kẻ tấn công chỉ có quyền của tài khoản đó thay vì toàn quyền trên máy chủ.

Requires và After khác nhau thế nào?

After chỉ sắp thứ tự khởi động chứ không tạo ràng buộc, đơn vị được nhắc tới hỏng thì dịch vụ của bạn vẫn chạy. Requires tạo ràng buộc thật, đơn vị kia dừng thì dịch vụ của bạn cũng bị dừng theo. Trong nhiều trường hợp Wants là lựa chọn hợp lý hơn vì nó gợi ý phụ thuộc mà không kéo theo việc dừng dây chuyền.

Dấu trừ trước đường dẫn EnvironmentFile có ý nghĩa gì?

Nó bảo systemd bỏ qua khi tệp không tồn tại thay vì coi đó là lỗi khởi động. Rất tiện lúc mới triển khai, khi tệp biến môi trường chưa kịp tạo. Nhưng nếu ứng dụng bắt buộc phải có các biến đó mới chạy được, hãy bỏ dấu trừ đi để dịch vụ báo lỗi sớm thay vì chạy với cấu hình thiếu.

Đặt mật khẩu và khóa bí mật thẳng vào phần Environment có an toàn không?

Không nên, vì nội dung file unit ai đọc được tệp cũng thấy, và các dòng đó còn hiện ra khi xem thông tin dịch vụ. Hãy để bí mật trong một tệp riêng đặt quyền chỉ chủ sở hữu đọc được rồi trỏ EnvironmentFile vào đó, hoặc dùng cơ chế quản lý bí mật của hệ thống nếu bản systemd của bạn hỗ trợ.

Xem log của dịch vụ bằng lệnh nào?

Dùng journalctl với tham số -u kèm tên đơn vị. Thêm -f để theo dõi trực tiếp, thêm -n kèm số dòng để xem phần cuối, thêm --since kèm mốc thời gian để giới hạn khoảng, thêm -p err để chỉ lấy các dòng từ mức lỗi trở lên. Khung lệnh trong công cụ đã điền sẵn tên đơn vị của bạn.

Dịch vụ ở trạng thái failed và không bật lại được nữa?

Nhiều khả năng nó đã vượt ngưỡng số lần khởi động lại trong một khoảng thời gian nên systemd bỏ cuộc. Hãy chạy lệnh đặt lại trạng thái hỏng cho đơn vị đó rồi bật lại, đồng thời tăng số giây chờ giữa hai lần bật. Quan trọng hơn là đọc log để tìm nguyên nhân thật thay vì chỉ bật lại.

Timer của systemd hơn cron ở điểm nào?

Tác vụ chạy qua timer ghi log vào journal nên tra cứu dễ hơn, chịu mọi giới hạn tài nguyên và tham số sandbox đã đặt trong file service, và có tùy chọn chạy bù khi máy chủ đang tắt đúng lúc tới hạn. Cron thì bỏ qua luôn lượt đó và log thường phải tự chuyển hướng vào tệp.

Bật timer rồi có cần bật cả service không?

Không. Bạn chỉ bật tệp timer, còn tệp service chỉ cần nằm đúng chỗ. Timer là thứ gọi service dậy đúng giờ. Nếu bật cả hai, service sẽ chạy thêm một lần ngay lúc máy khởi động, thường không phải điều bạn muốn với một tác vụ sao lưu ban đêm.

Sửa file unit xong khởi động lại dịch vụ mà không thấy thay đổi?

Vì systemd giữ bản cấu hình đã nạp trong bộ nhớ, phải chạy lệnh nạp lại cấu hình trước rồi mới khởi động lại dịch vụ. Nếu vẫn không đổi, hãy kiểm tra xem có tệp ghi đè trong thư mục cùng tên với đuôi .d hay không, vì nội dung trong đó được áp dụng sau và sẽ thắng.

Từ khóa liên quan

  • systemd service generator
  • tạo file service systemd
  • systemd unit file
  • chạy nodejs như service linux
  • systemd type simple forking
  • systemd restart on-failure
  • systemd environment file
  • systemd memorymax cpuquota
  • systemd protectsystem sandbox
  • systemd nonewprivileges
  • systemctl enable now
  • journalctl xem log service
  • systemd timer thay cron
  • oncalendar systemd cú pháp
  • systemd persistent chạy bù
  • systemd service failed start-limit
  • chạy python gunicorn bằng systemd
  • tự động chạy ứng dụng khi khởi động linux

Công cụ Developer Tools liên quan

.env Generator

Tạo file .env và .env.example cho dự án.

.gitignore Generator

Tạo .gitignore cho Node.js, Python, Java.

API Mock Generator

Tạo mock JSON data cho API testing.

API Response Formatter

Format và phân tích API response.

API Tester

Test REST API: GET, POST, PUT, DELETE.

Postman Alternative - API Testing Tool Online với Collections, Environment & File Upload

Postman Alternative miễn phí - Test APIs với Collections, Multiple Environments, Pre-request Scripts, Collection Runner, File Upload (form-data), Tests/Assertions, Code Generation (cURL, JS, Python, Node.js). Browser-based, không cần cài đặt. Save requests, export/import collections, auto-save history. Hỗ trợ Bearer Token, Basic Auth, API Key. Hoàn hảo cho API development và testing.

Swagger API Tester - Test API với OpenAPI/Swagger Spec & Authentication Online

Swagger API Tester miễn phí - Import OpenAPI/Swagger specification và test API endpoints với đầy đủ authentication (Bearer Token/JWT, Basic Auth, API Key). Hỗ trợ OpenAPI 3.0, Swagger 2.0, auto-parse endpoints, parameters, request body. Giao diện như Swagger UI với color-coded methods, grouped endpoints, real-time testing. Hoàn hảo cho API development, testing, debugging secured APIs.

Base Converter

Chuyển đổi Binary, Hex, Base32.

Base64 Encoder

Mã hóa/giải mã Base64.

Binary Converter

Chuyển đổi Decimal, Binary, Hex.

Box Shadow Generator

Tạo CSS box-shadow trực quan.

Chmod Calculator

Tính quyền file Linux.

Dịch vụ của Tấn Phát Digital

Đang xây sản phẩm và cần thêm người làm phần nặng?

Gói giải pháp doanh nghiệp

Nền tảng custom cho ngân hàng, y tế và sàn B2B, chuẩn ISO 27001, GDPR, PCI-DSS, SLA 99.99%.

Từ 50.000.000đXem chi tiết →

Dịch vụ phát triển Blockchain & Web3

Smart contract, dApp và NFT marketplace đa chuỗi, audit bảo mật đầy đủ trước khi lên mainnet.

Từ 50.000.000đXem chi tiết →

Dịch vụ thiết kế website tại Hồ Chí Minh

Website doanh nghiệp, bán hàng và đặt lịch, chuẩn SEO ngay từ cấu trúc, tốc độ tải dưới 3 giây.

Từ 5.000.000đXem chi tiết →

Dịch vụ thiết kế landing page

Trang đích riêng cho từng chiến dịch quảng cáo, tỷ lệ chuyển đổi 3–8%, bàn giao trong 5–21 ngày.

Từ 3.000.000đXem chi tiết →

Tư vấn và báo giá miễn phí trong 24 giờ. Xem toàn bộ dịch vụ

Zalo
Facebook
Tấn Phát Digital
Zalo
Facebook