サーバー同期はこれでOK|rsync over SSH 完全ガイド(コピペ可)

バックアップ・復元

差分だけ高速暗号化で安全。サーバーとのファイル同期は rsync × SSH が最適解です。この記事は “いますぐ動く” コマンドと、事故を防ぐ運用テンプレを中心にまとめました。

まずは最短レシピ(コピペ可)

1) 鍵認証の用意

# まだ鍵が無い場合のみ
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 user@server.example.com

2) まずはドライラン(実行せず差分確認)

SRC="/path/to/local_dir"
DST="user@server.example.com:/srv/app/shared"
rsync -a -z -P --delete --itemize-changes \
  -e 'ssh -p 22 -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=accept-new' \
  "$SRC/" "$DST" --dry-run

3) 本番実行

rsync -a -z -P --delete --itemize-changes \
  -e 'ssh -p 22 -i ~/.ssh/id_ed25519' \
  "$SRC/" "$DST"

ポイント

  • "$SRC/" の末尾スラッシュは「中身を同期」の意味(超重要)。
  • --delete は宛先から不要ファイルを削除=完全ミラー。必ずドライランで確認してから。

使い回せる基本構文

  • ローカル → リモート(ミラー)
rsync -a -z -P --delete -e 'ssh -p 22' SRC_DIR/ user@host:/path/to/DST_DIR
  • リモート → ローカル(取得)
rsync -a -z -P --delete -e 'ssh -p 22' user@host:/path/to/SRC_DIR/ ./DST_DIR
  • 除外パターンの指定
# .rsync-exclude を用意(例)
cat > .rsync-exclude <<'EOF'
*.tmp
node_modules/
.DS_Store
cache/
EOF

rsync -a -z -P --delete --exclude-from=.rsync-exclude \
  -e 'ssh -p 22' SRC_DIR/ user@host:/path/to/DST_DIR

よく使うオプション早見表

オプション役割 / 効果
-aアーカイブ(再帰・時刻・権限 等)基本は常に付ける
-z転送圧縮低速回線で有効
-P進捗+再開に強い(--partial --progress大きいファイル向け
--delete宛先から不要を削除(完全ミラー)要ドライラン確認
--itemize-changes変更内容を記号で一覧化監査・検証向け
--exclude(-from)除外キャッシュ除外など
--numeric-idsUID/GID を数字で扱う異環境間で整合
--bwlimit=5m帯域制限業務時間の負荷抑制
--info=stats2,progress2詳細統計と進捗rsync 3.x 以降

macOS の標準 rsync は古いことが多いです。brew install rsync で 3.x を導入すると快適。

SSH設定をスッキリ書く(~/.ssh/config)

Host prod
  HostName server.example.com
  User user
  Port 22
  IdentityFile ~/.ssh/id_ed25519
  StrictHostKeyChecking accept-new
  ServerAliveInterval 60

以後はこれでOK:

rsync -a -z -P --delete SRC_DIR/ prod:/srv/app/shared

バスティオン経由(踏み台)

Host bastion
  HostName bastion.example.com
  User ops

Host prod
  HostName private.example.internal
  User deploy
  ProxyJump bastion
  IdentityFile ~/.ssh/id_ed25519
# ProxyJump は ssh 側の設定なので、そのまま使える
rsync -a -z -P --delete ./build/ prod:/var/www/app/

日次スナップショット(履歴も残す/リモート)

未変更はハードリンク再利用で容量節約(rsync 先の同一FS上に前回のスナップショットが必要)。

SRC="/data"
HOST="prod"
ROOT="/srv/backup/snapshots"
STAMP="$(date +%F)"           # 例: 2025-08-23
TARGET="${ROOT}/${STAMP}"
PREV="${ROOT}/latest"         # リモートにある直近スナップショット

# 転送(--link-dest は「宛先サーバー基準の絶対パス/相対パス」で指定)
rsync -a --delete \
  --link-dest="$PREV" \
  -e ssh "$SRC/" "${HOST}:${TARGET}"

# latest を新しいスナップショットへ付け替え
ssh "$HOST" ln -sfn "$TARGET" "$PREV"

--link-dest は「宛先側のパス」を指定します。相対なら 宛先ディレクトリからの相対

自動化テンプレ(cron+排他+ログ)

# /usr/local/sbin/rsync_push.sh
#!/usr/bin/env bash
set -euo pipefail
SRC="/var/www/app"
DST="prod:/srv/app/shared"
EXC="/etc/rsync/exclude.txt"
LOG="/var/log/rsync_push.log"

flock -n /tmp/rsync_push.lock -c "
  rsync -a -z -P --delete --exclude-from=\"$EXC\" \
    \"$SRC/\" \"$DST\" >>\"$LOG\" 2>&1
"
crontab -e
# 毎日 02:20 に実行(メール通知不要なら MAILTO= 空)
MAILTO=""
20 2 * * * bash /usr/local/sbin/rsync_push.sh

速度・安定性チューニング

  • ローカル高速化-W/--whole-file(差分計算を省略、同一ホスト間で有効)
  • 途中再開-P --partial-dir=.rsync-partial
  • 削除の安全性--delete-delay(削除は最後にまとめて)
  • 大規模同期--exclude-from で一時ファイルやビルド生成物を省く
  • ネットワーク負荷--bwlimit=5m、業務時間外の cron 実行

安全運用チェックリスト

  • ✅ 本番前に --dry-run --itemize-changes
  • 末尾スラッシュの意味を固定運用(常に SRC/
  • ✅ 初回は --delete を付けず挙動を確認
  • ✅ 除外リストは ファイル管理(リポジトリで共有)
  • ✅ 復元テスト(たまに逆向き rsync で戻せるか検証)
  • .ssh は権限厳密に:chmod 700 ~/.ssh; chmod 600 ~/.ssh/id_ed25519

双方向の自動マージが必要なら rsync ではなく Unison / Syncthing などのツールを検討。

トラブル対処

  • 「消えた!」--delete の対象だった可能性。必ずドライラン&バックアップを。
  • 権限が崩れる--numeric-ids、ACL/拡張属性は -A -X、宛先FSの対応を確認。
  • SSH が落ちるServerAliveIntervalClientAliveInterval を設定。
  • macOS でオプションが使えない → Homebrew の rsync 3.x を利用。
  • 大容量で遅い → 除外の見直し、-W、帯域制限、夜間実行。

まとめ

  • rsync over SSH は「安全・高速・省コスト」の三拍子。
  • 運用の肝は ドライラン→本番末尾スラッシュ除外とログ定期同期
  • 履歴が必要なら --link-dest スナップショットで“軽い世代管理”。

このページのレシピをコピペして、今日から 事故らないサーバー同期 を始めましょう。

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント