sshできるdockerコンテナをつくるために最低限必要なこと

3ヶ月ぶりにDockerを触ったのですが、全てを忘れていて愕然としたので最低限必要なことをメモしておきます。 ホストOSは Mac OS X です。

Getting Started

Get Started with Docker for Mac OS X に立ち戻るのが基本です。

以下、Docker Toolbox をインストール済で、OS X のコンソールから docker コマンドを実行できる前提で。

Docker image を build する

Dockerfile を用意します。

パッケージをインストールし、 /var/run/sshd を作成するという簡単なものです。 (きちんとやるなら MAINTAINER 等書く必要あると思いますが、ここでは省いてます)

ubuntu

FROM ubuntu:14.04

RUN apt-get update && apt-get -y upgrade && apt-get install -y build-essential libssl-dev libreadline-dev zlib1g-dev language-pack-ja
RUN apt-get -y install openssh-server ufw curl
RUN mkdir /var/run/sshd

debian

FROM debian:wheezy

RUN apt-get update && apt-get -y upgrade && apt-get install -y build-essential libssl-dev libreadline-dev zlib1g-dev task-japanese sudo
RUN apt-get -y install openssh-server ufw curl
RUN mkdir /var/run/sshd

イメージをビルドします。

$ docker build -t kotaroito/ubuntu .
$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
kotaroito/ubuntu    latest              c6ec79983625        18 seconds ago      485.5 MB

作成したイメージからコンテナを起動するには run サブコマンドを使います。また、 ps サブコマンドでコンテナの状態を確認できます。

$ docker run kotaroito/ubuntu

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS                                             NAMES
93e06154f722        kotaroito/ubuntu    "/bin/bash"              1 seconds ago       Exited (0) 2 seconds ago                                                        naughty_pare

不要になったイメージは rmi サブコマンドで削除できます。

$ docker rmi -f c6ec79983625

DockerHub

Dockerhub を利用すれば、イメージの共有・再利用がカンタンです。 アカウントを作成したら、ログインしてプッシュすればokです。

$ docker login --username=kotaroito --email=****@****
$ docker push kotaroito/ubuntu

ssh / sudo できるようにする

最初に作成したイメージではコンテナに ssh / sudo できないので、必要な設定をDockerfileに加えていきます。

FROM ubuntu:14.04

RUN apt-get update && apt-get -y upgrade && apt-get install -y build-essential libssl-dev libreadline-dev zlib1g-dev language-pack-ja
RUN apt-get -y install openssh-server ufw curl
RUN mkdir /var/run/sshd

RUN useradd -m kotaroito && echo "kotaroito:kotaroito" | chpasswd && gpasswd -a kotaroito sudo
RUN mkdir -p /home/kotaroito/.ssh; chown kotaroito /home/kotaroito/.ssh; chmod 700 /home/kotaroito/.ssh
 
ADD ./authorized_keys /home/kotaroito/.ssh/authorized_keys
RUN chown kotaroito /home/kotaroito/.ssh/authorized_keys; chmod 600 /home/kotaroito/.ssh/authorized_keys

CMD /usr/sbin/sshd -D && tail -f /dev/null

最後のCMDはコンテナがexitしない工夫です。 あとは、buildして run すれば ok ですが、sudo するために privileged オプションを付けておきます。

$ docker build -t kotaroito/ubuntu .
$ docker run --privileged -d -p 2222:22 kotaroito/ubuntu

コンテナは Mac OS X の上で直接稼働しているわけではなく、VMVirtualBox 等)上で動いてるので、ssh するためには VMIPアドレスを調べる必要があります。

$ docker-machine ip default
192.168.99.100

これで ssh することができます。

$ ssh -v kotaroito@192.168.99.100 -p2222

なお、sshd を docker コンテナで走らせる必要はない、という議論もあります。 production で使うならこれはその通りだと思います。

blog.docker.com

以上。

追記(2017年10月)

Docker Toolbox on Mac OS"Legacy desktop solution." です。 アンインストールするには、公式に提供されているスクリプト toolbox/uninstall.sh at master · docker/toolbox · GitHub を使えばよいです。

Mac OS X でのpyenvによるpython環境構築

pythonで機会学習入門するために Mac OS X に環境構築したので、メモを残しておきます。

1. pyenv と pyenv-virtualenv のインストール

brew install pyenv
brew install pyenv-virtualenv

2.bashrcの設定

# pyenv
[[ -s "$HOME/.pyenv" ]] && export PYENV_ROOT="$HOME/.pyenv" && export PATH="$PYENV_ROOT/bin:$PATH" && if which pyenv > /dev/null; then eval "$(pyenv init -)"; eval "$(pyenv virtualenv-init -)"; fi

3. pyenvの動作確認

pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4
  2.4.1
  2.4.2
  snip...

4. pyenv で python をインストール

pyenv install 3.4.3

5. virtualenv の設定

pyenv virtualenv 3.4.3 my-env-3.4.3

6. 機会学習で利用するパッケージのインストール

pip install numpy
pip install scipy
pip install matplotlib
pip install scikit-learn

7. matplotlibの設定

OS X だと matplotlib がそのまま動かないので、ホームディレクトリに .matplotlib/matplotlibrc を 設置。

backend : TkAgg

8. Tensorflowのインストール

pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py3-none-any.whl

追記(2017/4/2)

ローカルに複数プロジェクトがある前提だったのでpyenvを利用していますが、 確かにこういう視点もありますね。勉強になります。

qiita.com

InnoDBのロックに関する記事まとめ

InnoDBのロック機構どうなってたっけ?? と思ったら、読み返したい記事たち。

14.2.6 InnoDB のレコード、ギャップ、およびネクストキーロック

https://dev.mysql.com/doc/refman/5.6/ja/innodb-record-level-locks.html

MySQL InnoDBのネクストキーロック おさらい

http://d.hatena.ne.jp/sh2/20090112

InnoDBのロックの範囲とネクストキーロックの話

http://blog.kamipo.net/entry/2013/12/03/235900

InnoDBで行ロック/テーブルロックになる条件を調べた #mysqlcasual Advent Calendar 2013

http://bluerabbit.hatenablog.com/entry/2013/12/07/075759

良く分かるMySQL Innodbのギャップロック

http://qiita.com/kenjiszk/items/05f7f6e695b93570a9e1

opensslコマンドで証明書を確認する

自分用メモです。

OpenSSL の s_client コマンドを使うと、SSL/TLS クライアントとして リモートホストに接続できます。

The s_client command implements a generic SSL/TLS client which connects to a remote host using SSL/TLS. It is a very useful diagnostic tool for SSL servers.

例えば、証明書を確認するには以下コマンドにて。

$ openssl s_client -connect google.com:443 -showcerts -servername google.com < /dev/null | less

ActiveRecord の with_options に関する注意書き

with_options (Object) - APIdock にて、ActiveRecord の with_options について注意書きが書かれていたのでメモ。 和訳はちょっと雑です。


with_options はネストすることができ、receiver に引き継がれます。

メモ: ネスト階層は継承したデフォルトオプション値を自身のオプションとマージします。

class Post < ActiveRecord::Base
  with_options if: :persisted?, length: { minimum: 50 } do
    validates :content, if: -> { content.present? }
  end
end

このコードは以下と等価です。

validates :content, length: { minimum: 50 }, if: -> { content.present? }

継承されたデフォルトの if キーは無視されます。

/etc/shadow の password field

/etc/shadow の password field に出現する "!" や "*" についてのメモ。

MAN USERMOD(8)

OPTIONS
       The options which apply to the usermod command are:

       -L, --lock
           Lock a user's password. This puts a '!' in front of the encrypted password, effectively disabling the password. You can't use this option with -p or -U.

REFERENCES

superuser.com

ubuntuforums.org

deploy:assets:backup_manifest が失敗する

Rails を 4.2.0 から 4.2.4 にアップグレードしようと capistrano でデプロイしたらエラーが発生した。

 INFO [e43c382f] Running /usr/bin/env cp /home/myapp/myapp/releases/20150916085015/public/assets/manifest* /home/myapp/myapp/releases/20150916085015/assets_manifest_backup on ***.***.***.***

SSHKit::Command::Failed: cp exit status: 1
cp stdout: Nothing written
cp stderr: cp: cannot stat ‘/home/myapp/myapp/releases/20150916085015/public/assets/manifest*’: No such file or directory

Tasks: TOP => deploy:assets:backup_manifest
(See full trace by running task with --trace)

manifest を cp できてない模様。

capistrano に本件の issue が上がっており、コメントに

Rails 4.2.4, it works after upgrading capistrano-rails to 1.1.3 and capistrano-bundler to 1.1.4

とのこと。

capistrano-rails を 1.1.3 上げたら、エラーは発生せずデプロイは成功。

単なるメモになってしまったが、覚えてないとハマりそうなので備忘録として。