😽
DockerでSTFP検証用のコンテナを用意し、LaravelでSFTPをする
各バージョン
PHP 7.4
Laravel 8.47.0
macOS Catalina
Docker 20.10.6
docker-compose 1.29.1
docker-composeファイルに以下の内容を追加します。
まずはパスワード認証でSFTPを使用するための設定になります。
公開鍵認証で接続する設定は記事の後半に書いています。
docker-compose.yml
version: '3'
services:
...
sftp-server:
image: atmoz/sftp
container_name: sftp-server
volumes:
- ./sftp-server/files:/home/user/files
ports:
- "2222:22"
command: "user:password:::files"
※ PHP や nginx のコンテナの記述は省略しています。
Dockerイメージは atmoz/sftp を使用しています。
commandでは、user
というユーザーを作成しパスワードを password
にし、files
というディレクトリを作成しています。
volumesでは、指定のローカルディレクリをマウントしています。
そうすることで、開発時にファイルの転送後、問題なく転送されたかを確認しやすくなります。
LaravelでSFTPの設定を行う
LaravelでSFTPを行うために必要なライブラリをインストールします。
composer require league/flysystem-sftp
AppServiceProvider.phpのboot()メソッドに以下の内容を追加します。
app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use League\Flysystem\Sftp\SftpAdapter;
...
public function boot()
{
Storage::extend('sftp', function ($app, $config) {
return new Filesystem(new SftpAdapter($config));
});
}
ディスクの設定を追加します。
config/filesystems.php
'disks' => [
//
'sftp' => [
'driver' => 'sftp',
'port' => env('SFTP_PORT'),
'host' => env('SFTP_HOST'),
'username' => env('SFTP_USER'),
'password' => env('SFTP_PASSWORD'),
'root' => env('SFTP_ROOT'),
'timeout' => 10,
],
],
.envに以下の内容を追加します。
.env
SFTP_PORT=22
SFTP_HOST=sftp-server
SFTP_USER=user
SFTP_PASSWORD=password
SFTP_ROOT=files
動作テスト
$ php artisan tinker
>>> Storage::disk('sftp')->put('hello.txt', 'Hello World.');
// ./sftp-server/filesにhello.txtが転送されているはずです。
>>> Storage::disk('sftp')->get('hello.txt');
=> "Hello World."
今までの設定は、パスワード認証になります。
公開鍵認証の設定は以下になります。
ホスト側で認証用の公開鍵、秘密鍵を作成します。
docker-compose.ymlの同階層で下のコマンドを行います。
$ mkdir .ssh && cd .ssh
$ ssh-keygen -t rsa -b 4096 -N "" -f sftp_rsa
docker-compose.yml
version: '3'
services:
app: //PHP/Laravelで使用するコンテナ
volumes:
- ./.ssh/sftp_rsa:/root/.ssh/sftp_rsa
sftp-server:
volumes:
- ./.ssh/sftp_rsa.pub:/home/user/.ssh/keys/sftp_rsa.pub
ディスクの設定を以下に変更します。
config/filesystems.php
'disks' => [
//
'sftp' => [
- 'password' => env('SFTP_PASSWORD'),
+ 'privateKey' => env('SFTP_PRIVATEKEY'),
],
],
.envを以下の内容に変更します。
.env
- SFTP_PASSWORD=password
+ SFTP_PRIVATEKEY=/root/.ssh/sftp_rsa
動作テスト
$ php artisan tinker
>>> Storage::disk('sftp')->get('hello.txt');
=> "Hello World."
Discussion