サービス連携の用途でSFTPをプログラムから利用することがあると思いますが、今回はDockerコンテナを使ってSFTP開発環境の作り方を紹介します。
docker-compose.ymlはこんな感じで記述します。
version: '3'
services:
sftp:
image: atmoz/sftp
volumes:
- /path/to/server-repo/.ssh/id_rsa.pub:/home/foo/.ssh/keys/id_rsa.pub:ro # sync publick key for authorized_keys
- /path/to/upload:/home/foo/upload # sync upload directory
- etc_ssh:/etc/ssh
ports:
- "2222:22"
command: "foo:pass:::upload"
volumes:
etc_ssh:
driver: local
まず、Dockerイメージは atmoz/sftp を使います。このイメージはコマンドにコロン区切りの文字列を指定することでSFTPの各種設定が可能になります。
上記のcommandの場合、foo
というユーザを作成しパスワードはpass
でuploadディレクトリを作成する、という感じです。
一番上の共有設定(id_rsa.pubの共有)はアプリケーションが利用する秘密鍵に対応する公開鍵をSFTPコンテナと共有しています。これによってアプリケーション側から公開鍵認証を使ってSFTPサーバに接続できます。
二番目のuploadディレクトリの共有はSFTPサーバにアップロードされたファイル群をホスト側で確認したり、逆にSFTPからダウンロードするアプリケーションの場合は、SFTPサーバに事前にファイルをホスト側からアップロードするために共有しています。この設定は必須ではないのですが、テスト時はホスト側でファイルの入出力を見れたほうが便利なのでこのような設定を入れています。
最後の共有はSSHホストの秘密鍵・公開鍵をボリュームコンテナで永続化しています。永続化しない場合、コンテナは秘密鍵を起動時に自動で生成してしまいます。自動で生成する分には問題なく動くのですが、当然ながらコンテナを立ち上げる度に違う秘密鍵を生成することになり、公開鍵も変わってきます。そうするとknown_hostsで記録した公開鍵も変わってくるため、known_hostsを書き換える等しない限りはSSHで接続ができなくなります。この自動生成は既に同名のファイルが存在する場合は生成しないようになっているので、ボリュームコンテナで永続化するか、予めホスト側で作成しておいてそれをコンテナと共有するようにすれば解決します。
これでDockerコンテナを立ち上げれば、docker-compose内にアプリケーションが起動している場合は、sftp
のホスト名でアクセスでき、ローカルで別にアプリケーションを立ち上げている場合はlocalhost:2222
でアクセスできます。