Dockerでhubot-slackを動かす

SlackのTokenを取得する

これは、Slackから取得するればおk

hubotをSlackに接続できるようにする

yomanのジェネレーターを使って作成します 簡単ですね。

npm install -g hubot coffee-script yo generator-hubot
# hubotの雛形を作成
yo hubot
# slackのアダプター
npm install hubot-slack --save

環境変数HUBOT_SLACK_TOKEN にSlackから取得できたTokenを設定する

./bin/hubot

これでSlackに設定したhubotのユーザーがログイン状態になればおk

Dockerで動かすようにする

centos6のDockerfileの内容です。

FROM centos:centos6
MAINTAINER oomatomo ooma0301@gmail.com

# install package
RUN rpm -Uhv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN yum update -y

# time
ENV TZ JST-9

# nodejs npm
RUN yum install -y tar bzip2 git
RUN curl --silent --location https://rpm.nodesource.com/setup_5.x | bash -
RUN yum install -y nodejs
RUN yum install -y gcc-c++ make

# change hubot user
RUN useradd -d /hubot -m -s /bin/bash -U hubot
USER    hubot
WORKDIR /hubot

# npm install
COPY package.json ./
RUN npm install

COPY ./bin/hubot ./bin/hubot
COPY hubot-scripts.json ./
COPY external-scripts.json ./
COPY ./scripts ./scripts

CMD ["bin/hubot", "-a", "slack", "-n", "hubotの名前"]

docker-compose.ymlの内容

hubot:
  build: .
  environment:
    - HUBOT_SLACK_TOKEN

環境変数にHUBOT_SLACK_TOKENを設定していれば

docker-compose up -d hubot でhubotが立ち上がります

リポジトリ

github.com

まとめ

案外簡単にできてびっくりしました

以前は、Global IPなどが必要だったのですが新しい使い方からは要らないので

自分の手元から起動できるので楽です!!

IntelliJ IDEAのGo言語に関する設定

IntelliJ IDEAでのGoのプラグインをインストール

Goで検索すると、候補が出るのでインストールする f:id:oomatomo:20160313202942p:plain

これだけです

Go言語のSDKを作成

homebrewでインストールしたGoのパスの設定をします f:id:oomatomo:20160313203044p:plain

GO SDKを指定するとパスを指定します 今回は、/usr/local/Cellar/go/1.5.2/libexecを指定しました f:id:oomatomo:20160313203046p:plain

追加したSDKのパスを確認する f:id:oomatomo:20160313203450p:plain

GOPATHの設定の確認

自分が認識しているPATHかどうか確認する

f:id:oomatomo:20160313203058p:plain

これで環境を構築できました。

scalaのプログラムをCircleCiを使ってs3にアップロードして、dockerで起動させる

scalaのプログラムをdockerで動かすために sbt-dockerとかありますが、今回はそれは使いません。

起動までの流れ

  • CircleCi のテスト完了後に、ファイルをS3にアップロードする
  • dockerはファイルにアップロードされたファイルを解凍して、起動する

単純に、CIでテストを回した後S3にjarをアップロードして dockerはアップロードされたjarを起動することにしてます。

CircleCi

AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYはCircleCi側でポチポチっと設定しました。
circle.ymlの内容は、以下の通りです。

machine:
  timezone:
    Asia/Tokyo
  java:
    version: oraclejdk8
dependencies:
  # project/build.propertiesを見てくれる
  #pre:
  #  - wget -q https://dl.bintray.com/sbt/debian/sbt-0.13.8.deb
  #  - sudo dpkg -i sbt-0.13.8.deb
  cache_directories:
    # デフォルトでキャッシュされる
    # - "~/.ivy2"
    # bootにインストールされたパッケージが入る
    - "~/.sbt/boot"
  override:
   # aws cliをinstall
    - sudo pip install awscli
    - sbt update
  post:
    # aws cliの設定 
    - aws configure set region ap-northeast-1
test:
  override:
    # カバレッジを出力
    - sbt clean coverage test coverageReport coverageAggregate
  post:
    # カバレッジのレポートをCircleCiで見れるようにする
    - cp -R ~/play-deploy/target/scala-2.10/scoverage-report/ $CIRCLE_ARTIFACTS
deployment:
  production:
    branch: master
    commands:
      # zipにまとめる
      - sbt universal:packageBin
      # s3へ
      - aws s3 cp ~/play-deploy/target/universal/dilaton-web-0.0.1.zip s3://play-deploy/play-deploy-0.0.1.zip

Dockerfile

TimeZoneを設定したり、aws-cliをインストールしたりしてます。
build時には、s3からjarのzipをダウンロードはしてません。

FROM centos:centos6
MAINTAINER oomatomo ooma0301@gmail.com

RUN rpm -Uhv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN yum update -y
# timezone
ENV TZ JST-9

# java
RUN yum install -y wget tar java-1.8.0-openjdk java-1.8.0-openjdk-devel

# aws cli
RUN yum install -y python-pip
RUN pip install awscli
ENV AWS_DEFAULT_REGION ap-northeast-1
ENV AWS_DEFAULT_OUTPUT json

# deploy
RUN yum install -y unzip
COPY deploy.sh ~/

EXPOSE 9000
CMD ["~/deploy.sh"]

deploy.sh

デプロイ用のスクリプトです。 ここで、s3からjarのzipダウンロードしてます。

#! /bin/bash
env
aws s3 cp s3://play-deploy/play-deploy-0.0.1.zip ~/play-deploy-0.0.1.zip
unzip -o ~/play-deploy-0.0.1.zip -d /usr/local/bin/
/usr/local/bin/play-deploy-0.0.1/bin/play -Dfile.encoding=UTF-8

docker-compose.yml

.play.envAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY を設定しています。
build時に環境変数を渡したかったのですが、できなかったのでrunの時にenv_fileを使ってawsのアクセスキーを渡してます。
docker-composeがversion2になってargsが対応されてましたが、env_fileみたいに使えません。
そのため、直接 docker-compose.yml に書かなければいけないので諦めました。

https://docs.docker.com/compose/compose-file/#args

play:
  build: ./play
  env_file: ~/.play.env
  ports:
    - "9000:9000"

まとめ

とりあえず、動いた。。 でも、仕事では使えないな〜〜。

TODO

gitのtagベースでjarファイルやdockerを起動できるようにする

slickでHikariCPを使った時の設定値の上書きに関して

slickでHikariCPを使うときに、設定値が上書きされて コードを見てたら気づいたことがあったので残します。

slickでHikariCPを使うときの設定

HikariCP https://github.com/brettwooldridge/HikariCP

db.master {
    url  = "jdbc:mysql://hoge:3306/hoge"
    driver=com.mysql.jdbc.Driver
    user = hoge
    password = hoge
    # connectionPoolはHikariCPを選択する部分
    connectionPool = HikariCP
    keepAliveConnection = true
    properties = {
         #HikariCPの設定ファイルをここに記入する
         maximumPoolSize = 10
         minimumIdle = 10
         ...etc
    }
}

こんな感じで設定してみたら、maximumPoolSizeminimumIdleが10になるので 動かすと、mysql側でshow processlistを確認したら20プロセスあった。

それで、設定の部分のコードを見てみました。

コネクションプールの選択の部分

https://github.com/slick/slick/blob/3.1/slick/src/main/scala/slick/jdbc/JdbcDataSource.scala

28行目あたりが、コネクションプールの選択の部分ですね。 connectionPoolの部分を見て、設定をしています。

def forConfig(c: Config, driver: Driver, name: String, classLoader: ClassLoader): JdbcDataSource = {
    def loadFactory(name: String): JdbcDataSourceFactory = {
      val clazz = classLoader.loadClass(name)
      clazz.getField("MODULE$").get(clazz).asInstanceOf[JdbcDataSourceFactory]
    }
    val pf: JdbcDataSourceFactory = c.getStringOr("connectionPool", "HikariCP") match {
      case "disabled" => DataSourceJdbcDataSource
      case "HikariCP" => loadFactory("slick.jdbc.hikaricp.HikariCPJdbcDataSource$")
      case "slick.jdbc.HikariCPJdbcDataSource" =>
        logger.warn("connectionPool class 'slick.jdbc.HikariCPJdbcDataSource$' has been renamed to 'slick.jdbc.hikaricp.HikariCPJdbcDataSource$'")
        loadFactory("slick.jdbc.hikaricp.HikariCPJdbcDataSource$")
      case name => loadFactory(name)
    }
    pf.forConfig(c, driver, name, classLoader)
  }

HikariCPの場合、slick.jdbc.hikaricp.HikariCPJdbcDataSource を見ていることがわかります。

HikariCPの設定の上書き

https://github.com/slick/slick/blob/3.1/slick-hikaricp/src/main/scala/slick/jdbc/hikaricp/HikariCPJdbcDataSource.scala

// propertiesの設定を読み込む
c.getPropertiesOpt("properties").foreach(hconf.setDataSourceProperties)

// HikariCPの設定を読み込む
hconf.setConnectionTimeout(c.getMillisecondsOr("connectionTimeout", 1000))
hconf.setValidationTimeout(c.getMillisecondsOr("validationTimeout", 1000))
hconf.setIdleTimeout(c.getMillisecondsOr("idleTimeout", 600000))
hconf.setMaxLifetime(c.getMillisecondsOr("maxLifetime", 1800000))
hconf.setLeakDetectionThreshold(c.getMillisecondsOr("leakDetectionThreshold", 0))
hconf.setInitializationFailFast(c.getBooleanOr("initializationFailFast", false))
c.getStringOpt("connectionTestQuery").foreach { s =>
  hconf.setJdbc4ConnectionTest(false)
  hconf.setConnectionTestQuery(s)
}
c.getStringOpt("connectionInitSql").foreach(hconf.setConnectionInitSql)
val numThreads = c.getIntOr("numThreads", 20)
hconf.setMaximumPoolSize(c.getIntOr("maxConnections", numThreads * 5))
hconf.setMinimumIdle(c.getIntOr("minConnections", numThreads))
hconf.setPoolName(name)
hconf.setRegisterMbeans(c.getBooleanOr("registerMbeans", false))

// Equivalent of ConnectionPreparer
hconf.setReadOnly(c.getBooleanOr("readOnly", false))
c.getStringOpt("isolation").map("TRANSACTION_" + _).foreach(hconf.setTransactionIsolation)
hconf.setCatalog(c.getStringOr("catalog", null))

初めに propertiesが呼ばれてそのまま設定され その後、デフォルトの設定が反映されるみたいです。

propertiesにmaximumPoolSizeを設定していても maxConnectionsが優先されるみたいです。 あと、HikariCP側と若干命名が変わっているです。

これが原因で、propertiesにmaximumPoolSizeとかを設定しても上書きされていました!!! なるほど。。。

# デフォルトの設定値
val numThreads = c.getIntOr("numThreads", 20)
hconf.setMaximumPoolSize(c.getIntOr("maxConnections", numThreads * 5))
hconf.setMinimumIdle(c.getIntOr("minConnections", numThreads))

設定の例

db.master {
    url  = "jdbc:mysql://hoge:3306/hoge"
    driver=com.mysql.jdbc.Driver
    user = hoge
    password = hoge
    connectionPool = HikariCP
    keepAliveConnection = true
    maxConnections = 10
    minConnections = 10
    connectionTimeout = 10000
    validationTimeout = 5000
    idleTimeout = 600000
    maxLifetime = 3000000
    leakDetectionThreshold = 0
    initializationFailFast = false
    readOnly = false
    catalog = null
    properties = {
        autoCommit = true
        initializationFailFast = true
        isolateInternalQueries = false
        allowPoolSuspension = false
    }
}

まとめ

propertiesに書いても、上書きされることを覚えておく!!

個人用のwordpressをdockerで動かす

自分がいじっているwordpressをDockerで動かすようになりました。

前提条件

wordpressの運用の良い方法は、あまり知らないので参考しないで欲しいです。 仕事では、このような状況ではないはずなので。。。 とりあえず、wordpressをまるっとリポジトリ管理することで楽できるのでやってます。

事前準備

wordpressのコードを、ダウンロードして git init して リポジトリ管理にする

wget http://wordpress.org/latest.tar.gz
tar -xzvf latest.tar.gz
cp /srv/wordpress/wp-config-sample.php /srv/wordpress/wp-config.php
 cd /srv/wordpress/ && git init .....

wp-config.phpにDBの設定を記入

Dockerfile

FROM ubuntu:14.04
MAINTAINER oomatomo ooma0301@gmail.com

RUN apt-get update -y
# wordpressを動かすために必要なphp5系
RUN apt-get install -y php5-fpm php5-mysql

# php5-fpmの初期の設定ファイルを削除する
RUN rm /etc/php5/fpm/pool.d/www.conf
# php5-fpmの
COPY wordpress.conf /etc/php5/fpm/pool.d/wordpress.conf
COPY start.sh ~/
CMD ["~/start.sh"]

/etc/php5/fpm/pool.d/wordpress.conf

/var/run/にphp5-fpm_wordpress.sockというソケットファイルを作るように設定します。

[wordpress]

user = www-data
group = www-data
# ソケットファイルの設置
listen = /var/run/php5-fpm_wordpress.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic

pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

chdir = /

start.sh

www-dataでphp5-fpmを動かしているので、ファイルの権限を変更しています。 また、dockerで動かすのでphp5-fpmのデーモン化はしないような設定にしています。

#! /bin/bash
chown -R www-data:www-data /srv
/usr/sbin/php5-fpm --nodaemonize -c /etc/php5/fpm/php-fpm.conf

docker-compose.yml

/var/run/には、ホストから見るソケットファイルがあるのでvolumesに入れてます。 /srv/には、リポジトリ管理しているwordpressのファイルがあるのでこれも、volumesに入れてます。

wordpress:
  build: ./wordpress
  volumes:
    - /var/run:/var/run
    - /srv:/srv

/etc/nginx/conf.d/wordpress.conf

ホストのnginxの設定ファイル

fastcgi_pass unix:/var/run/php5-fpm_wordpres.sock; root /srv/wordpress/ ; 以外は、デフォルトのやつですね。

server {
  listen       80;
  # ドメインを設定
  server_name  hoge.net;
  # wordpressのパス
  root /srv/wordpress/ ;
  client_max_body_size 64M;
  # Deny access to any files with a .php extension in the uploads directory
  location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
  }
  location / {
    index index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$args;
  }
  location ~* \.(gif|jpg|jpeg|png|css|js)$ {
    expires max;
  }
  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_index index.php;
    #  /etc/php5/fpm/pool.d/wordpress.conf で記述した ソケットファイル
    fastcgi_pass  unix:/var/run/php5-fpm_wordpres.sock;
    fastcgi_param   SCRIPT_FILENAME
                    $document_root$fastcgi_script_name;
    include       fastcgi_params;
  }
}

deploy

docker-compose up -d wordpress で完了するので楽です リポジトリ管理は、ホスト側で行っているのでdockerを止める必要もないので、個人が使う分にはちょうどいいです。

まとめ

サービスでは、使えないが個人が使う分にはこんな感じかなと思いました。

goをdockerでbuildから起動まで

今回は、とりあえず動くベースでやったのでこの方法を 仕事のサービスでは使わない方がいいです。

https://github.com/oomatomo/go-redirect.git

goで簡単なリダイレクトするプログラムを作ったやつです。 これをdockerを使って起動します。

FROM centos:centos6
MAINTAINER oomatomo ooma0301@gmail.com

RUN rpm -Uhv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN yum update -y
RUN yum install -y git
# go install
RUN yum install -y golang
RUN mkdir ~/.go
ENV GOPATH /.go

# go build
WORKDIR /usr/local/src/
RUN git clone https://github.com/oomatomo/go-redirect.git
WORKDIR /usr/local/src/go-redirect
RUN go get github.com/cihub/seelog
RUN go build
RUN mv go-redirect /usr/local/bin/

EXPOSE 8080
ENV PORT 8080
CMD ["/usr/local/bin/go-redirect"]

内容は、シンプルです。

  • go言語のinstall
  • コードのclone
  • ライブラリのインストール
  • コードのbuild
  • 起動

ライブラリ管理でGomとか使っていないので、そのまま go get .. で対応しています。

docker-compose.ymlは、こんな感じです。

redirect:
  build: ./redirect
  log_driver: "json-file"
  ports:
    - "8080:8080"

メモ:rpmからjavaのアップデートをする

www.ipa.go.jp

java脆弱性が見つかったので、上げるときのメモ

Java SE Development Kit 8 - Downloads

oracleのサイトから、Accept License Agreement を選択状態にして 取得したいRPMのリンクを取得する

http://download.oracle.com/otn-pub/java/jdk/8u71-b15/jdk-8u71-linux-x64.rpm 今回は、こんな感じ。

qiita.com

上のサイトの参考に、rpmを取得する

wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u71-b15/jdk-8u71-linux-x64.rpm

取得できたら yum でインストール

yum localinstall jdk-8u71-linux-x64.rpm

alternativesで使うjavaのバージョンを選択する

$ alternatives --config java

There are 3 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
 + 2           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java
*  3           /usr/java/jdk1.8.0_71/jre/bin/java

Enter to keep the current selection[+], or type selection number: 3
$ alternatives --config javac

There are 3 programs which provide 'javac'.

  Selection    Command
-----------------------------------------------
   1           /usr/lib/jvm/java-1.7.0-openjdk.x86_64/bin/javac
 + 2           /usr/lib/jvm/java-1.8.0-openjdk.x86_64/bin/javac
*  3           /usr/java/jdk1.8.0_71/bin/javac

Enter to keep the current selection[+], or type selection number: 3

変更前

$ java -version
openjdk version "1.8.0_65"
OpenJDK Runtime Environment (build 1.8.0_65-b17)
OpenJDK 64-Bit Server VM (build 25.65-b01, mixed mode)

変更後

$ java -version
java version "1.8.0_71"
Java(TM) SE Runtime Environment (build 1.8.0_71-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.71-b15, mixed mode)

終わり。