問題現象
- Mattermost のホストを引っ越ししようとデータ移管したが、過去に投稿された画像の多くが表示されず、読み込み待ち表示や空表示となってしまった。
- 一部の画像は問題なく表示されている。
- 正しく表示されない画像の URI もデータ移管先の API から取得しようとしている。
環境
移行元
- Windows Server 2016 + Docker for Windows 18.06.1-ce
- Mattermost V4.5.1
- Docker Image: mattermost/mattermost-preview
- Mattermost のデータは Docker コンテナのボリュームを Windows のファイルシステムにマウント して永続化
- GNU tar 1.30 (git for Windows V2.19.0 に同梱の tar)
- データ移管時に使用
移行先
- Debian 9.5 + Docker 18.06.1-ce
- Mattermost V5.3.1
- Docker Image: mattermost/mattermost-preview(同上)
- GNU tar 1.29
データ移管作業
- Windows フォルダ配下にファイルとして永続化されたデータ(mattermost-data, mysql)をアーカイブしてデータ移行先へ転送。
- Windows 標準の機能で zip ファイルにアーカイブしようとしたが、扱えないファイル名があるとのエラーが出て失敗。
- 代わりに、Windows 上で GNU tar コマンドを使って tar.gz ファイルにアーカイブ。特に、エラーや警告はなし。
- 移行先では Docker コンテナのボリュームをマウントした Windows フォルダ配下に tar.gz ファイルを展開してデータ復元。
原因
-
Mattermost でメッセージに画像を Ctrl+V で貼り付けた場合、そのデータを永続化するファイルの名前が「画像の貼り付け先: ~」となり、Windows ファイルシステムでの禁則文字
:
を含んでしまっている。 -
Windows ファイルシステム上のファイル名として
:
は禁則文字だが、Docker コンテナ内では:
を含むファイル名も作成でき、かつ、 Docker コンテナのボリュームを Windows ファイルシステムにマウントしている場合でも、Docker コンテナ内からは:
を含むファイル名で扱えてしまう。 -
Windows 側から該当ファイルを見ると、ファイル名中の
:
が別の文字
に置き換えられて見える。それを GNU tar でアーカイブするとその文字が文字化けしてアーカイブされてしまう。
対策
-
Docker コンテナ内でボリュームをアーカイブする。
- Docker コンテナの Shell に接続
- コンテナ内の Shell で tar コマンドを実行してボリューム上のファイル一式をアーカイブ
PS> docker exec -it <container_name> /bin/bash bash> (cd /mm/mattermost; tar cf /tmp/mattermost-volumes.tar config/ mattermost-data/) bash> (cd /var/lib; tar rf /tmp/mattermost-volumes.tar mysql/) bash> gzip /tmp/mattermost-volumes.tar bash> ^C PS> docker cp <container_name>:/tmp/mattermost-volumes.tar.gz .
わかってしまえば対策は簡単だが、Docker for Windows のボリュームマウントでは Windows ファイルシステムでの禁則文字を含むファイル名でも保存できてしまうとは想像していなかった。
参考(ベストプラクティス)
あとから調べてみると、Docker コンテナのボリュームをバックアップするには、 --volumes-from
を使ってバックアップ処理用の Data Volume Container を横付けし、そのコンテナ内からアーカイブするのがベストプラクティスのようです。
- Backup, restore, or migrate data volumes - docker docs
- Dockerのシステム移行手順(バックアップおよび復元方法)
- Docker の Data Volume まわりを整理する
Data Volume Container は知っていたのですが、コンテナ内からアーカイブすべき理由を身をもって理解できました。
以上