❤️ 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.
Khi bạn chạy VPS Linux, hầu hết mọi thứ đều chạy dưới dạng service: Nginx, MySQL, PHP-FPM, SSH, Docker… Tất cả đều do một thứ quản lý, đó là systemd.

Bài này mình sẽ đi qua cách dùng systemd để quản lý service trên VPS, từ những lệnh cơ bản đến tự viết service file riêng. Nội dung áp dụng cho cả Ubuntu và AlmaLinux (CentOS) vì systemd hoạt động giống nhau trên cả hai.
Systemd là gì?
Systemd là init system mặc định trên hầu hết các bản Linux hiện tại: Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS… Nó là process đầu tiên được khởi động khi máy bật (PID 1), và có nhiệm vụ khởi động tất cả các service khác theo đúng thứ tự.
Trước systemd, Linux dùng SysVinit với các script trong /etc/init.d/. Cách này chậm vì chạy tuần tự từng service một. Systemd thay thế bằng cách chạy song song, quản lý dependency giữa các service, và cung cấp logging tập trung qua journald.
Nói ngắn gọn: systemd quản lý vòng đời của tất cả services trên VPS. Bạn muốn start, stop, restart, xem log, hay tự tạo service mới, đều thông qua systemd.
systemctl: lệnh chính để quản lý service
systemctl là công cụ dòng lệnh để tương tác với systemd. Mọi thao tác quản lý service đều dùng lệnh này.
Xem trạng thái service
systemctl status nginx
Output sẽ trông giống như thế này:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2026-03-15 09:00:00 UTC; 7h ago
Docs: man:nginx(8)
Main PID: 1234 (nginx)
Tasks: 3 (limit: 4915)
Memory: 8.5M
CPU: 125ms
CGroup: /system.slice/nginx.service
├─1234 "nginx: master process /usr/sbin/nginx"
├─1235 "nginx: worker process"
└─1236 "nginx: worker process"
Mấy thông tin cần chú ý:
- Loaded: cho biết file unit có tồn tại không, và service có được
enabled(tự khởi động khi boot) hay không. - Active: trạng thái hiện tại.
active (running)là đang chạy,inactive (dead)là đã dừng,failedlà bị lỗi. - Main PID: process ID chính của service.
- CGroup: danh sách các process con thuộc service này.
Dòng cuối cùng thường hiện vài dòng log gần nhất, giúp bạn nhanh chóng biết service có vấn đề gì không.
Start, stop, restart
Khởi động service:
sudo systemctl start nginx
Dừng service:
sudo systemctl stop nginx
Khởi động lại (stop rồi start):
sudo systemctl restart nginx
restart sẽ có một khoảng downtime ngắn vì service bị tắt rồi bật lại. Nếu bạn chỉ thay đổi config và muốn áp dụng mà không gián đoạn, dùng reload:
sudo systemctl reload nginx
Không phải service nào cũng hỗ trợ reload. Nginx và Apache thì có, nhưng nhiều service khác thì không. Nếu không hỗ trợ, bạn sẽ thấy lỗi khi chạy. Lúc đó dùng restart thay thế.
Enable và disable
Hai lệnh này quyết định service có tự khởi động khi VPS boot hay không:
# Tự start khi boot
sudo systemctl enable nginx
# Không tự start khi boot
sudo systemctl disable nginx
enable không start service ngay lập tức, nó chỉ đăng ký để service tự chạy khi boot. Nếu muốn vừa enable vừa start luôn:
sudo systemctl enable --now nginx
Tương tự, disable --now sẽ vừa disable vừa stop service.
Check nhanh trạng thái
Nếu bạn chỉ cần biết service đang chạy hay không, không cần xem cả đống output của status:
# Service đang chạy không?
systemctl is-active nginx
# Service có enable không?
systemctl is-enabled nginx
Hai lệnh này trả về đúng một từ: active/inactive hoặc enabled/disabled. Rất tiện khi dùng trong script:
if systemctl is-active --quiet nginx; then
echo "Nginx đang chạy"
fi
Liệt kê services
Muốn biết VPS đang chạy những service nào:
systemctl list-units --type=service
Lệnh này chỉ hiện các service đang active. Output sẽ có cột UNIT (tên service), LOAD, ACTIVE, SUB (trạng thái chi tiết), và DESCRIPTION.
Muốn xem service nào đang bị lỗi:
systemctl list-units --type=service --state=failed
Nếu kết quả trống thì tốt, nghĩa là không có service nào fail.
Để xem tất cả các service, kể cả những cái disabled hay chưa chạy:
systemctl list-unit-files --type=service
Lệnh này sẽ hiện STATE là enabled, disabled, static, hoặc masked. Service static là loại không thể enable/disable vì nó chỉ được gọi bởi service khác. Service masked là bị chặn hoàn toàn, không thể start bằng bất kỳ cách nào.
Xem log service với journalctl
Systemd có hệ thống log riêng gọi là journald, và bạn dùng journalctl để đọc log. Cái này rất hữu ích khi debug service bị lỗi.
Xem toàn bộ log của một service:
journalctl -u nginx
Log thường rất dài, nên bạn sẽ muốn lọc theo thời gian:
# Log trong 1 giờ qua
journalctl -u nginx --since "1 hour ago"
# Log từ hôm nay
journalctl -u nginx --since today
# Log trong khoảng thời gian cụ thể
journalctl -u nginx --since "2026-03-15 10:00" --until "2026-03-15 12:00"
Theo dõi log realtime (giống tail -f):
journalctl -u nginx -f
Nhấn Ctrl+C để thoát.
Xem log của lần chạy cuối cùng (hữu ích khi service crash rồi restart):
journalctl -u nginx -b
Mặc định trên một số distro, log của journald không được lưu lâu dài (chỉ giữ trong RAM). Để log tồn tại qua reboot, kiểm tra xem thư mục /var/log/journal/ có tồn tại không. Nếu không, tạo nó: sudo mkdir -p /var/log/journal && sudo systemd-tmpfiles --create --prefix /var/log/journal
Tạo service tự viết (custom unit file)
Đây là phần hay nhất. Bạn có thể tạo service riêng cho bất kỳ ứng dụng nào: một app Node.js, một script Python backup, hoặc bất kỳ process nào bạn muốn systemd quản lý.
Service file nằm ở /etc/systemd/system/ và có đuôi .service. Mình sẽ tạo một service cho app Node.js làm ví dụ.
Tạo file:
sudo nano /etc/systemd/system/myapp.service
Nội dung:
[Unit]
Description=My Node.js App
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node /var/www/myapp/index.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.target
Giải thích từng section:
[Unit] chứa thông tin mô tả và dependency:
Description: mô tả ngắn, hiện khi chạysystemctl status.After=network.target: chờ network sẵn sàng trước khi start. Hầu hết web app đều cần dòng này.
[Service] là phần chính, quy định cách chạy:
Type=simple: process chạy ở foreground. Đây là type phổ biến nhất.User=www-data: chạy với user nào. Không nên chạy bằng root trừ khi bắt buộc.WorkingDirectory: thư mục làm việc của app.ExecStart: lệnh để khởi động app. Phải dùng đường dẫn tuyệt đối.Restart=on-failure: tự restart nếu app crash. Các option khác:always(luôn restart),no(không restart).RestartSec=5: chờ 5 giây trước khi restart, tránh restart loop.Environment: set biến môi trường. Mỗi biến một dòng.
[Install] quy định khi nào service được kích hoạt:
WantedBy=multi-user.target: start service khi hệ thống đạt multi-user mode (tức là boot xong). Hầu hết service trên VPS đều dùng dòng này.
Sau khi tạo hoặc sửa file service, bạn phải chạy daemon-reload để systemd nhận file mới:
sudo systemctl daemon-reload
Rồi enable và start:
sudo systemctl enable --now myapp
Kiểm tra xem đã chạy chưa:
systemctl status myapp
Mỗi khi sửa file .service, bạn phải chạy sudo systemctl daemon-reload rồi sudo systemctl restart myapp để áp dụng thay đổi. Quên bước daemon-reload là lỗi rất phổ biến.
Các service quan trọng trên VPS
Trên một VPS chạy web, bạn sẽ thường xuyên làm việc với các service sau:
- sshd: SSH server, cho phép bạn kết nối vào VPS. Đây là service quan trọng nhất, nếu nó tắt thì bạn bị mất kết nối.
- nginx hoặc apache2/httpd: web server.
- mysql hoặc mariadb: database server.
- php-fpm: PHP FastCGI process manager, cần thiết nếu chạy WordPress hoặc PHP app.
- cron/crond: chạy scheduled tasks.
- fail2ban: tự động ban IP khi phát hiện brute force.
- docker: container runtime, nếu bạn dùng Docker.
Systemd hoạt động giống nhau trên Ubuntu và AlmaLinux, nhưng tên một số service khác nhau giữa hai distro:
| Service | Ubuntu / Debian | AlmaLinux / CentOS |
|---|---|---|
| Web server (Apache) | apache2 | httpd |
| Cron | cron | crond |
| SSH | ssh | sshd |
| Firewall | ufw | firewalld |
| Database (MySQL) | mysql | mysqld |
Nginx, MariaDB, PHP-FPM, Fail2ban, Docker thì tên giống nhau trên cả hai.
Targets (thay thế runlevels)
Nếu bạn từng dùng Linux cũ, có thể đã nghe về runlevels (level 3, level 5…). Systemd thay thế chúng bằng targets.
Xem target mặc định:
systemctl get-default
Trên VPS, kết quả sẽ là multi-user.target, tức là hệ thống chạy ở chế độ dòng lệnh, không có giao diện đồ họa. Đây là cái bạn muốn trên server.
Nếu vì lý do nào đó mà VPS chạy graphical.target (có desktop), bạn nên chuyển lại:
sudo systemctl set-default multi-user.target
Các target phổ biến:
multi-user.target: chế độ dòng lệnh, có network. Tương đương runlevel 3.graphical.target: có giao diện đồ họa. Tương đương runlevel 5. Không dùng trên VPS.rescue.target: chế độ rescue, chỉ có root shell. Tương đương runlevel 1.
Troubleshooting service lỗi
Service không chạy được là chuyện bạn sẽ gặp thường xuyên. Đây là quy trình debug mình hay dùng:
Bước 1: Xem status
systemctl status nginx
Dòng Active sẽ cho biết service đang ở trạng thái gì. Nếu là failed, kéo xuống cuối sẽ có vài dòng log gợi ý nguyên nhân.
Bước 2: Xem log chi tiết
journalctl -u nginx -n 50 --no-pager
Lệnh này hiện 50 dòng log gần nhất. Thường lỗi sẽ nằm ở mấy dòng cuối.
Hoặc dùng journalctl -xe để xem log hệ thống gần nhất kèm giải thích:
journalctl -xe
Bước 3: Test config trước khi restart
Nhiều service có lệnh test config riêng. Chạy test trước khi restart sẽ giúp bạn biết lỗi ở đâu mà không ảnh hưởng service đang chạy:
# Nginx
nginx -t
# Apache (Ubuntu)
apachectl configtest
# Apache (AlmaLinux)
httpd -t
# PHP-FPM
php-fpm -t
Bước 4: Thử start lại và xem log realtime
Mở hai terminal. Terminal 1 chạy:
journalctl -u nginx -f
Terminal 2 chạy:
sudo systemctl start nginx
Bạn sẽ thấy log hiện ra ngay lập tức ở terminal 1, rất dễ phát hiện lỗi.
Lỗi phổ biến nhất khi service không start được: sai config, port đã bị service khác chiếm, thiếu permission trên file/thư mục, hoặc binary không tồn tại ở đường dẫn trong ExecStart.
Systemd timer (thay thế cron)
Ngoài quản lý service, systemd còn có timer, hoạt động như cron nhưng có thêm một số ưu điểm: log tập trung qua journalctl, quản lý dependency, và không bị miss khi máy tắt rồi bật lại (với option Persistent=true).
Mỗi timer cần hai file: một .service (định nghĩa việc cần làm) và một .timer (định nghĩa lịch chạy).
Ví dụ tạo timer backup hàng ngày lúc 2 giờ sáng:
Tạo file service:
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Daily backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root
Type=oneshot nghĩa là process chạy xong rồi thoát, không phải service chạy liên tục.
Tạo file timer:
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 2am
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
Giải thích:
OnCalendar=*-*-* 02:00:00: chạy mỗi ngày lúc 2:00 AM. Format làYear-Month-Day Hour:Minute:Second.Persistent=true: nếu VPS tắt lúc 2 AM và bật lại lúc 5 AM, timer sẽ chạy ngay vì biết đã lỡ lịch.
Kích hoạt timer:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
Kiểm tra timer đã hoạt động chưa:
systemctl list-timers
Output sẽ hiện lần chạy tiếp theo (NEXT), lần chạy trước (LAST), và tên timer.
Nếu muốn test thử timer mà không cần chờ đến 2 AM:
sudo systemctl start backup.service
Lệnh này chạy service trực tiếp, bỏ qua timer. Xong thì xem log bằng journalctl -u backup.
Một số ví dụ OnCalendar khác:
# Mỗi giờ
OnCalendar=hourly
# Mỗi thứ Hai lúc 6 AM
OnCalendar=Mon *-*-* 06:00:00
# Mỗi 15 phút
OnCalendar=*:0/15
Checkpoint: thực hành
Sau bài này, bạn nên tự thực hành mấy việc sau trên VPS:
1. Start/stop Nginx và xem trạng thái
sudo systemctl stop nginx
systemctl status nginx
sudo systemctl start nginx
systemctl status nginx
Quan sát trạng thái thay đổi từ inactive (dead) sang active (running).
2. Tạo custom service cho một script đơn giản
Tạo một script:
sudo bash -c 'cat > /usr/local/bin/hello.sh << "EOF"
#!/bin/bash
while true; do
echo "Hello from my service - $(date)"
sleep 60
done
EOF'
sudo chmod +x /usr/local/bin/hello.sh
Tạo service file:
sudo bash -c 'cat > /etc/systemd/system/hello.service << "EOF"
[Unit]
Description=Hello Service
[Service]
Type=simple
ExecStart=/usr/local/bin/hello.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF'
Enable, start, và xem log:
sudo systemctl daemon-reload
sudo systemctl enable --now hello
systemctl status hello
journalctl -u hello -f
Xong thì dọn dẹp:
sudo systemctl disable --now hello
sudo rm /etc/systemd/system/hello.service /usr/local/bin/hello.sh
sudo systemctl daemon-reload
3. Xem log của SSH
# Ubuntu
journalctl -u ssh --since "1 hour ago"
# AlmaLinux
journalctl -u sshd --since "1 hour ago"
Bạn sẽ thấy log mỗi lần có ai SSH vào VPS. Nếu có fail2ban chạy, bạn cũng sẽ thấy các lần đăng nhập sai bị ghi lại ở đây.
Có thể bạn cần xem thêm
- Quản lý process trên Linux - ps, kill, htop cho VPS
- Đọc log hệ thống trên Linux VPS - journalctl và /var/log
- Troubleshooting VPS Linux - Cách xủ lý sự cố VPS phổ biến
- Checklist bảo mật VPS Linux - 15 bước thiết yếu
- Firewall nâng cao trên Linux VPS - UFW và firewalld cho production
- Cập nhật hệ thống tự động trên Linux VPS - unattended-upgrades và dnf-automatic
Về tác giả
Trần Thắng
Chuyên gia tại AZDIGI với nhiều năm kinh nghiệm trong lĩnh vực web hosting và quản trị hệ thống.