IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

Series: Lập trình Raspberry Pi – Bài 3: Quản lý ứng dụng chạy nền bằng systemd (auto-start, restart, logs)

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 journalctl và 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/gateway
  • Restart=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
  • status báo code exit:
    • Xem log bằng journalctl -u pi-agent -f
  • Sửa file service nhưng không ăn:
    • Quên sudo systemctl daemon-reload

11) Bài tập nâng cấp

  1. Đổi tên service thành iotlabs-gateway.service theo hostname của bạn.
  2. Thêm EnvironmentFile và in ra DEVICE_ID trong log.
  3. Set Restart=on-failure và test crash.