dockerでSFTPサーバーを作成し、Pythonで作成した一時ファイルをアップロードしてみた
データアナリティクス事業本部のueharaです。
今回はdockerイメージからSFTPサーバーを作成し、Pythonで一時ファイルの作成・ファイルのアップロードを行うという検証をしてみたいと思います。
SFTPじゃなくてFTPが知りたい!って方は以下の記事をご参考下さい。
dockerによるSFTPサーバーの構築
SFTPのdockerイメージは atmoz/sftp を利用したいと思います。
dockerイメージのダウンロード
以下のコマンドを実行し、イメージのダウンロードを行います。
docker pull atmoz/sftp
コンテナの起動
イメージの用意ができたら、 docker-compose.yml
ファイルを作成します。
version: '3' services: sftp: image: atmoz/sftp container_name: sftp-test # docker-compose.ymlがあるディレクトリに、コンテナとの共有ディレクトリを作る volumes: - ./data:/home/testuser/data ports: - "2222:22" command: testuser:test123:::data
今回はあくまでローカル環境での検証を目的としているため、ユーザー名は testuser
、パスワードは test123
としています。
コンテナ側の22番ポートには、ホスト側の 2222
番を割り当てます。
コンテナとの共有ディレクトリについても、 docker-compose.yml
を置くディレクトリと同じ階層としています。
docker-compose.yml
の準備が完了したら、 docker-compose.yml
があるディレクトリでdocker-compose upを実行し、コンテナを起動します。
docker-compose up
コンテナを起動すると、ホスト側に共有ディレクトリが作成され、以下のようになっているかと思います。
. ├ data └ docker-compose.yml
以上でSFTPサーバーの構築は完了です。
PythonによるSFTPサーバーへのアクセス
接続先情報の準備
今回、接続先情報は別ファイルで管理し、Pythonの標準モジュールであるconfigparserで読み込む形としたいと思います。
先程 docker-compose.yml
で設定した接続情報を、 config.ini
に書き起こしてみます。
[sftp] host = localhost port = 2222 username = testuser password = test123
PythonでのSFTPサーバーへのアクセス
Pythonを利用して、一時ファイルを作成し、それをSFTPでアップロードしてみたいと思います。
全体のコードとしては以下の通りです。
import configparser import tempfile import paramiko # config.iniの読み取り config = configparser.ConfigParser() config.read("config.ini", encoding="utf-8") # 接続するためのSSHクライアントの準備 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy) # 接続先情報を設定して接続 client.connect( cofig["sftp"]["host"], port=int(cofig["sftp"]["port"]), username=cofig["sftp"]["username"], password=cofig["sftp"]["password"] ) # セッション開始 sftp = client.open_sftp() # 一時ファイルを作成してアップロード with tempfile.NamedTemporaryFile(mode="w", encoding="utf8") as tmpf: tmpf.write("This is test file.\n") tmpf.flush() sftp.put(tmpf.name, "/data/test.txt") sftp.close() client.close()
SFTPのクライアントとしては、 Paramiko を利用しています。
ParamikoのSSH Clientに関してはこちらのドキュメントに記載がありますが、 open_sftp()
でSFTP client objectを取得することができます。
一時ファイルの作成には、Pythonの標準モジュールである tmpfile を利用しています。こちらは、一時ファイルやディレクトリを作成する際に非常に便利なモジュールです。
特に tempfile.NamedTemporaryFile()
は一時ファイルのpathが取得できるのが特徴です。
1つ注意点として、WindowsだとNamedTemporaryFileで一時ファイルを開いている状態で、その名前を使用して再度ファイルを開くことができません(UNIX系のシステムであれば問題なし)。
その場合でも、以下のように記載をすることができます。
with tempfile.NamedTemporaryFile(mode="w", encoding="utf8", delete=False) as tmpf: tmpf.write("This is test file.\n") tmpf_name = tmpf.name sftp.put(tmpf_name, "/data/test.txt")
上記プログラム sftp_test.py
を実行後、ホスト側の共有ディレクトリである data
に、 test.txt
がアップロードされていれば成功です。
. ├ data └ test.txt └ docker-compose.yml
This is test file.
最後に
今回はdockerイメージからSFTPサーバーを作成し、Pythonで一時ファイルの作成・アップロードを行うといった検証をしてみました。
参考になりましたら幸いです。