hello-world
webエンジニアのメモ。とりあえずやってみる。

PHPからrsyncを実行する

公開日時

「stg環境でアップロードしたファイルを、本番環境へ反映する管理機能が欲しい」という要望があった場合、同一サーバ内であればcpコマンドでファイルをコピーできますが、stg環境と本番環境が分かれている場合はrsyncコマンドでファイルを転送する必要があります。

しかし、Apache + PHP の構成で管理画面が作成されている場合、管理画面から上記の機能を実行するとapacheユーザとして実行されてしまい、正しく動作しません。

apacheユーザからsudoで別ユーザとしてrsyncを実行するようにすることで正しく動作させることができます。

前提条件

  • stg環境のログインユーザ:stg
  • 本番環境のログインユーザ:prod

  • stg環境のアップロードディレクトリ:/var/www/stg/uploads
  • 本番環境のアップロードディレクトリ:/var/www/prod/uploads

1. sshキーを作成する

本番環境にrsyncするためにsshキーを作成します。

以下のコマンドをstg環境で実行します。

Nオプションでパスフレーズをなしにしています。

ssh-keygen -N "" -t rsa

/home/stg/.ssh に

  • id_rsa
  • id_rsa.pub

が生成されているので、id_rsa.pub の内容を、本番環境の /home/prod/.ssh/authorized_keys に追記します。

sshディレクトリの権限は以下のようにしておきます

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

以上の設定が終わったら、stg環境から

ssh prod@{ホスト名}

で本番環境にアクセスできることを確認します。

2. apacheユーザがrsyncをsudo実行できるようにする

  • rsyncコマンドのパスを確認
which rsync
#/usr/bin/rsync
  • visudoを編集してapacheユーザがrsyncのみパスワードなしでsudo実行できるようにします
sudo visudo

#Defaults    requiretty   # コメントアウト

# 2013/9/4 ALL=(ALL)をALL=(stg)に修正 
# ALL=(ALL)だとroot実行可能なのでstgユーザの権限でのみ実行するように
apache  ALL=(stg) NOPASSWD: usr/bin/rsync  # 追記

3. PHPからrsyncを実行するようにする

PHPからシェルコマンドを実行したい場合は、shell_exec関数を使います

管理画面でボタンが押されたら下記コマンドを実行するようにします

shell_exec("sudo -u stg rsync -avr --exclude '.git' --exclude '.svn' --exclude '**/.svn' --delete /var/www/stg/uploads/ prod@{ホスト名}:/var/www/prod/uploads/");

これで、 stg環境の /var/www/stg/uploads/ 以下のファイルが本番環境の /var/www/prod/uploads/ 以下に同期されます。

参考


Related #apache

[apache].htaccessで日付と時間に応じてリダイレクトさせる

apache使用時に、ある時間になるまでは特定の階層以下にアクセスできないようにしたい場合、RewriteCondに時間を指定することで実現できました。

[apache]cronで指定時刻になったら.htaccessのbasic認証を解除する

cronを使って指定時間になったらbasic認証を解除したいと思い調べてやってみました。