😽

DockerでSTFP検証用のコンテナを用意し、LaravelでSFTPをする

2021/07/05に公開

各バージョン

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 を使用しています。
https://hub.docker.com/r/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