Docker による Windows における Linux 環境の整備2015年10月31日 | |
はじめにDocker を使って Windows 上で Linux 環境を整備する方法について。 バージョンDocker Toolbox 1.8.3, Windows 7 64 bit ファイル
DockerDocker は、コンテナ型仮想化技術の一つである。VirtualBox のようなハードウェアレベルの仮想化と異なり、コンテナ型ではホスト OS とゲスト OS がカーネルを共有しているため、仮想化のオーバーヘッドが少なくて済むと言われている。 Docker を Windows で使うためのソフトとして Docker Toolbox がある。Docker はもともと Linux の技術なので、VirtualBox で Linux の仮想マシンを動かして、仮想マシン越しに Docker を利用するようになっている。 Docker Toolsここ から Docker Tools のインストーラをダウンロードする。ふつうにインストールすればよい。デスクトップに "Docker Quickstart Terminal" というアイコンができるので、これを実行すると、コマンドラインが起動する。 ![]() Docker Toolbox では、Docker を利用するために VirtualBox で Linux の仮想マシンを動かしている。VirtualBox を起動してみれば、こっそり仮想マシンが動いているのがわかる。 ![]() ※最初に実行したとき、"Starting VM..." というメッセージから進まなくなった。ウインドウを閉じて、VirtualBox の仮想マシンを落として再度実行したらうまくいった。 以下のコマンドを打ってみてエラーが出なければ OK。 $ docker version Client: Version: 1.8.3 API version: 1.20 Go version: go1.4.2 Git commit: f4bf5c7 Built: Mon Oct 12 18:01:15 UTC 2015 OS/Arch: windows/amd64 Server: Version: 1.8.3 API version: 1.20 Go version: go1.4.2 Git commit: f4bf5c7 Built: Mon Oct 12 18:01:15 UTC 2015 OS/Arch: linux/amd64 作業はこのまま Windows のコマンドラインで行う方法と、仮想マシンに入って行う方法がある。仮想マシンに入るには以下のようにする。 $ docker-machine ssh default ここで "default" はマシン名である。どういうマシンがあるかは次のように調べる。 $ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM default * virtualbox Running tcp://192.168.99.100:2376 コンテナの実行コンテナを実行するには、コンテナのもとになるイメージが必要である。イメージは多数公開されている。たとえば Ubuntu のイメージをダウンロードするには、以下のようにする。 $ docker pull ubuntu:14.04 ここで ":14.04" はタグで、バージョンを指定している。タグを指定してしなければ ":latest" (最新版) が指定される。"docker images" でイメージのリストを表示できる。 $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 14.04 0a17decee413 12 days ago 188.4 MB コンテナを実行してみよう。 $ docker run ubuntu:14.04 ls -l total 64 drwxr-xr-x 2 root root 4096 Oct 9 08:39 bin drwxr-xr-x 2 root root 4096 Apr 10 2014 boot drwxr-xr-x 5 root root 360 Oct 25 06:50 dev drwxr-xr-x 64 root root 4096 Oct 25 06:50 etc drwxr-xr-x 2 root root 4096 Apr 10 2014 home drwxr-xr-x 12 root root 4096 Oct 9 08:38 lib drwxr-xr-x 2 root root 4096 Oct 9 08:38 lib64 drwxr-xr-x 2 root root 4096 Oct 9 08:38 media drwxr-xr-x 2 root root 4096 Apr 10 2014 mnt drwxr-xr-x 2 root root 4096 Oct 9 08:38 opt dr-xr-xr-x 127 root root 0 Oct 25 06:50 proc drwx------ 2 root root 4096 Oct 9 08:39 root drwxr-xr-x 7 root root 4096 Oct 9 08:38 run drwxr-xr-x 2 root root 4096 Oct 12 17:27 sbin drwxr-xr-x 2 root root 4096 Oct 9 08:38 srv dr-xr-xr-x 13 root root 0 Oct 25 06:50 sys drwxrwxrwt 2 root root 4096 Oct 9 08:39 tmp drwxr-xr-x 11 root root 4096 Oct 12 17:27 usr drwxr-xr-x 12 root root 4096 Oct 12 17:27 var ls でルートディレクトリが表示されている。ちなみに、もしダウンロードしていないイメージを指定した場合、ダウンロード可能であれば勝手にダウンロードされる。 ふつうの Linux のようにログインすることもできる。 $ winpty docker run -it ubuntu:14.04 bash root@d07fdf761298:/# ls -l total 64 drwxr-xr-x 2 root root 4096 Oct 9 08:39 bin drwxr-xr-x 2 root root 4096 Apr 10 2014 boot drwxr-xr-x 5 root root 380 Oct 25 06:54 dev drwxr-xr-x 64 root root 4096 Oct 25 06:54 etc drwxr-xr-x 2 root root 4096 Apr 10 2014 home drwxr-xr-x 12 root root 4096 Oct 9 08:38 lib drwxr-xr-x 2 root root 4096 Oct 9 08:38 lib64 drwxr-xr-x 2 root root 4096 Oct 9 08:38 media drwxr-xr-x 2 root root 4096 Apr 10 2014 mnt drwxr-xr-x 2 root root 4096 Oct 9 08:38 opt dr-xr-xr-x 128 root root 0 Oct 25 06:54 proc drwx------ 2 root root 4096 Oct 9 08:39 root drwxr-xr-x 7 root root 4096 Oct 9 08:38 run drwxr-xr-x 2 root root 4096 Oct 12 17:27 sbin drwxr-xr-x 2 root root 4096 Oct 9 08:38 srv dr-xr-xr-x 13 root root 0 Oct 25 06:50 sys drwxrwxrwt 2 root root 4096 Oct 9 08:39 tmp drwxr-xr-x 11 root root 4096 Oct 12 17:27 usr drwxr-xr-x 12 root root 4096 Oct 12 17:27 var root@d07fdf761298:/# exit exit $ ここでオプション "-i" はインタラクティブモード、"-t" は TTY の指定である。はじめの winpty は TTY を使うためのものである。もし仮想マシンに入って作業をする場合は、winpty は必要ない。 注目すべき点は、VirtualBox で仮想マシンを動かすのとは異なり、Ubuntu の起動の手順が不要なことである。注意すべき点は、コンテナは一時的な環境なので、コンテナ内で作業した内容は永続せず、コンテナを破棄した時点で消滅することである。 コンテナの情報コンテナの情報を得るには "docker ps" を用いる。 $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a271558fd737 ubuntu:14.04 "bash" 15 seconds ago Exited (0) 12 seconds ago pensive_davinci aaa8be548bc4 ubuntu:14.04 "ls -l" 29 seconds ago Exited (0) 29 seconds ago elated_davinci オプション "-a" で終了したコンテナも含めて表示する。オプション "-q" で ID だけ表示される。 $ docker ps -qa a271558fd737 aaa8be548bc4 最後に実行したコンテナ ID を得るには、次のようにする。 $ docker ps -ql コンテナ情報は、一見するとコンテナの「実行履歴」のように見えるが、そうではない。コンテナはイメージをもとにコマンドとセットで作成され、実行される。ここで表示されているものは、実行を終了しているものも含めて実体を持ったもので、コンテナ内で作業した内容を保持しているし、実行を再開することもできる。 コンテナの実行の再開コンテナの実行を終了すると、STATUS が "Exited" になるが、コンテナ自体はまだ存在しており、再度実行することができる。実行には "docker start <ID>" を用いる。 $ winpty docker run -it ubuntu:14.04 bash root@1315d9e96a4a:/# touch test root@1315d9e96a4a:/# ls bin dev home lib64 mnt proc run srv test usr boot etc lib media opt root sbin sys tmp var root@1315d9e96a4a:/# exit exit $ docker start `docker ps -ql` 1315d9e96a4a $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1315d9e96a4a ubuntu:14.04 "bash" 43 seconds ago Up 14 seconds trusting_bhaskara STATUS で再開したのはわかるが、bash には戻っていない。bash に (コンテナに) 戻るには "docker attach <ID>" を用いる。 $ winpty docker attach `docker ps -ql` root@1315d9e96a4a:/# ls bin dev home lib64 mnt proc run srv test usr boot etc lib media opt root sbin sys tmp var 作成したファイル "test" はちゃんと残っている。 逆に、コンテナを止めずにコンテナから出るには、Ctrl+P, Ctrl+Q と入力すればよい。 $ winpty docker attach `docker ps -ql` root@1315d9e96a4a:/# (ここで Ctrl+P, Ctrl+Q と入力) $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1315d9e96a4a ubuntu:14.04 "bash" 6 minutes ago Up 6 minutes trusting_bhaskara コンテナの停止と削除コンテナの停止には "docker stop <ID>" を用いる。コンテナの削除には "docker rm <ID>" を用いる。 すべてのコンテナを削除したい場合は、次のようにすればよい。 docker stop `docker ps -qa` docker rm `docker ps -qa` コンテナ実行時にオプション "--rm" を付けておくと、コンテナは終了時に自動的に削除される。 コンテナ名の設定コンテナを指定する場合、ID は使いにくい。そのため、コンテナに名前を付けることができる。オプション "--name" を使う。 $ winpty docker run --name myubuntu -it ubuntu:14.04 bash root@a2c20bf18851:/# exit exit $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a2c20bf18851 ubuntu:14.04 "bash" 17 seconds ago Exited (0) 15 seconds ago myubuntu 上で見てきたコンテナ情報を見ると、それぞれのコンテナに勝手な名前が付けられていたことがわかる。"--name" はこれを任意の名前にできるわけである。同じ名前のコンテナを作ることはできないので、いろいろやっているうちにコンテナが大量に作成されるのが嫌な場合は、コンテナに名前を付けてしまえばよい。 Docker 仮想マシンが終了した場合のコンテナの扱いDocker 仮想マシンが終了してもコンテナは消えず、仮想マシンを起動したらまた扱える。ただし、コンテナは終了した状態になっているので、再開させる必要がある。 イメージの作成自分のイメージを作成する場合は、Dockerfile というファイルを用意する。もっとも簡単なものは、以下のようなものだろう。 FROM ubuntu:14.04 MAINTAINER Yuu Kasuga ここで "FROM" はもとにするイメージの指定、"MAINTAINER" はメンテナの名前の指定である。Dockerfile があるディレクトリで、次のようにイメージを作成する。 $ docker build -t myubuntu . ここで "myubuntu" のところは好きな名前 (およびタグ) を指定する。うまく行ったら、イメージリストに表示されるはずである。 $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE myubuntu latest 9c766eb34f04 20 seconds ago 188.4 MB ubuntu 14.04 0a17decee413 12 days ago 188.4 MB 注意: 最初に "Sending build context to Docker daemon ..." というメッセージが出るが、これはカレントにあるファイルをすべて Docker daemon に送っているそうで、うっかり大きなファイルをその辺に置いといたりすると延々とデータを送り続けるので、気を付けること。 "docker build" は Dockerfile のコマンドごとに結果をキャッシュしており、Dockerfile の部分的な修正に対して、変更されていない部分にはキャッシュを適用する。そのため、再実行は高速である。ただし、キャッシュが効かなくなるのは Dockerfile の修正された箇所だけではなくて、修正された箇所以降すべてである。したがって、プログラムのインストールなど、時間がかかるものは最初のほうに書いたほうがよいかもしれない。 参考 ユーザーの作成ユーザーを作成したい場合は、Dockerfile に次のように追加する。 RUN useradd -s /bin/bash -m penguin RUN echo penguin:penguin | chpasswd RUN usermod -G sudo penguin "RUN" はイメージ作成時にコマンドを実行させるものである。実行させたい Linux コマンドをそのまま書けばよい。上の例では、1 行目でユーザーを作成、2 行目でパスワードの設定 ("名前:パスワード" の形式)、3 行目で sudo できるように sudo グループに追加している。 ただ、このまま実行しても root で実行されてしまう。ユーザーを指定するには、コンテナ起動時にオプション "-u" でユーザーを指定する。 $ winpty docker run -u penguin -it myubuntu bash penguin@34717bbe999c:/$ pwd / ルートディレクトリから始まってしまう。ふつうの Linux のようにログインした状態で始まりたい。その場合、Dockerfile で作業ディレクトリを指定する。 WORKDIR /home/penguin ただし、作業ディレクトリを指定した後の "RUN" はその作業ディレクトリで実行されることに注意。 実行すると、ホームディレクトリから始まる。 $ winpty docker run -u penguin -it myubuntu bash penguin@8bfaead642b9:~$ pwd /home/penguin ユーザーは Dockerfile で指定することもできる。 USER penguin ただし、ユーザーを指定した後の "RUN" はそのユーザーで実行されることに注意。 ホスト名の指定せっかくなのでホスト名も指定したい。ホスト名の指定は、コンテナ実行時にオプション "-h" で行う。 $ winpty docker run -u penguin -h penguin-machine -it myubuntu bash penguin@penguin-machine:~$ だいぶそれっぽくになってきた。 コマンドの指定コンテナ実行時にコマンドを指定しているが、この指定を Dockerfile で行うこともできる。 CMD ["ls", "-la"] コマンドなしで実行すると、ls が起動する。 $ winpty docker run -u penguin -h penguin-machine -it myubuntu total 20 drwxr-xr-x 2 penguin penguin 4096 Oct 25 07:29 . drwxr-xr-x 3 root root 4096 Oct 25 07:29 .. -rw-r--r-- 1 penguin penguin 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 penguin penguin 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 penguin penguin 675 Apr 9 2014 .profile コマンドラインのほうでコマンドを指定すると、そちらが使われる。 $ winpty docker run -u penguin -h penguin-machine -it myubuntu bash penguin@penguin-machine:~$ 複数のコマンドを実行したい場合は、スクリプトを渡せばよい。たとえば、次のようなスクリプトを用意する。 script.sh #!/bin/sh pwd ls -la Dockerfile に次のように書く。 ADD ./script.sh /tmp/script.sh RUN chown penguin:penguin /tmp/script.sh RUN chmod +x /tmp/script.sh WORKDIR /home/penguin CMD ["/tmp/script.sh"] ここで、"ADD" はファイルをコンテナに渡す指示である。 $ winpty docker run -u penguin -h penguin-machine -it myubuntu /home/penguin total 20 drwxr-xr-x 2 penguin penguin 4096 Oct 25 07:29 . drwxr-xr-x 3 root root 4096 Oct 25 07:29 .. -rw-r--r-- 1 penguin penguin 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 penguin penguin 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 penguin penguin 675 Apr 9 2014 .profile Windows フォルダの共有コンテナではデータは永続しないので、必要なデータを Windows 側にもっていく手段が必要である。Windows のフォルダをコンテナから見えるようにするには、以下のようにする。 まず、Dockerfile で Windows フォルダを共有するためのディレクトリを作成する。 RUN mkdir /home/penguin/user RUN chown penguin.penguin /home/penguin/user コンテナ実行時にフォルダの共有を指定する。 $ winpty docker run -u penguin -h penguin-machine -v /c/Users/`whoami`:/home/penguin/user -it myubuntu オプション "-v" で Windows 側とコンテナ側のディレクトリを指定している。ほんとうはこれで上手くいきそうなのだが、Docker Toolbox がコマンドラインとして使っている MinGW がパスを変換してしまうため、それを抑えるために次のようにする。 $ winpty docker run -u penguin -h penguin-machine -v //c/Users/`whoami`:/home/penguin/user -it myubuntu これでもうまく行かなくて、結局つぎのようにすればうまくいく。 run #!/bin/sh docker run -u penguin -h penguin-machine -v //c/Users/`whoami`:/home/penguin/user -it myubuntu 実行 $ winpty sh run penguin@penguin-machine:~$ ls user ... 参考 コミットコンテナに対する修正結果をイメージに適用することができる。それには "docker commit <ID>" を用いる。 たとえば、コンテナにファイルを追加する。 $ winpty sh run penguin@penguin-machine:~$ ls user penguin@penguin-machine:~$ touch file penguin@penguin-machine:~$ ls file user そのまま再実行しても、ファイルは消える。 $ winpty sh run penguin@penguin-machine:~$ ls user コンテナにファイルを追加した直後、次のようにする。 $ docker commit `docker ps -ql` myubuntu このあと実行すると、ファイルが追加されている。 $ winpty sh run penguin@penguin-machine:~$ ls file user イメージの削除イメージを削除するには、"docker rmi <image>" を用いる。ふつうはイメージを使用しているコンテナを先に停止・削除してから行う。 イメージを作成する過程で、次のように失敗したものが無名で残る場合がある。 $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE myubuntu latest 62a361974965 7 minutes ago 188.7 MB <none> <none> 72280c94523f 9 minutes ago 188.7 MB <none> <none> cb568cba0c4a 15 minutes ago 188.7 MB <none> <none> ec605e8e590d 16 minutes ago 188.7 MB <none> <none> 5ab94691159a 21 minutes ago 188.7 MB <none> <none> d60c1a716ef2 21 minutes ago 188.7 MB <none> <none> 6432ea58d388 24 minutes ago 188.7 MB <none> <none> 34f21cdfe2a4 35 minutes ago 188.7 MB <none> <none> e5ab9efefebe 36 minutes ago 188.7 MB ubuntu 14.04 0a17decee413 12 days ago 188.4 MB これらを削除するには、次のようにすればよい。まず、"<none>" を含む行だけ取り出す。 $ docker images | grep "<none>" <none> <none> 72280c94523f 9 minutes ago 188.7 MB <none> <none> cb568cba0c4a 15 minutes ago 188.7 MB <none> <none> ec605e8e590d 16 minutes ago 188.7 MB <none> <none> 5ab94691159a 21 minutes ago 188.7 MB <none> <none> d60c1a716ef2 21 minutes ago 188.7 MB <none> <none> 6432ea58d388 24 minutes ago 188.7 MB <none> <none> 34f21cdfe2a4 35 minutes ago 188.7 MB <none> <none> e5ab9efefebe 36 minutes ago 188.7 MB 3 列目だけ欲しいので、awk で 3 列目だけ取り出す。 $ docker images | grep "<none>" | awk '{print $3}' 72280c94523f cb568cba0c4a ec605e8e590d 5ab94691159a d60c1a716ef2 6432ea58d388 34f21cdfe2a4 e5ab9efefebe これを "docker rmi" に渡せばよい。 $ docker rmi -f `docker images | grep "<none>" | awk '{print $3}'` ここでオプション "-f" は強引に消すためのものである。 イメージの保存と復元イメージを保存するには、次のようにする。 $ docker save image > filename.tar 保存したイメージを復元するには、次のようにする。 $ docker load < filename.tar テストすると、以下のとおりである。 $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE myubuntu latest 1b514a102904 About an hour ago 231 MB ubuntu 14.04 0a17decee413 12 days ago 188.4 MB $ docker save myubuntu > myubuntu.tar $ docker rmi myubuntu ... $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 14.04 0a17decee413 12 days ago 188.4 MB $ docker load < myubuntu.tar $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE myubuntu latest 1b514a102904 About an hour ago 231 MB ubuntu 14.04 0a17decee413 12 days ago 188.4 MB gzip を使うこともできる。 $ docker save image | gzip > filename.tar.gz 復元は tar の場合と同じである。 $ docker load < filename.tar.gz イメージの名前の変更イメージの名前 (タグ) を変えるには、"docker tag <src> <new>" を使う。 $ docker tag myubuntu myubuntu2 X を使う/SSH で接続するコンテナで X を用いたプログラムを実行したい場合は、コンテナに SSH で接続して X11 のポートフォワーディングを使えばよい。 コンテナに SSH で接続するためには、まず SSH をインストールする必要がある。Dockerfile に以下を追加する。 RUN apt-get install -y ssh apt-get で ssh をインストールしている。そしてサーバーを起ち上げるのだが、"RUN" はイメージを作る時のコマンドを指定するためのものなので、"RUN" によってサービスを開始させることはできない。そこで、最後に実行する script.sh の中に書く。 sudo service ssh start SSH で接続するために、鍵を用意する。 $ ssh-keygen -t rsa パスフレーズは設定しなくてよい。これで C:\Users\ユーザー名\.ssh に公開鍵 id_rsa.pub と秘密鍵 id_rsa が生成される。公開鍵をコンテナに設定する必要があるのだが、Windows のフォルダは見えているので、script.sh の中で設定してしまう。 script.sh #!/bin/sh sudo service ssh start mkdir /home/penguin/.ssh cat /home/penguin/user/.ssh/id_rsa.pub >> /home/penguin/.ssh/authorized_keys /bin/bash イメージを作成する。途中で apt-get が実行され、SSH がインストールされるのがわかる。 コンテナを実行するとき、オプション "-p" でポートを指定する。 docker run -u penguin -h penguin-machine -v //c/Users/`whoami`:/home/penguin/user -p 22 -it myubuntu sudo しているのでパスワードを聞かれる。パスワードが通ると、SSH のサービスが開始され、bash が実行される。 $ winpty sh run [sudo] password for penguin: [ OK ]rting OpenBSD Secure Shell server sshd penguin@penguin-machine:~$ 別のターミナルを開く ("Docker Quickstart Terminal" を実行すればよい)。今実行したコンテナの情報を表示する。 $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c612f5c4a90a myubuntu "/tmp/script.sh" 19 seconds ago Up 19 seconds 0.0.0.0:32769->22/tcp prickly_babbage "PORTS" で "0.0.0.0:32769->22/tcp" となっている。仮想マシンの IP を確認する。 $ docker-machine ip default 192.168.99.100 192.168.99.100 のポート 32769 に SSH で接続すればコンテナにつながる。 $ ssh -p 32769 penguin@192.168.99.100 The authenticity of host '[192.168.99.100]:32769 ([192.168.99.100]:32769)' can't be established. ECDSA key fingerprint is SHA256:LjKzt2jnfQz5kSWAmCdTQmEZEX05iEYN7ee7lxQptOU. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[192.168.99.100]:32769' (ECDSA) to the list of known hosts. Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.19.0-30-generic x86_64) * Documentation: https://help.ubuntu.com/ The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. penguin@penguin-machine:~$ ここでユーザー作成時にユーザーシェルを指定していない場合、sh が使われる。useradd でシェルを指定しているのはこのためである。 ポートは次のように指定することもできる。 docker run -u penguin -h penguin-machine -v //c/Users/`whoami`:/home/penguin/user -p 32779:22 -it myubuntu 指定したポートになっているのがわかる。 $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8d2b1d11180a myubuntu "/tmp/script.sh" 32 seconds ago Up 32 seconds 0.0.0.0:32779->22/tcp jolly_fermat 注意: いろいろやっているうちにエラーが出て接続できなくなることがある。その場合、~/.ssh/known_hosts を消せば解決するかもしれない。 参考: DockerコンテナのLinux GUIアプリをWindowsで起動する (Qiita) SSH サーバーのバックグラウンド実行SSH を使うことにすれば、bash を実行する必要はない。SSH サーバーだけ立てればよいのだが、かといって bash を起動しないと、コンテナがすぐに終了してしまう。これは、コンテナがフォアグラウンド実行のコマンドを前提としているからである。フォアグラウンドでじっとしてさえいればよいので、苦肉の策として、tail を使う。また、bash を使わないなら一般ユーザーで実行する必要もないので (一般ユーザーだと sudo でパスワードを聞かれるので)、ユーザー指定なしで (root で) コンテナを起動する。 docker run -h penguin-machine -v //c/Users/`whoami`:/home/penguin/user -p 32779:22 -d myubuntu script.sh #!/bin/sh service ssh start mkdir /home/penguin/.ssh cat /home/penguin/user/.ssh/id_rsa.pub >> /home/penguin/.ssh/authorized_keys chown -R penguin.penguin /home/penguin/.ssh tail -f /dev/null ここで "docker run" のオプションに "-it" ではなく "-d" を使っている。これはコンテナをバックグラウンド実行させるものである。この場合、winpty は必要ない。 参考: Dockerfileを書く時の注意とかコツとかハックとか X を使うSSH がつながったところだが、まだ X は使えない状態である。Windows で X を使うには、以下のような方法がある。
MobaXterm は X サーバー内蔵の SSH クライアントであり、これでコンテナにつなげば何の問題もなく X が使える。ここではあえて VcXsrv を用いる方法を採る。 VcXsrv は ここ から入手する。VcXsrv を起動すると、画面右下の通知領域にアイコンが表示される。それを右クリックして、"Show log" を選択する。表示されるログの中に、DISPLAY 変数の値が書いてある。 Welcome to the VcXsrv X Server Vendor: The VcXsrv Project Release: 1.17.2.0 ... winClipboardThreadProc - DISPLAY=127.0.0.1:0.0 これを環境変数に設定してから、オプション "-X" 付きで SSH を実行する。 $ export DISPLAY=127.0.0.1:0.0 $ ssh -X -p 32779 penguin@192.168.99.100 試しに xterm を入れて実行してみる。 $ sudo apt-get install xterm $ xterm ![]() Windows における Linux コマンドの実行Linux にログインしてシェル上でコマンドを実行するのではなく、Windows のコマンドラインで Linux コマンドを実行したい。SSH はもともとコマンドを実行できるし、Windows のフォルダは見えているのだから、パスを変換することでカレントのファイルに Linux コマンドを適用することが可能だろう。以下のようなスクリプトでよいかもしれない。 ssh_exec #!/bin/sh if [ $# -lt 1 ]; then echo "usage: ssh_exec <command>" exit 0 fi LOCAL_USER_DIR=/c/Users/`whoami` REMOTE_USER_DIR=/home/penguin/user PWD=`pwd | sed -e "s%$LOCAL_USER_DIR%$REMOTE_USER_DIR%"` export DISPLAY=127.0.0.1:0.0 ssh -X -p 32779 penguin@192.168.99.100 ". ~/.bashrc; cd $PWD; $*" ここで、~/.bashrc を読み込ませているのは、この中にパスなどの設定がある場合に対応するため。 テスト $ ./ssh_exec cat ssh_exec Warning: No xauth data; using fake authentication data for X11 forwarding. #!/bin/sh if [ $# -lt 1 ]; then echo "usage: ssh_exec <command>" exit 0 fi LOCAL_USER_DIR=/c/Users/`whoami` REMOTE_USER_DIR=/home/penguin/user PWD=`pwd | sed -e "s%$LOCAL_USER_DIR%$REMOTE_USER_DIR%"` export DISPLAY=127.0.0.1:0.0 ssh -X -p 32779 penguin@192.168.99.100 ". ~/.bashrc; cd $PWD; $*" 実は docker のコマンドでも同じことができる。"docker exec <container>" でコンテナにコマンドを実行させることができる。 cnt_exec #!/bin/sh if [ $# -lt 1 ]; then echo "usage: cnt_exec <command>" exit 0 fi LOCAL_USER_DIR=/c/Users/`whoami` REMOTE_USER_DIR=/home/penguin/user PWD=`pwd | sed -e "s%$LOCAL_USER_DIR%$REMOTE_USER_DIR%"` docker exec penguin-machine bash -c "~/.bashrc; cd $PWD; $*" ここで、コンテナ名を "penguin-machine" と想定している。 テスト $ ./cnt_exec cat cnt_exec bash: /home/penguin/.bashrc: Permission denied #!/bin/sh if [ $# -lt 1 ]; then echo "usage: cnt_exec <command>" exit 0 fi LOCAL_USER_DIR=/c/Users/`whoami` REMOTE_USER_DIR=/home/penguin/user PWD=`pwd | sed -e "s%$LOCAL_USER_DIR%$REMOTE_USER_DIR%"` docker exec penguin-machine bash -c "~/.bashrc; cd $PWD; $*" X を使うにはどうせ SSH を使わざるを得ないし、SSH のほうでよいかと。 パスを通すスクリプトのパスを通すには、つぎのようにする。ユーザーフォルダに .profile というファイルを以下の内容で作成する。 . ~/.bashrcまた、ユーザーフォルダの .bashrc に以下の行を追加する。 export PATH=~/docker:$PATH ここで、スクリプトの置場をユーザーフォルダの "docker" フォルダとしている。 アイコンの作成アイコンから起動できるようにする。コンテナの起動用と SSH 接続用の 2 つを作る。"Docker Quickstart Terminal" を 2 つコピーして、たとえば "run container"、"terminal" などという名前にする。 "Docker Quickstart Terminal" は "C:\Program Files\Docker Toolbox\start.sh" を bash により実行している。このファイルをコピーして "start_docker.sh" などという名前にする。エディタで開いて、最後の exec の行をコメントにし、コンテナ実行用スクリプトを指定する。 #exec "$BASH" --login -i docker/run "run container" のリンク先を "start_docker.sh" に修正する。 SSH のほうは、つぎのようなスクリプトを用意する。 start_ssh.sh #!/bin/sh set -e cd docker/ssh_container ここで ssh_container は SSH 接続用スクリプトである。 "terminal" のリンク先を "start_ssh.sh" に修正する。 コンテナの作成と再開の切り替えコンテナは最初の実行時に作成され、Docker 仮想マシンを停止しても残る。ただし、仮想マシン再起動時にはコンテナは停止しているので、再開する必要がある。したがって、パソコンを起動後コンテナを使おうとする場合、コンテナがなければ "docker run" でコンテナを作る必要があるが、すでにコンテナがあるなら "docker start" で再開させればよい。(コンテナ名が指定された) コンテナがすでにあるのに "docker run" した場合、作成に失敗する。 コンテナの作成と再会を切り替えるために、起動スクリプトを次のようにしたらよいかもしれない。 EXIST=`docker ps -a -f "name=penguin-machine" | grep penguin-machine` if [ "$EXIST" = "" ]; then echo "Create container" docker run -h penguin-machine --name penguin-machine -v //c/Users/`whoami`:/home/penguin/user -p 32779:22 -d myubuntu else echo "Start container" docker start penguin-machine fi ここではコンテナ名を "penguin-machine" としている。"docker ps" でその名前のコンテナがあるか調べて、コマンドを切り替えている。 ホームディレクトリを共有フォルダにする?ホームディレクトリに Windows 共有フォルダを置くぐらいなら、ホームディレクトリ自体を共有フォルダにしたらどうか、と思って試してみたが、SSH がスムーズにつながらなかったのでやめた。 CPU 数とメモリサイズコンテナの CPU 数とメモリサイズは、Docker 仮想マシンの設定に従う。設定を変えたい場合は、VirtualBox を起動して、仮想マシンをシャットダウンし (メニュー[仮想マシン]-[閉じる]-[ACPI シャットダウン])、[設定] の [システム] で設定を行う。 時計がずれる場合コンテナと Windows の時計がずれている場合、ずれているのは Windows のほうの時計のはずなので、Windows のほうの時計を時刻サーバーと同時させる。 Ubuntu の日本語化Ubuntu を日本語化するには、Dockerfile に次のように書く。 RUN sudo apt-get -y install language-pack-ja RUN update-locale LANG=ja_JP.UTF-8 ENV LANG ja_JP.UTF-8 参考: Ubuntu 14.04 LTS: 日本語環境にする (Server World) 参考 | |
PENGUINITIS |