jpskill.com
💬 コミュニケーション コミュニティ

systemd

Linuxのシステムサービスやデーモンの管理、自動起動、ログ記録などを効率的に行うSkill。

📜 元の英語説明(参考)

Systemd service management, unit files, timers, and journal logging on Linux. Use when user mentions "systemd", "systemctl", "service file", "unit file", "journalctl", "system service", "daemon", "auto-start on boot", "timer", "systemd timer", "service restart", "enable service", "journald", "system logs", or managing Linux services and daemons.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Linuxのシステムサービスやデーモンの管理、自動起動、ログ記録などを効率的に行うSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o systemd.zip https://jpskill.com/download/6132.zip && unzip -o systemd.zip && rm systemd.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/6132.zip -OutFile "$d\systemd.zip"; Expand-Archive "$d\systemd.zip" -DestinationPath $d -Force; ri "$d\systemd.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して systemd.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → systemd フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-17
取得日時
2026-05-17
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Systemd

systemctl コマンド

sudo systemctl start myapp
sudo systemctl stop myapp
sudo systemctl restart myapp
sudo systemctl reload myapp            # 完全な再起動なしで設定をリロードします
sudo systemctl enable myapp            # 起動時に自動開始します
sudo systemctl enable --now myapp      # 有効にしてすぐに開始します
sudo systemctl disable myapp

systemctl status myapp
systemctl is-active myapp
systemctl is-enabled myapp
systemctl show myapp -p MainPID,MemoryCurrent

sudo systemctl daemon-reload           # ユニットファイルを編集後にリロードします

systemctl list-units --type=service --state=failed
systemctl list-unit-files --type=service
systemctl list-timers

ユニットファイルの作成

システムサービスは /etc/systemd/system/myapp.service に配置します。

[Unit]
Description=My Application Server
After=network.target postgresql.service
Wants=postgresql.service

[Service]
Type=simple
User=appuser
Group=appgroup
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp

[Install]
WantedBy=multi-user.target

作成または編集後: sudo systemctl daemon-reload && sudo systemctl enable --now myapp

サービスタイプ

タイプ 動作 ユースケース
simple デフォルト。ExecStart プロセスがメインプロセスです ほとんどの長時間実行サービス
forking プロセスがフォークし、親が終了します。PIDFile を設定します 従来のデーモン
oneshot 実行して終了します。完了後にサービスは「アクティブ」です セットアップスクリプト、マイグレーション
notify simple と同様ですが、準備ができたときに sd_notify を送信します systemd 対応アプリ
idle simple と同様ですが、他のジョブが終了するまで待機します 低優先度の起動タスク
# Forking の例
[Service]
Type=forking
PIDFile=/run/myapp/myapp.pid
ExecStart=/opt/myapp/bin/server --daemonize

# Oneshot の例
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/setup-iptables.sh

環境変数

[Service]
Environment=NODE_ENV=production
Environment=PORT=3000 HOST=0.0.0.0
EnvironmentFile=/etc/myapp/env
EnvironmentFile=-/etc/myapp/env.local   # ダッシュプレフィックス: ファイルが存在しなくてもエラーになりません

環境ファイル (/etc/myapp/env): 1行に1つの VAR=VALUE を記述します。

再起動ポリシー

[Service]
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=300    # レートリミットウィンドウ
StartLimitBurst=5            # ウィンドウ内の最大再起動回数
ポリシー クリーン終了 不正なシグナル タイムアウト ウォッチドッグ
no - - - -
on-failure - はい はい はい
on-abnormal - はい はい はい
always はい はい はい はい

失敗したユニットをリセットします: sudo systemctl reset-failed myapp

リソース制限

[Service]
MemoryMax=512M
MemoryHigh=400M              # ハードリミット前にスロットルします
CPUQuota=200%                # 最大2つのフルコア
CPUWeight=50                 # 相対的な重み (デフォルトは100)
LimitNOFILE=65536
LimitNPROC=4096

依存関係管理

[Unit]
# 順序付けのみ (依存関係は引き込みません)
After=network.target redis.service
Before=nginx.service

# 依存関係を引き込みます
Requires=postgresql.service       # ハード: postgres が失敗すると、これも失敗します
Wants=redis.service               # ソフト: redis が失敗しても続行します
BindsTo=docker.service            # Requires と同様 + docker が停止すると停止します

# 実際のネットワーク接続が必要なサービスの場合
After=network-online.target
Wants=network-online.target

ユーザーサービス

ユニットは ~/.config/systemd/user/ に配置します。root 権限は不要です。

# ~/.config/systemd/user/myapp.service
[Unit]
Description=My User Application

[Service]
Type=simple
ExecStart=%h/bin/myapp
Restart=on-failure
Environment=PORT=8080

[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now myapp
journalctl --user -u myapp -f
sudo loginctl enable-linger $USER    # アクティブなログインセッションなしで実行します

%h はユーザーのホームディレクトリに展開されます。

タイマー (Cron の代替)

# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true                  # ダウンタイム後に実行し損ねた実行を再開します
RandomizedDelaySec=900

[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Backup job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

モノトニックタイマー (起動からの相対時間):

[Timer]
OnBootSec=5min
OnUnitActiveSec=1h              # 最後の実行から1時間ごとに繰り返します

OnCalendar の例:

hourly | daily | weekly
Mon,Fri *-*-* 09:00:00          # 月曜日と金曜日の午前9時
*-*-01 00:00:00                 # 毎月1日
*-*-* *:00/15:00                # 15分ごと

検証: systemd-analyze calendar "Mon,Fri *-*-* 09:00:00"

journalctl によるログクエリ

journalctl -u myapp -f                                  # フォローします
journalctl -u myapp -n 100                              # 最新100行
journalctl -u myapp --since "1 hour ago"                # 時間フィルター
journalctl -u myapp --since "2024-01-15" --until "2024-01-16"
journalctl -u myapp -p err                              # 優先度フィルター
journalctl -u myapp -b                                  # 現在のブートのみ
journalctl -u myapp -o json-pretty -n 10                # JSON 出力
journalctl -u myapp -o json --no-pager | jq '.MESSAGE'
journalctl -k                                           # カーネルメッセージ
journalctl --disk-usage
sudo journalctl --v
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Systemd

systemctl Commands

sudo systemctl start myapp
sudo systemctl stop myapp
sudo systemctl restart myapp
sudo systemctl reload myapp            # Reload config without full restart
sudo systemctl enable myapp            # Auto-start on boot
sudo systemctl enable --now myapp      # Enable and start immediately
sudo systemctl disable myapp

systemctl status myapp
systemctl is-active myapp
systemctl is-enabled myapp
systemctl show myapp -p MainPID,MemoryCurrent

sudo systemctl daemon-reload           # Reload unit files after editing

systemctl list-units --type=service --state=failed
systemctl list-unit-files --type=service
systemctl list-timers

Writing Unit Files

Place system services in /etc/systemd/system/myapp.service.

[Unit]
Description=My Application Server
After=network.target postgresql.service
Wants=postgresql.service

[Service]
Type=simple
User=appuser
Group=appgroup
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp

[Install]
WantedBy=multi-user.target

After creating or editing: sudo systemctl daemon-reload && sudo systemctl enable --now myapp

Service Types

Type Behavior Use Case
simple Default. ExecStart process is the main process Most long-running services
forking Process forks; parent exits. Set PIDFile Traditional daemons
oneshot Runs and exits. Service is "active" after completion Setup scripts, migrations
notify Like simple, but sends sd_notify when ready systemd-aware apps
idle Like simple, but waits until other jobs finish Low-priority startup tasks
# Forking example
[Service]
Type=forking
PIDFile=/run/myapp/myapp.pid
ExecStart=/opt/myapp/bin/server --daemonize

# Oneshot example
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/setup-iptables.sh

Environment Variables

[Service]
Environment=NODE_ENV=production
Environment=PORT=3000 HOST=0.0.0.0
EnvironmentFile=/etc/myapp/env
EnvironmentFile=-/etc/myapp/env.local   # Dash prefix: no error if missing

Environment file (/etc/myapp/env): one VAR=VALUE per line.

Restart Policies

[Service]
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=300    # Rate-limit window
StartLimitBurst=5            # Max restarts within window
Policy Clean exit Unclean signal Timeout Watchdog
no - - - -
on-failure - Yes Yes Yes
on-abnormal - Yes Yes Yes
always Yes Yes Yes Yes

Reset a failed unit: sudo systemctl reset-failed myapp

Resource Limits

[Service]
MemoryMax=512M
MemoryHigh=400M              # Throttle before hard limit
CPUQuota=200%                # 2 full cores max
CPUWeight=50                 # Relative weight (default 100)
LimitNOFILE=65536
LimitNPROC=4096

Dependency Management

[Unit]
# Ordering only (does NOT pull in the dependency)
After=network.target redis.service
Before=nginx.service

# Pull in dependencies
Requires=postgresql.service       # Hard: if postgres fails, this fails too
Wants=redis.service               # Soft: continues even if redis fails
BindsTo=docker.service            # Like Requires + stop when docker stops

# For services needing actual network connectivity
After=network-online.target
Wants=network-online.target

User Services

Place units in ~/.config/systemd/user/. No root required.

# ~/.config/systemd/user/myapp.service
[Unit]
Description=My User Application

[Service]
Type=simple
ExecStart=%h/bin/myapp
Restart=on-failure
Environment=PORT=8080

[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now myapp
journalctl --user -u myapp -f
sudo loginctl enable-linger $USER    # Run without active login session

%h expands to the user's home directory.

Timers (Cron Replacement)

# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true                  # Run missed executions after downtime
RandomizedDelaySec=900

[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Backup job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Monotonic timers (relative to boot):

[Timer]
OnBootSec=5min
OnUnitActiveSec=1h              # Repeat every hour after last run

OnCalendar examples:

hourly | daily | weekly
Mon,Fri *-*-* 09:00:00          # Mon and Fri at 9 AM
*-*-01 00:00:00                 # First of every month
*-*-* *:00/15:00                # Every 15 minutes

Validate: systemd-analyze calendar "Mon,Fri *-*-* 09:00:00"

journalctl Log Querying

journalctl -u myapp -f                                  # Follow
journalctl -u myapp -n 100                              # Last 100 lines
journalctl -u myapp --since "1 hour ago"                # Time filter
journalctl -u myapp --since "2024-01-15" --until "2024-01-16"
journalctl -u myapp -p err                              # Priority filter
journalctl -u myapp -b                                  # Current boot only
journalctl -u myapp -o json-pretty -n 10                # JSON output
journalctl -u myapp -o json --no-pager | jq '.MESSAGE'
journalctl -k                                           # Kernel messages
journalctl --disk-usage
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=7d

Socket Activation

Start services on-demand when a connection arrives.

# /etc/systemd/system/myapp.socket
[Unit]
Description=My App Socket

[Socket]
ListenStream=8080
Accept=no

[Install]
WantedBy=sockets.target
# /etc/systemd/system/myapp.service
[Unit]
Description=My App
Requires=myapp.socket

[Service]
Type=simple
ExecStart=/opt/myapp/bin/server

The service receives the socket as fd 3 (SD_LISTEN_FDS_START). Enable the socket, not the service: sudo systemctl enable --now myapp.socket

Templated Units

Template files use @ in the name. Instance name is %i.

# /etc/systemd/system/myapp@.service
[Unit]
Description=My App instance %i
After=network.target

[Service]
Type=simple
User=appuser
ExecStart=/opt/myapp/bin/server --port %i
Restart=on-failure

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now myapp@8080
sudo systemctl enable --now myapp@8081

Common Service Patterns

Node.js

[Service]
Type=simple
User=nodeapp
WorkingDirectory=/opt/nodeapp
ExecStart=/usr/bin/node server.js
EnvironmentFile=/etc/nodeapp/env
Environment=NODE_ENV=production
LimitNOFILE=65536
Restart=on-failure
RestartSec=5

Python (uvicorn with venv)

[Service]
Type=simple
User=pyapp
WorkingDirectory=/opt/pyapp
ExecStart=/opt/pyapp/venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8000
EnvironmentFile=/etc/pyapp/env
Restart=on-failure

Go Binary

[Service]
Type=simple
User=goapp
ExecStart=/usr/local/bin/goservice
EnvironmentFile=/etc/goservice/env
Restart=on-failure
LimitNOFILE=65536

Docker Container

[Unit]
After=docker.service
Requires=docker.service

[Service]
Type=simple
Restart=always
RestartSec=10
ExecStartPre=-/usr/bin/docker stop mycontainer
ExecStartPre=-/usr/bin/docker rm mycontainer
ExecStart=/usr/bin/docker run --rm --name mycontainer -p 8080:80 myimage:latest
ExecStop=/usr/bin/docker stop mycontainer

- prefix on ExecStartPre: don't fail if the command fails (container may not exist).

All patterns need [Unit] with After=network.target and [Install] with WantedBy=multi-user.target.

Debugging Failed Services

systemctl status myapp
journalctl -xeu myapp                             # Logs with explanations
journalctl -u myapp -b --no-pager                 # Full boot log
systemd-analyze blame                              # Time per unit at boot
systemd-analyze critical-chain myapp               # Dependency chain timing
systemd-analyze verify myapp.service               # Validate unit file syntax
systemd-analyze security myapp                     # Security audit score
systemctl show myapp -p ExecMainStatus,Result,ActiveState

Common exit codes:

  • 200: bad unit file syntax (check ExecStart path, missing =)
  • 203: exec format error (missing shebang, wrong architecture)
  • 217: user/group doesn't exist

Security Hardening

[Service]
ProtectSystem=strict              # Mount / read-only
ProtectHome=true                  # Hide /home, /root, /run/user
ReadWritePaths=/var/lib/myapp     # Whitelist writable paths
PrivateTmp=true                   # Isolated /tmp
NoNewPrivileges=true              # Block privilege escalation
PrivateDevices=true               # No physical device access
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
SystemCallFilter=@system-service
SystemCallArchitectures=native

# Dynamic user (ephemeral UID, ideal for stateless services)
DynamicUser=true
StateDirectory=myapp              # Auto-creates /var/lib/myapp
CacheDirectory=myapp              # Auto-creates /var/cache/myapp
LogsDirectory=myapp               # Auto-creates /var/log/myapp

# Allow binding ports < 1024 without root
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

Audit: systemd-analyze security myapp (0 = most secure, 10 = least).

Path Units (File Watching)

# /etc/systemd/system/deploy-watcher.path
[Unit]
Description=Watch for deployment triggers

[Path]
PathChanged=/var/deploy/trigger       # Trigger on write + close
PathExists=/var/deploy/run-now        # Trigger when file appears
PathModified=/var/deploy/config       # Trigger on any write
Unit=deploy.service

[Install]
WantedBy=multi-user.target
# /etc/systemd/system/deploy.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/deploy.sh
sudo systemctl enable --now deploy-watcher.path

Quick Reference: Unit File Specifiers

Specifier Meaning
%i Instance name (template units)
%I Unescaped instance name
%n Full unit name
%h User home directory
%t Runtime directory (/run)
%S State directory (/var/lib)
%C Cache directory (/var/cache)