【決定版】Ubuntu起動時にコマンドを自動実行する方法|rc.local・cron・systemdを徹底解説

Linux

「Ubuntuでパソコンを起動したら、自動でプログラムやスクリプトを実行したい!」

そんなニーズは、サーバー運用や定型作業の自動化では特に重要です。例えば、Webサーバーの起動、データベースの接続確認、ログファイルの整理、開発環境の準備など、毎回手動で行うのは非効率です。

この記事では、Ubuntuで起動時にコマンドを自動実行するrc.local・cron・systemdの3つの方法について、それぞれの使い方・特徴・注意点を丁寧に解説します。初心者から上級者まで、目的に応じた最適な手法を選べるようになります。

スポンサーリンク

Ubuntu起動時コマンド実行の基本知識

なぜ起動時の自動実行が必要なのか

起動時の自動実行が活用される場面:

サーバー運用での活用

  • Webサーバーやデータベースの自動起動
  • 監視スクリプトの開始
  • ログローテーションの設定
  • バックアップタスクの開始

開発環境での活用

  • 開発サーバーの自動起動
  • 仮想環境の自動アクティベーション
  • テスト環境の準備
  • 開発ツールの自動起動

日常業務での活用

  • ネットワークドライブのマウント
  • 環境変数の設定
  • 定期実行タスクの開始
  • システムの初期設定

3つの方法の特徴比較

方法特徴難易度適用場面注意点
rc.local単純なスクリプト実行★☆☆軽量な初期化作業Ubuntu 18.04以降では要設定
cron (@reboot)ユーザー単位での実行★★☆個人用スクリプト環境変数に注意
systemd高機能なサービス管理★★★本格的なサービス運用設定が複雑だが最も安全

それぞれの特徴を踏まえて、次から具体的な設定手順を詳しく説明します。

rc.localによる自動起動設定

rc.localとは

rc.localは、システム起動の最終段階で実行される従来からあるスクリプトファイルです。

シンプルで理解しやすく、システム全体に影響する初期化作業に適しています。

基本的な設定手順

ステップ1:rc.localファイルの作成

# rc.localファイルを編集(存在しない場合は作成)
sudo nano /etc/rc.local

ステップ2:スクリプト内容の記述

#!/bin/bash
# 
# Ubuntu起動時に実行されるスクリプト
#

# ログファイルに起動時刻を記録
echo "$(date): システムが起動しました" >> /var/log/startup.log

# ネットワークドライブをマウント
mount -t cifs //192.168.1.100/share /mnt/network -o username=user,password=pass

# 環境変数を設定
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# カスタムサービスを起動
/home/ubuntu/scripts/start-services.sh &

# 正常終了
exit 0

ステップ3:実行権限の付与

# rc.localに実行権限を与える
sudo chmod +x /etc/rc.local

Ubuntu 18.04以降での注意点

新しいUbuntuでは、rc.localがデフォルトで無効になっている場合があります:

rc.localサービスの有効化:

# rc.localサービスの状態確認
sudo systemctl status rc-local

# サービスが存在しない場合、手動で作成
sudo nano /etc/systemd/system/rc-local.service

サービス定義ファイルの内容:

[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target

サービスの有効化:

# サービスを有効にして自動起動を設定
sudo systemctl enable rc-local
sudo systemctl start rc-local

# 動作確認
sudo systemctl status rc-local

実用的な使用例

Webサーバー環境の自動起動:

#!/bin/bash
# /etc/rc.local

# ログファイルの初期化
touch /var/log/webapp-startup.log
echo "$(date): Web application startup beginning" >> /var/log/webapp-startup.log

# Dockerサービスの起動を待機
while ! docker info > /dev/null 2>&1; do
    sleep 1
done

# Webアプリケーションコンテナの起動
docker-compose -f /opt/webapp/docker-compose.yml up -d

echo "$(date): Web application startup completed" >> /var/log/webapp-startup.log
exit 0

rc.localは簡単ですが、新しいUbuntuでは設定が必要です。次に、より柔軟なcronを使った方法を説明します。

cronの@rebootオプションを使う方法

cronによる起動時実行の特徴

cronの@rebootオプションは、システム起動時に特定のコマンドを実行する機能です。ユーザー単位で設定でき、個人の作業環境の初期化に適しています。

基本的な設定方法

ステップ1:crontabの編集

# 現在のユーザーのcrontabを編集
crontab -e

# rootユーザーのcrontabを編集(システム全体の設定)
sudo crontab -e

ステップ2:@rebootエントリの追加

# 基本的な書式
@reboot /path/to/command

# 具体例
@reboot /home/username/scripts/startup.sh
@reboot /usr/local/bin/backup-check.py >> /var/log/backup.log 2>&1
@reboot sleep 30 && /opt/application/start.sh

実践的な設定例

開発環境の自動セットアップ:

# crontab -e で以下を追加

# 開発サーバーの起動(30秒待ってから実行)
@reboot sleep 30 && /home/developer/scripts/start-dev-server.sh >> /home/developer/logs/startup.log 2>&1

# Node.js プロジェクトの自動起動
@reboot cd /home/developer/myapp && npm start >> /home/developer/logs/app.log 2>&1

# 仮想環境のアクティベーション確認
@reboot /home/developer/scripts/check-virtualenv.sh

スタートアップスクリプトの例:

#!/bin/bash
# /home/developer/scripts/start-dev-server.sh

# ログファイルの準備
LOG_FILE="/home/developer/logs/startup.log"
echo "$(date): Development server startup initiated" >> $LOG_FILE

# 環境変数の設定
export NODE_ENV=development
export PATH=$PATH:/home/developer/.local/bin

# データベースの起動確認
if ! systemctl is-active --quiet postgresql; then
    echo "$(date): Starting PostgreSQL" >> $LOG_FILE
    sudo systemctl start postgresql
fi

# Redis の起動確認
if ! systemctl is-active --quiet redis; then
    echo "$(date): Starting Redis" >> $LOG_FILE
    sudo systemctl start redis
fi

# Node.js アプリケーションの起動
cd /home/developer/myapp
npm run dev >> $LOG_FILE 2>&1 &

echo "$(date): Development server startup completed" >> $LOG_FILE

cronを使う際の注意点

環境変数の問題:

cronで実行されるスクリプトは、通常のシェルとは異なる環境で動作します:

# crontabの先頭で環境変数を設定
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/home/username
SHELL=/bin/bash

# フルパスを使用する
@reboot /usr/bin/python3 /home/username/scripts/startup.py

# 環境を明示的に読み込み
@reboot /bin/bash -l -c '/home/username/scripts/startup.sh'

実行タイミングの調整:

# ネットワークが利用可能になるまで待機
@reboot sleep 60 && /home/username/scripts/network-dependent.sh

# 他のサービスの起動を待つ
@reboot while ! nc -z localhost 3306; do sleep 1; done && /home/username/scripts/db-setup.sh

cronは柔軟性が高く使いやすい方法です。次に、最も本格的なsystemdを使った方法を説明します。

systemdサービスによる自動実行

systemdの利点

systemdは現代のLinuxシステムで標準的なサービス管理システムです。起動時の自動実行においても最も堅牢で高機能な選択肢です。

systemdの主な利点:

  • 依存関係の管理:他のサービスとの起動順序を制御
  • 再起動機能:プロセスが停止した場合の自動再起動
  • ログ管理:systemd-journaldとの連携
  • リソース制限:CPUやメモリ使用量の制限
  • セキュリティ:専用ユーザーでの実行やサンドボックス機能

基本的な設定手順

ステップ1:サービスファイルの作成

# システム全体のサービスとして作成
sudo nano /etc/systemd/system/myapp.service

# ユーザー固有のサービスとして作成(推奨)
mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/myapp.service

ステップ2:サービス定義の記述

[Unit]
Description=My Custom Application Service
Documentation=https://myapp.example.com/docs
After=network-online.target
Wants=network-online.target

[Service]
Type=exec
User=myuser
Group=mygroup
WorkingDirectory=/home/myuser/myapp
ExecStart=/home/myuser/myapp/start.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10

# セキュリティ設定
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/myuser/myapp/data

# リソース制限
MemoryLimit=512M
CPUQuota=50%

# 環境変数
Environment=NODE_ENV=production
Environment=PORT=3000

[Install]
WantedBy=default.target

ステップ3:サービスの有効化と起動

# システム設定の再読み込み
sudo systemctl daemon-reload

# サービスの有効化(自動起動設定)
sudo systemctl enable myapp.service

# サービスの即座起動
sudo systemctl start myapp.service

# ユーザーサービスの場合
systemctl --user daemon-reload
systemctl --user enable myapp.service
systemctl --user start myapp.service

実践的なサービス例

Webアプリケーションサービス:

[Unit]
Description=Node.js Web Application
Documentation=https://docs.myapp.com
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=exec
User=webapp
Group=webapp
WorkingDirectory=/opt/webapp
ExecStart=/usr/bin/node /opt/webapp/server.js
ExecReload=/bin/kill -USR1 $MAINPID

# 自動再起動設定
Restart=always
RestartSec=5
StartLimitInterval=60
StartLimitBurst=3

# ログ設定
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mywebapp

# セキュリティ強化
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/opt/webapp/logs /opt/webapp/uploads

# 環境変数
Environment=NODE_ENV=production
Environment=PORT=8080
Environment=DATABASE_URL=postgresql://webapp:password@localhost/webapp_db

[Install]
WantedBy=multi-user.target

監視スクリプトサービス:

[Unit]
Description=System Monitor Script
After=network.target

[Service]
Type=exec
User=monitor
Group=monitor
ExecStart=/usr/local/bin/monitor.py --config /etc/monitor/config.yaml

# 定期実行設定(5分ごと)
Restart=always
RestartSec=300

# ログ設定
StandardOutput=journal
StandardError=journal

# リソース制限
MemoryLimit=128M
CPUQuota=10%

[Install]
WantedBy=multi-user.target

サービス管理の実用コマンド

サービスの状態確認:

# サービスの詳細状態
systemctl status myapp.service

# サービスの起動確認
systemctl is-active myapp.service

# 自動起動設定の確認
systemctl is-enabled myapp.service

ログの確認:

# サービスのログを表示
journalctl -u myapp.service

# リアルタイムでログを追跡
journalctl -u myapp.service -f

# 最新50行のログを表示
journalctl -u myapp.service -n 50

サービスの操作:

# サービスの再起動
sudo systemctl restart myapp.service

# サービスの停止
sudo systemctl stop myapp.service

# 設定の再読み込み
sudo systemctl reload myapp.service

# サービスの無効化
sudo systemctl disable myapp.service

まとめ

Ubuntu起動時にコマンドを自動実行する3つの方法を整理すると:

rc.local

  • 適用場面:軽量なシステム初期化、レガシー互換
  • メリット:シンプルで理解しやすい
  • 注意点:新しいUbuntuでは追加設定が必要

cron(@reboot)

  • 適用場面:個人用スクリプト、開発環境の自動化
  • メリット:ユーザー単位での柔軟な設定
  • 注意点:環境変数とパスの設定に注意

systemd

  • 適用場面:本格的なサービス運用、高可用性システム
  • メリット:高機能で安全、詳細な制御が可能
  • 注意点:設定が複雑、学習コストが高い

選択の指針

  1. まず簡単に試したい → cron(@reboot)
  2. システム全体の初期化 → rc.local
  3. 本格的な運用サービス → systemd

コメント

タイトルとURLをコピーしました