Series: Lập trình Raspberry Pi & Ứng dụng thực tế Phần 1 — Nền tảng Raspberry Pi Bài 3: Quản lý ứng dụng chạy nền bằng systemd (auto-start, restart, logs)
1) Mục tiêu bài học
Sau bài này bạn sẽ:
- Tạo một app “hello service” chạy nền trên Pi.
- Cấu hình systemd service: auto-start khi boot, tự restart khi lỗi.
- Xem log nhanh bằng
journalctlvà debug service như DevOps chuẩn.
2) Tại sao phải dùng systemd (thay vì chạy node app.js/python app.py)
- Ổn định: app crash → tự restart
- Quản trị: start/stop/status/logs chuẩn hệ điều hành
- Tự động: boot lên là chạy, không phụ thuộc terminal/SSH session
3) Chuẩn bị thư mục ứng dụng
Tạo user chạy service (khuyến nghị) — nếu bạn đã có user developer thì dùng luôn.
Tạo thư mục app:
mkdir -p ~/apps/pi-agent
cd ~/apps/pi-agent
4) Ví dụ app chạy nền (Python) — đơn giản mà “thật”
Tạo file app.py:
nano app.py
Dán nội dung:
import time
from datetime import datetimedef main():
while True:
print(f"[pi-agent] alive at {datetime.now().isoformat(timespec='seconds')}")
time.sleep(5)if __name__ == "__main__":
main()
Test chạy thử:
python3 app.py
Thấy log chạy mỗi 5 giây là OK. Bấm Ctrl+C để dừng.
5) Tạo systemd service
Tạo file service:
sudo nano /etc/systemd/system/pi-agent.service
Dán cấu hình (đổi User= đúng user của bạn, ví dụ developer):
[Unit]
Description=IoTLabs Pi Agent (demo)
After=network-online.target
Wants=network-online.target[Service]
Type=simple
User=developer
WorkingDirectory=/home/developer/apps/pi-agent
ExecStart=/usr/bin/python3 /home/developer/apps/pi-agent/app.py# Tự restart khi lỗi
Restart=always
RestartSec=3# Log ra journald
StandardOutput=journal
StandardError=journal# Tối ưu cơ bản
KillSignal=SIGINT
TimeoutStopSec=10[Install]
WantedBy=multi-user.target
6) Enable + start service
sudo systemctl daemon-reload
sudo systemctl enable pi-agent
sudo systemctl start pi-agent
Kiểm tra trạng thái:
sudo systemctl status pi-agent --no-pager
7) Xem log như dân chuyên
Xem log gần nhất:
journalctl -u pi-agent -n 50 --no-pager
Follow realtime:
journalctl -u pi-agent -f
8) Thử “crash” để thấy auto-restart hoạt động
Sửa app.py để crash sau 10 giây (chỉ để test):
import time
raise Exception("boom")
Reload/restart:
sudo systemctl restart pi-agent
Xem log:
journalctl -u pi-agent -n 50 --no-pager
Bạn sẽ thấy service restart liên tục theo Restart=always.
Sau đó nhớ sửa lại app bình thường nhé.
9) Best practices cho dự án thật
A) Dùng file .env (không hard-code)
Trong systemd, thêm:
EnvironmentFile=/home/developer/apps/pi-agent/.env
và trong .env dạng:
MQTT_HOST=mqtt.iotlabs.vn
MQTT_PORT=8883
DEVICE_ID=pi-gw-01
B) Giới hạn tài nguyên (tuỳ cần)
Bạn có thể thêm:
MemoryMax=200M
CPUQuota=50%
Giúp Pi chạy ổn khi có nhiều service.
C) Đặt restart policy hợp lý
Restart=always: phù hợp agent/gatewayRestart=on-failure: phù hợp job/service không muốn restart khi bạn chủ động stop
10) Checklist debug nhanh
- Service không chạy:
- Sai đường dẫn
ExecStart - Sai
WorkingDirectory - User không có quyền đọc file
- Sai đường dẫn
statusbáo code exit:- Xem log bằng
journalctl -u pi-agent -f
- Xem log bằng
- Sửa file service nhưng không ăn:
- Quên
sudo systemctl daemon-reload
- Quên
11) Bài tập nâng cấp
- Đổi tên service thành
iotlabs-gateway.servicetheo hostname của bạn. - Thêm
EnvironmentFilevà in raDEVICE_IDtrong log. - Set
Restart=on-failurevà test crash.


