2014年9月23日火曜日

Ruby on Rails4 で バッチ処理をする(rails runner, whenever)

railsのコマンドでrunnerというコマンドがある
例)
rails runner Tasks::AlertTask.execute
これを利用します。

crontabへの登録はcrontab -eで手書きすることもできるが、モジュール管理もできるのでrubyで書く方法をためします。

・バッチモジュール作成
> vim config/application.rb
config.autoload_paths += %W(#{config.root}/lib) # 追記する
バッチクラス作成
> vim lib/tasks/alert_task.rb
class Tasks::AlertTask

  def self.execute
    puts "Hoge"
  end
end

ちゃんと作成出来たかを確認する。
> rails runner Tasks::AlertTask.execute
Hoge

・スケジュール登録(crontabへの登録手順)
> vim Gemfile
gem 'whenever', :require => false # 追記

> bundle install

config/schedule.rbを作成
> wheneverize .

> vim config/schedule.rb

set :output, "log/cron_log.log" # ログファイルパス
set :environment, :development # 実行環境
every 1.day, :at => '5:00 am' do # 毎日5時に実行
  runner "Tasks::AlertTask.execute" # 実行するタスク(lib/tasks/alert_task.rbのexecuteメソッドを実行)
end

crontab登録
> bundle exec whenever -update-crontab

crontab確認
> crontab -l

もし、実行されなかった場合。
パターン1:
bin/rails:7: undefined method `require_relative' for main:Object (NoMethodError)
と表示される場合はrubyが複数存在する可能性があります。下記にて不要なrubyを消しましょう。
> yum remove ruby

パターン2:
/usr/bin/env: ruby: No such file or directory
と表示される場合は下記を実施。
> vim ~/.bashrc
export PATH=/usr/local/bin:$PATH

2014年9月3日水曜日

JavaScriptで数値の桁あふれでハマった・・・

お好きなブラウザで確認できるので、一度試してみるといいかもしれません。

ブラウザの開発者ツールでコンソールを表示し、下記を入力して下さい。
var i = 1118918899790958592;

この数値がiという変数に格納されていると思いますよね。
では、そのままコンソールでiを出力してみてください。
> var i = 1118918899790958592;
> i
1118918899790958600
んっ!!!!!
ということで、10の位で丸められていますね。。。
どんな桁落ちだよ。

通常こんなでかい数字を扱うことはないと思うのですが、今回利用していたAPIの戻り値がJSONでそのID的なものが数値型でこの桁数という・・・。
やられたわー。
4時間くらい楽しんでしまった・・・。

2014年8月20日水曜日

Ruby on Rails4をproduction環境として動かす(nginx + unicorn)

rails4(nginx + unicorn)での動かし方をまとめます。

環境は下記となります。
・Ruby2.1
・nginx
・unicorn

1.Unicornをインストールする
Gemfileに書きを追記
gem 'unicorn'
追記後にbundle installをお忘れなく。

2.config/unicorn.rb作成(下記をコピペでいい)
application = '{適当なアプリ名}'

worker_processes 2
working_directory "/#{application}"

listen "/var/run/unicorn/unicorn_#{application}.sock"   # Unix Domain Socket

pid "/var/run/unicorn/unicorn_#{application}.pid"       # PIDファイル出力先
 
timeout 60
 
preload_app true

stdout_path "/var/log/unicorn/unicorn.stdout_#{application}.log"  # 標準出力ログ出力先
stderr_path "/var/log/unicorn/unicorn.stderr_#{application}.log"  # 標準エラー出力ログ出力先
 
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
 
before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid
      begin
        sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
        Process.kill(sig, File.read(old_pid).to_i)
      rescue Errno::ENOENT, Errno::ESRCH
      end
    end
 
    sleep 1
  end
 
after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
3.assetsをプリコンパイルする
production環境ではassetsを毎回コンパイルすると遅いらしいので、最初にコンパイルさせる。
bundle exec rake assets:precompile
4.unicorn起動
unicorn_rails -c config/unicorn.rb -E production -D -p 13000

5.nginxの設定
/etc/nginx/conf.d/rails.conf的なファイルに書きを記載(rails.confは.confがあれば勝手に読み込むのでファイル名は何でも良い)
upstream unicorn-unix-domain-socket {
   ### unicorn.rbで指定したUnicornのソケットを指定:
   server unix:/var/run/unicorn/unicorn_subsche.sock fail_timeout=0;
}

upstream unicorn-tcp {
   ### unicornのポートを指定 ※ここでは、Unicorn起動時にポート 13000で起動させるものとします。
   server 127.0.0.1:13000;
}

server {
   listen 80;
   server_name {サーバ名};

   root /{アプリパス}/public;

   access_log  /var/log/nginx/access.log;
   error_log /var/log/nginx/error.log;

   location ^/assets/ {
       root /{アプリパス}/public;
   }


   auth_basic "user name";
   auth_basic_user_file "/etc/nginx/htpasswd";

   location / {
       if (-f $request_filename) {
           break;
       }

       proxy_set_header X-Real-IP  $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Host $http_host;

       proxy_pass http://unicorn-unix-domain-socket;
    }

    location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
       expires 1y;
    }
}


6.nginx起動
service nginx start
起動しているのであれば、下記コマンド。
service nginx restart

7.ブラウザからアクセス
表示できれば終わり。表示できなければ下記を確認して下さい。


■起動しない場合
・DBがない
・SECRET_KEY_BASEを設定していない

ポイント1.DBがない
ずっとdevelopment環境で開発している場合、production用のdatabaseが作成されていない可能性があります。
下記コマンドで、production用のdatabaseを作成しましょう。
rake db:create db:migrate RAILS_ENV=production

ポイント2. SECRET_KEY_BASEを設定していない
下記のエラーが出る場合は、きっとこのパターンです。
E, [2014-08-20T22:34:16.262827 #3625] ERROR -- : app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)
E, [2014-08-20T22:34:16.263001 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:452:in `validate_secret_key_config!'
E, [2014-08-20T22:34:16.263061 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:195:in `env_config'
E, [2014-08-20T22:34:16.263083 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/engine.rb:510:in `call'
E, [2014-08-20T22:34:16.263103 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:144:in `call'
E, [2014-08-20T22:34:16.263122 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:576:in `process_client'
E, [2014-08-20T22:34:16.263142 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:670:in `worker_loop'
E, [2014-08-20T22:34:16.263160 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:525:in `spawn_missing_workers'
E, [2014-08-20T22:34:16.263187 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:140:in `start'
E, [2014-08-20T22:34:16.263206 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/bin/unicorn_rails:209:in `'
E, [2014-08-20T22:34:16.263225 #3625] ERROR -- : /usr/local/bin/unicorn_rails:23:in `load'
E, [2014-08-20T22:34:16.263243 #3625] ERROR -- : /usr/local/bin/unicorn_rails:23:in `
'
config/secrets.ymlファイルで「secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>」という部分が存在するため、下記コマンドを実施する。
export SECRET_KEY_BASE=`rake secret`
その後、unicornの再起動を行う。

これでアクセス出来なければ別な問題かもしれません。

2014年7月29日火曜日

インストールした直後のLinux(Redhat,CentOS系)が外に繋げない(名前解決してくれない。yumできない)。

VMとかにLinuxをインストールして、yumでミドルウェアをインストールしようとしたら、、、WorldWideWebに繋がっていないなんてことありますよね。

そんな場合は、慌てずに下記を試してください。

1.pingってみる
ping yahoo.co.jp
これで100% packet loss


2.まずは、問題の切り分けです。
/etc/hostsに下記を追記してください。
182.22.59.229 yahoo.co.jp


3.外につながるか確認
ping yahoo.co.jp
これで、つながる。


手順3でつながるなら、下記手順で対応出来る可能性があります。

4./etc/nsswitch.confを確認
hosts:と書かれている行を探す。
"files"としか書かれていなければ、アウト。
"files dns"と記述してください。

5.手順4で無理なら、/etc/resolve.confを確認
nameserverの記述があるか?
なければ、下記を追加
nameserver 8.8.8.8
※8.8.8.8はGoogleのpublic DNSです。

これで外の世界につながるようになっているはずです。

※手順2でhostsファイルに追記した設定は消しておいてください。

2014年7月21日月曜日

MySQLのスロークエリログに出し方

下記を/etc/my.cnfに追記する。
[mysqld]
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
log_queries_not_using_indexes
log_slow_admin_statements

・low_query_log
1:ログを出力する
2:ログを出力しない

・long_query_time
単位は秒なので、どのラインから遅いか?というのを適当に決めて書く

・log_queries_not_using_indexes
これを記述するとインデックスを使っていない検索はすべてログに出す

・log_slow_admin_statements
ALTER TABLEなどのクエリも同様に計測したい場合に記述する

MySQLのスロークエリをログに出す方法があると初めて知った。

他にも色々と書いてあって参考になった。↓

2014年7月20日日曜日

Railsにて複合主キーのテーブルをupdateしたい場合

Railsはデフォルトでは複合主キーに対応しておらず、検索は問題なくできるが、更新系(update,delete)はエラーが発生してしまう。
『rails update Mysql2::Error: Unknown column where clause』的なエラーに遭遇してしまうはず。

そういう場合は、composite_primary_keysというモジュールを組み込むと解決できるので試してみるとよい。

Gemfileに下記を記述
gem 'composite_primary_keys'

その後、bundle install
bundle install

それから、modelを修正する
class UserClassRelation < ActiveRecord::Base
  self.primary_keys = :user_id, :class_id
end

上記を書いたら、アプリケーションサーバを再起動してupdateなどを試してみてください。

2014年7月12日土曜日

Dockerfileを利用してMySQLのインストールとRuby2.1、Railsのインストールを行い、かつソースもGithubからcloneする

Mac上で開発をしてもいいが、あんまり環境を汚したくないのでDocker上のCentOS上で開発ができる用にする再現の装備を整える手順です。

Docker上に設定しきってしまいたい部分。
OS:CentOS
ミドルウェア:MySQL,Ruby2.1,Rails
ソース:Githubのclone

MySQLに関してはutf-8がいいので、設定ファイルをホストOSからコピーさせています。

> cat Dockerfile 

FROM centos
MAINTAINER sample_name 

RUN echo "Install lib"
RUN yum install -y git vim sudo tar wget
RUN yum install -y gcc make gcc-c++ zlib-devel httpd-devel openssl-devel curl-devel sqlite-devel

RUN echo "Install mysql"
RUN yum install -y mysql mysql-server mysql-devel
ADD etc/my.cnf /etc/my.cnf
RUN touch /etc/sysconfig/network

RUN echo "Install ruby"
RUN cd /root/ && wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.1.tar.gz
RUN cd /root/ && tar zxvf ruby-2.1.1.tar.gz
RUN cd /root/ruby-2.1.1 && ./configure && make && make install
RUN gem install bundler --no-ri --no-rdoc -V
RUN gem install rb-readline --no-ri --no-rdoc -V

RUN echo "Install rails"
RUN gem install rails --no-ri --no-rdoc -V
RUN gem install mysql2 -v '0.3.16' --no-ri --no-rdoc
RUN echo rails -v

RUN git clone https://github.com/{githubユーザID}/{プロジェクト名}

RUN bundle install

ADDって箇所が、ホストOSのファイルをDocker上にコピーしている部分です。
Dockerfileのディレクトリからのファイルパスを記述します。
ADD ホストOS側のファイルパス Docker上のファイルパス

Dockerfileを利用してのdockerの起動は下記コマンドになります。
docker build -t {docker imageを保存する名前} .
例)
docker build -t ak220/ruby:1.0 .

本来なら、Monitとかのインストールもしてしまって、MySQLの起動などをMonitに任せる感じにしたいところだが、Docker上でシステム開発をすることを目的としているので、この状態で今回は終わりです。

MySQL起動時に /etc/sysconfig/network: No such file or directoryと言われたら

Dockerを利用してCentOS上のMySQLを起動しようとすると下記感じでエラーが出る事がある。
$ /etc/rc.d/init.d/mysqld start
/etc/rc.d/init.d/mysqld: line 23: /etc/sysconfig/network: No such file or directory

その場合は、networkファイルを作ってあげれば解決する。
$ touch /etc/sysconfig/network

git push で 403 Forbidden が発生したら

Githubにpushしたら下記エラーが発生した。
git push
error: The requested URL returned error: 403 Forbidden while accessing https://github.com/{githubユーザ名}/{プロジェクト名}/info/refs

fatal: HTTP request failed

・対処方法
pushするURLを見失っている状態っぽいので、下記コマンドを実施。
git remote set-url origin https://{githubユーザ名}@github.com/{プロジェクト名}
git push
これで正しくpushできるようになるはずです。

2014年6月8日日曜日

Java8のlambda式について

Java8が公開されてそれなりに時間が経ちましたが、さすがにそろそろLambda式に慣れないとまずいということでメモとして残していきます。

Java7までの書き方から始まり、徐々にラムダ式の簡略記法に変換していく感じでまとめています。
go1メソッド→go4メソッドまで順序だてる感じで簡略化していきます。
簡略化の仕方に関しては各メソッドにコメントとして記載しているのでそちらを参照してもらえるとわかりやすいかと思います。

package lambda1;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.UnaryOperator;

public class Main {

 private static final List list = Arrays.asList("a", "b", "c", "d",
   "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q",
   "r", "s", "t", "u", "v", "w", "x", "y", "z");

 public static void main(final String[] args) {
  Main m = new Main();
  m.go1();
  m.go2();
  m.go3();
  m.go4();
 }

 /**
  * Java8以前の記述方法。
  * この記述を徐々に簡略化していきます。
  */
 public void go1() {
  System.out.println("go1");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll(new UnaryOperator() {

   @Override
   public String apply(String str) {
    return "==" + str;
   }

  });
  System.out.println(l.toString());
 }

 /**
  * replaceAllの引数のUnaryOperatorインタフェースは
  * @FunctionalInterfaceのアノテーションが付いているので、
  * ラムダ式で記述を置き換えられる。
  */
 public void go2() {
  System.out.println("go2");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll((String t) -> {
   return "==" + t;
  });
  System.out.println(l.toString());
 }

 /**
  * 処理が1行の場合は{}で囲う必要がないので削除。
  * さらにreturnも1行の場合は削除できるので削除。
  */
 public void go3() {
  System.out.println("go3");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll((String t) -> "==" + t);
  System.out.println(l.toString());
 }

 /**
  * 型は推論してくれるし、かつ引数が1個なのでカッコも不要。
  */
 public void go4() {
  System.out.println("go4");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll(t -> "==" + t);
  System.out.println(l.toString());
 }
}


しかし、便利ですね。
最初はPHPみたいな矢印マークでとっつきにくかったですが、こうやって徐々に簡略化していくと色々とわかりやすく学べました。
これなら、自分で関数インタフェース(@FunctionalInterface)を利用して、便利に色々と作れる気がしてきました。

2014年4月11日金曜日

MacでDockerにMonitを入れてApacheを動かす

Dockerで起動したCentOS上にMonitをインストールしてApacheを起動させます。

Monitとは、プロセス監視ツールです。
なぜ、このMonitを利用するかというと、、、Dockerは起動時に1つしかプロセスを起動するコマンドが使えないためです。
このMonitを利用すると、プロセスが立ち上がっていない場合Monitがかわりに起動してくれる様な設定が可能です。
なので、Dockerの起動時に立ち上げるプロセスをMonitにしておけば、Monitに監視させている他のプロセス(ApacheやSSHなど)をMonitが立ち上げてくれるんです!

それではインストールの仕方と設定方法を書いていきます。
・用意するもの
Dockerがインストールされた環境のみ。
もし、DockerがインストールされていなければMacでDockerを動かすでインストールしてみてください。

・まずはDockerを使ってcentosを起動
$ docker run -i -t centos /bin/bash

・続いて、とりあえずサーバを最新化します
$ yum update

・Monitのインストール
$ rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
$ rpm -ivh http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.5.1-1.el5.rf.i386.rpm
$ yum install --enablerepo=rpmforge monit

・Apacheのインストール
$ yum install httpd
・index.html作成
$ echo test > /var/www/html/index.html

・一旦、centosをコミットしておく(ここは飛ばしてもOK)
$ exit
上記で、Dockerから抜ける。
$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES 20cafcb9639e        centos:6.4          /bin/bash           3 days ago          Exit 0                                  grave_shockley       
$ docker commit 20c ak220/centos 
・コミット確認
$ docker images
 REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
 ak220/centos        latest              d83459021df6        3 days ago          668 MB 
commitしたimageが存在することを確認。
・commitした状態の続きを操作するの
$ docker run -i -t ak220/centos /bin/bash

・Monitの設定
$ vi /etc/monit.conf 
変更項目は下記
変更前
set httpd port 2812 and
    use address localhost
    allow localhost
    allow admin:monit
    allow @monit
    allow @users readonly
変更後
set httpd port 2812 and
    use address 0.0.0.0
    allow admin:monit
続いて、MonitにApacheを監視させる。
$ vi /etc/monit.d/httpd.conf
check process httpd with pidfile /var/run/httpd.pid
    start program = "/etc/init.d/httpd start" with timeout 60 seconds
    stop program  = "/etc/init.d/httpd stop"
    if failed port 80 protocol http
    then restart
    group apache

・Monitの設定ファイルが正しいかを確認
$ monit -t
Control file syntax OK #と表示されればOK

・Monit起動
$ service monit start
Starting monit: Starting monit daemon with http interface at [0.0.0.0:2812]
                                                           [  OK  ]
もし「/etc/init.d/monit: line 18: /etc/sysconfig/network: No such file or directory」というエラーがでたら、下記のコマンドを実行して下さい。
$ touch /etc/sysconfig/network
Apacheが起動していることを確認する。ApacheのプロセスがあればOK。
$ ps -ef | grep httpd
root        53     1  0 14:10 ?        00:00:00 /usr/sbin/httpd
apache      55    53  0 14:10 ?        00:00:00 /usr/sbin/httpd
apache      56    53  0 14:10 ?        00:00:00 /usr/sbin/httpd
apache      57    53  0 14:10 ?        00:00:00 /usr/sbin/httpd
ここまでできたら、Dockerから抜けます。
$ exit


・構築したコンテナをコミットして、Monitを起動
$ docker ps -l
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS              PORTS               NAMES
d99e2f8dc5bc        ak220/centos:latest   /bin/bash           3 days ago          Exit 0                                  hungry_engelbart    
$ docker commit d99e2f ak220/centos
Dockerで構築したimageをコミットしたので、このイメージをRunさせるときにMonitのプロセスを実行します。
ついでに、localhost:10080をDockerのCentOSで稼働しているApacheの80番ポートに紐付けます。
$ docker run -d -t -p 10080:80 -p 12812:2812 ak220/centos /usr/bin/monit -I

で、http://localhost:10080にアクセスすると、、、ん、見れない。EC2上ではうまく行ったのに・・・。
だいぶ困った。同じ設定なのに。
EC2上とMac上でのDockerの起動の違いはMacではboot2docker上でDockerが起動していること。VirtualBoxのポートフォワードが犯人でした。
ということで、boot2dockerの設定をします。
$ ./boot2docker stop
$ for i in {49000..49900}; do
 VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i";
 VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i";
done
$ ./boot2docker start
$ docker run -d -t -p 49080:80 -p 49812:2812 ak220/centos /usr/bin/monit -I
http://localhost:49080/
で「test」っていう文字がブラウザに表示されたらOK。(このtestはecho text > /var/www/html/index.htmlで書き込んだやつ)
・Monitの管理画面
http://localhost:49812/
これでMonitの管理画面が見れます。プロセスの停止、起動が出来たりします。

VirtualBoxのポートフォワードにははめられました。みなさん気をつけて下さい。

2014年4月7日月曜日

Dockerの基本コマンド

Dockerの基本コマンドを羅列していきます。

・Dockerのバージョン確認
$ docker version

・Dockerで使用するコンテナの検索
$ docker search [centos]
ubuntuがほしいなら、「docker search ubuntu」

・使用するコンテナのダウンロード
$ docker pull centos
docker pull [searchした結果のNAME]
結構時間かかります。

・コンテナを走らせコマンドを実行する
$ docker run -i centos echo "hello world"
docker run -i [ダウンロードしたコンテナ名] [実行したいコマンド]

・コンテナのIDを取得
$ docker ps -l

・コンテナのコミット
$ docker commit 347ba centos/echo
docker commit [docker ps -lで表示されたIDの頭の一部で良いらしい] [コミットする名前]

・コミットしたコンテナの使用
$ docker run centos/echo echo 'hello'
docker run [コミットしたREPOSITORY名] [コマンド]

・コミットしたコンテナの確認
$ docker images

Dockerを使ってみた

「JAWS DAYS 2014」に行って最近はVMではなくコンテナってのが流行っているということなので、試してみました。
今回はDockerの導入手順だけを記載します。

・環境
Mac OX 10.9.2

・Dockerインストール前提
Mac上でDockerを利用するためにはboot2dockerというものを先にインストールする必要がある。
基本的な手順は公式サイトに書いてあるのでそちらを参照するのが良いかもしれない。

・Dockerインストール作業
1.boot2dockerのインストール
好きなディレクトリに移動。
$ curl https://raw.github.com/boot2docker/boot2docker/master/boot2docker > boot2docker
$ chmod +x boot2docker
$ ./boot2docker init
$ ./boot2docker up
以上でDockerを動かすための下準備完了。

2.Dockerインストール
好きなディレクトリに移動。
$ curl -o docker https://get.docker.io/builds/Darwin/x86_64/docker-latest
$ chmod +x docker
$ export DOCKER_HOST=tcp://127.0.0.1:4243
$ sudo cp docker /usr/local/bin/
以上でインストールは完了です。

では早速コンテナを立ち上げて使ってみましょう!

3.CentOSを立ち上げてechoコマンドを実行
$ docker run centos /bin/echo hello world
初回は、OSのイメージをダウンロードするのでスゴく時間がかかります。気長に待ちましょう。

1回イメージがダウンロードできれば、次からは即効でコンテナが起動しコマンドの結果が返ってきます。