LoginSignup
68
61

More than 5 years have passed since last update.

herokuでdockerコンテナを動かす(2015年10月版)

Last updated at Posted at 2015-09-26

以前heroku上でhubotのdockerコンテナを動かす記事を書いたのだが、2015年8月にアップデートがあり、docker-composeに対応した。
これに伴い、heroku toolbeltのdocker pluginからはdocker:startが無くなり、普通にdocker-compose upするだけでローカルで動作させることが可能になった。(前述の記事は意味の無い文章の羅列と化した。)

なお、内容は公式のGetting Startedをやるだけだが、途中自分がよく分からなかった所は詳しく書こうと思う。
今回はnodejsでやるけど、Railsとかでも多分だいたい一緒。

準備

あらかじめ、以下のものをインストールしておく必要がある。

  • docker
  • docker-compose
  • Heroku Toolbelt

gitとかはもう書かなくてもいいよね。

あと、Node.js/Memcachedのサンプルリポジトリを引っ張ってきておく。
これはmemchachedを操作する簡単なwebアプリ。

$ git clone https://github.com/RedisLabs/memcachedcloud-node-sample.git

heroku toolbeltのdocker pluginも導入しておく。

$ heroku plugins:install heroku-docker

リポジトリの構成を確認

package.json

npmのパッケージを管理するためのファイル。

app.json

docker:initのために必要なファイル。色々書いてあるけど、重要なのは以下の2つ。

image

docker hubのどのimageを利用するかを指定する。
サンプルだと以下の部分。

app.json
...
"image": "heroku/nodejs",
...

重要な点として、herokuで動かすdocker imageは何でも良いわけではない。
基本的にはherokuが提供しているimageを用いるが、自分でheroku対応のimageを作ることも可能。(→ Modifying the Dockerfile)
公式に提供されているimageの一覧はこちら

addons

heroku上で利用するアドオン名を指定する。
サンプルだと以下の部分。

app.json
  ...
  "addons": [
    "memcachedcloud:30"
  ]
}

Procfile

heroku上で実行するコマンドを指定するファイル。

web: node web.js

ローカルで動かしてみる

まずは以下のコマンドを入力。

$ heroku docker:init

このコマンドは、Procfileやapp.jsonに従って、Dockerfileとdocker-compose.ymlを生成する。

まずDockerfileの中を見てみると、単にapp.jsonで指定したimageを取ってくるだけであることがわかる。

FROM heroku/nodejs

次に、docker-compose.ymlだが、ここではwebshellという二つのコマンドの定義と、memchachedcloudというエイリアス名のmemchachedコンテナを立ち上げるようになっている。

docker-compose.yml
web:
  build: .
  command: 'bash -c ''node web.js'''
  working_dir: /app/user
  environment:
    PORT: 8080
    MEMCACHEDCLOUD_SERVERS: 'memcachedcloud:11211'
  ports:
    - '8080:8080'
  links:
    - memcachedcloud
shell:
  build: .
  command: bash
  working_dir: /app/user
  environment:
    PORT: 8080
    MEMCACHEDCLOUD_SERVERS: 'memcachedcloud:11211'
  ports:
    - '8080:8080'
  links:
    - memcachedcloud
  volumes:
    - '.:/app/user'
memcachedcloud:
  image: memcached

webでは、Procfileで指定したコマンドを実行するコンテナを立ち上げる。
それに対してshellは単にbashを実行するので、任意のコマンドを実行できる状態になる。

また、app.jsonでaddonsにmemchachedを指定したので、環境変数とmemchachedコンテナも自動的に追加されている。
MEMCACHEDCLOUD_SERVERのホスト名に単にmemcachedcloudと指定するだけで接続できるのがよくわからなかったが、dockerのlinkオプションは/etc/hostsに指定したエイリアス名で追加するようだ。(環境変数を追加するだけだと思ってた……)

さて、生成されたファイルの確認が終わったので、おもむろにサーバを立ち上げてみる。

$ docker-compose up web

するとweb_1 | Listening on 8080みたいなのが出るので、http://localhost:8080にアクセス。

こんな感じの画面が表示されれば、正常に動作している。

Screenshot 2015-09-26 13.48.17.png

Actionsのリンクを適当にクリックしてみて、memchachedと繋がっているのを確認する。

herokuにdeployする

deployは極めて簡単で、以下のコマンドを実行するだけ。

$ heroku docker:release

らくちん。

ところでMEMCHACEDCLOUD_USERNAMEって何やねん

web.jsを見ていると、最初にmemjsのclientを以下のように生成している。

web.js
var client = memjs.Client.create(process.env.MEMCACHEDCLOUD_SERVERS, {
  username: process.env.MEMCACHEDCLOUD_USERNAME,
  password: process.env.MEMCACHEDCLOUD_PASSWORD
});

MEMCACHEDCLOUD_USERNAMEとか、deployしたらherokuが勝手に設定するのは分かるけど、ローカルではいつ設定したんだよ…と思ったら、ローカルでは普通にundefinedだった。
memjsの仕様として値が入ってなかったら単に無視されるのかなーと思ってるけど、ちゃんと調べてない。

感想

今回の変更で個人的には以下の2点が嬉しいポイントだと感じている。

  • heroku toolbelt無しでも、docker-composeがあればローカルで動く
  • heroku add-onsをあまり意識しなくてよくなった

なので、 herokuのことが嫌いになっても別の適当な場所で動かせる
dockerのメリットであるポータビリティが活かせるようになった。
自前のサーバでもいいし、OpenShiftもdocker対応したので動くんじゃないかなーたぶん。
とりあえずheroku対応のdocker imageでアプリ作っとけば幸せになれるんじゃないかと思います。

68
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
61