「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
- 適用場面:本格的なサービス運用、高可用性システム
- メリット:高機能で安全、詳細な制御が可能
- 注意点:設定が複雑、学習コストが高い
選択の指針
- まず簡単に試したい → cron(@reboot)
- システム全体の初期化 → rc.local
- 本格的な運用サービス → systemd
コメント