DRYな備忘録

Don't Repeat Yourself.

【Elixir】バージョン管理しつつErlangとElixirをMacにインストールする

just want "Hello, World"?

brew install elixirで、ErlangもElixirも入ります。

参考

qiita.com

Prerequisite

  • JDK installed on your mac
  • brew install wget

Good Bye Elixir, installed via brew

brewで入れたelixirは消す

% brew uninstall elixir
% brew uninstall erlang

バイバイ

kerl for Erlang

github.com

% curl -O https://raw.githubusercontent.com/yrashk/kerl/master/kerl
% chmod a+x kerl
% sudo mv kerl /usr/local/bin
% kerl --help
% kerl list releases

install Erlang 18.0

% kerl build --help
usage: /usr/local/bin/kerl build <release> <build_name>
% kerl build 18.0 18.0-hello
Verifying archive checksum...
Checksum verified (232acb0c278ee05c8d787cbaf6399be5)
Extracting source code
Building Erlang/OTP 18.0 (18.0-hello), please wait...
Erlang/OTP 18.0 (18.0-hello) has been successfully built
% kerl list builds
18.0,18.0-hello

これは、

% ls -la ~/.kerl/builds
total 0
drwxr-xr-x  3 otiai10  staff  102  2  3 14:11 .
drwxr-xr-x  6 otiai10  staff  204  2  3 14:15 ..
drwxr-xr-x  4 otiai10  staff  136  2  3 14:15 18.0-hello
%

ここにビルドが入ってるってだけの意味。これをどっかにinstallして、それをどっかでactivateする

% mkdir -p ~/src/erlang/installations/18.0-hello
% kerl install 18.0-hello ~/src/erlang/installations/18.0-hello
Installing Erlang/OTP 18.0 (18.0-hello) in /Users/otiai10/src/erlang/installations/18.0-hello...
You can activate this installation running the following command:
. /Users/otiai10/src/erlang/installations/18.0-hello/activate
Later on, you can leave the installation typing:
kerl_deactivate
% . /Users/otiai10/src/erlang/installations/18.0-hello/activate
% which erl
/Users/otiai10/src/erlang/installations/18.0-hello/bin/erl
%

asdf

  • kiex <- f**k!
  • exenv <- s**t!
  • asdf <- no other way...

github.com

% cd && git clone https://github.com/HashNuke/asdf.git ~/.asdf
Cloning into '/Users/otiai10/.asdf'...
remote: Counting objects: 1041, done.
remote: Total 1041 (delta 0), reused 0 (delta 0), pack-reused 1041
Receiving objects: 100% (1041/1041), 125.29 KiB | 0 bytes/s, done.
Resolving deltas: 100% (511/511), done.
Checking connectivity... done.
% echo '. $HOME/.asdf/asdf.sh' >> ~/.zshrc
% source .zshrc

install elixir plugin for asdf

% asdf plugin-add elixir https://github.com/HashNuke/asdf-elixir
Cloning into '/Users/otiai10/.asdf/plugins/elixir'...
remote: Counting objects: 142, done.
remote: Total 142 (delta 0), reused 0 (delta 0), pack-reused 141
Receiving objects: 100% (142/142), 14.30 KiB | 0 bytes/s, done.
Resolving deltas: 100% (40/40), done.
Checking connectivity... done.
% asdf plugin-list
elixir

install elixir 1.1.1 via elixir-plugin for asdf

% asdf install elixir 1.1.1
/var/folders/_r/vhm2xvc152s2699tgzr9kr400000gn/T//elixir-precompiled-1.1.1.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   591    0   591    0     0    263      0 --:--:--  0:00:02 --:--:--   263
100 2858k  100 2858k    0     0   168k      0  0:00:16  0:00:16 --:--:--  336k
% asdf which elixir
No version set for elixir
% asdf list elixir
1.1.1
% asdf which elixir
No version set for elixir
% vi .tool-versions # elixir 1.1.1
% asdf reshim elixir
% asdf which elixir
1.1.1
%

Hello, Elixir!!

f:id:otiai10:20160203154727p:plain

固定

まあデフォルトでerlang 18でいいので、.zshrcに以下を追加

# erlang & elixir
. $HOME/src/erlang/installations/18.0-hello/activate
. $HOME/.asdf/asdf.sh

雑感

  • erlangもelixirも、エラーメッセージが不親切で、とりあえず嫌いだなって思いました
  • 動的型付けだし

DRYな備忘録として

追記

stackoverflow.com

【Postgres】function uuid_generate_v4() does not existとしかられる

問題

CREATE TABLE文を実行すると、(書いてて思ったけど、UUID v4、255byteもなくていいな)

CREATE TABLE "users" (
  "id" varchar(255)   DEFAULT uuid_generate_v4(),
  "name" text,
  PRIMARY KEY ("id")
)

以下のようにしかられる

ERROR:  function uuid_generate_v4() does not exist

uuid_generate_v4とは

PostgreSQL: Documentation: 9.5: uuid-ossp

The uuid-ossp module provides functions to generate universally unique identifiers (UUIDs) using one of several standard algorithms. There are also functions to produce certain special UUID constants.

参考

stackoverflow.com

解決

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

ログ

mydb=# CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
ERROR:  permission denied to create extension "uuid-ossp"
HINT:  Must be superuser to create this extension.

superuserでなければいけないようだ。入りなおして

mydb=# CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION
mydb=# SELECT uuid_generate_v4();
           uuid_generate_v4
--------------------------------------
 f7d5ac9b-a0e4-4f06-b172-30f9c2edc8f6
(1 row)

いけてる

DRYな備忘録

HerokuにDockerで動くアプリケーション(Go)をデプロイする

追記(2016/12/22)

任意のパッケージがインストールされた環境をHerokuにつくりたい、という目的でDockerを選択したけれど、Dockerfileに書かれているinstallコマンドは有効に動かない、みたいな情報を得ました。で、どうやらさいきんはbuildpackをうまいことして、任意のパッケージがインストールされた環境で動くアプリケーションをつくることができます、というのがこちらです↓

otiai10.hatenablog.com

以下、当エントリ原文

背景

  • apt-getなど、パッケージに依存する環境で動かすアプリのデモサイトを立てたい
  • herokuでDockerが動くらしい
  • Docker動くなら依存も解決したimageつくればいいだけっしょ

お断り: パッケージのインストールはできない

tl;dr

  1. heroku plugins:install heroku-docker
  2. アプリケーションを書く
  3. heroku create
  4. heroku docker:init
  5. heroku docker:release

参考

Herokuの'docker:release'の動き | SOTA

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

0. herokuのinstall

Heroku CLI | Heroku Dev Center ここからインストーラがダウンロードできるはず

1. heroku plugins:install heroku-docker

% heroku plugins:install heroku-docker
% heroku help docker

2. アプリケーションを書く

適当に、main.mainでサーバが立つようなアプリケーションパッケージを書いた

https://github.com/otiai10/marmoset/tree/master/examples/pygmy

3. heroku create

ご存知heroku create。これは、herokuというサービス上にネームスペースを確保するぐらいの意味合いしかない。

% cd %GOPATH/src/github.com/otiai10/marmoset
% heroku create pygmy-marmoset
https://pygmy-marmoset.herokuapp.com/

4. heroku docker:init

これが今回の最重要ポイント。とりあえず何も考えずに、

% heroku docker:init
 !    Error: Procfile required; aborting

おこられた。 Procfile というのが要る。これはheroku上で動くプロセスのエントリーポイントを定義するファイル。今回は、当該アプリケーションがbinでインストールされるはずということで、以下の内容でProcfileを作成。

web: pygmy

これでバイナリを叩いてもらう。webというキーで、pygmyという実行ファイルを指定している。

ふたたび

% heroku docker:init
 !    Error: docker image required: provide an --image flag or 'image' key in app.json

おこられた。app.jsonというのに、このアプリケーションの依存するdocker imageなどを指定する。今回のアプリケーションはデータベースなど使わないし、herokuが提供するgoのイメージだけでよいので、以下の内容でapp.jsonを作成。

{
    "image": "heroku/go"
}

ふたたび

% heroku docker:init
%

成功した。これによってこのプロジェクトに追加されたファイルは、じつは4つある。

  1. Procfile さっき書いたやつ
  2. app.json これもさっき書いたやつ
  3. Dockerfile おなじみのDockerファイル。app.jsonのimageをベースに書かれていることがわかる
  4. docker-compose.yml herokuのdockerイメージは、これをベースにupコマンドを打つと思われる

なので、ローカルで挙動を確認するために、いますぐ以下のコマンドを実行してください。

% docker-compose up web

これが成功したら、基本的にはheroku上でもこのアプリケーションは動くと思ってよい。

5. heroku docker:release

いよいよリリースする。ローカルのファイルをまんまリリースするので、git repositoryにpushしておく必要はない。

% heroku docker:release
Remote addons:  (0)
Local addons:  (0)
Missing addons:  (0)
Creating local slug...
Building web
Step 1 : FROM heroku/go
# Executing 2 build triggers...
Step 1 : COPY . /app/.temp
Step 1 : RUN /app/.cache/gotools/bin/compile
 ---> Running in 79ea8d976df3
godep go install -tags heroku ./...
 ---> f214d7b10780
Removing intermediate container a4907e576b66
Removing intermediate container 79ea8d976df3
Successfully built f214d7b10780
extracting slug from container...
creating remote slug...
language-pack: heroku-docker (heroku/go)
remote process types: { web: 'cd /app/user && pygmy' }
uploading slug [====================] 100% of 2 MB, 0.0s
releasing slug...
Successfully released pygmy-marmoset!
%

いけたっぽいので、

% heroku open

で確認。marmoset sample page、いけた。

つまずいたポイント

slug.tgz no such file

  • heroku/goイメージを使わずに、サーバのエントリポイントまで込み込みのDocker Imageをつくって、それを立てるつもりだった
  • herokuにdocker:releaseすると、docker-composeにしたがってイメージからslugファイルを取り出そうとしている?
  • 自前のイメージだとそれが無いので、docker-compose upの段階で以上のようにコケる

解決

app.json

{
-     "image": "otiai10/marmoset"
+    "image": "heroku/go"
}

Dockerfile

- FROM otiai10/marmoset
+ FROM heroku/go

/app/.temp/Godeps/Godeps.json: No such file or directory

  • /app/.cache/gotools/bin/compileの中で、godep go installしてるのまじ余計なんだけどで、Godeps/Godeps.jsonを探している。ふつうにgo installでもええんやで...

解決

% godep save

Godeps/Godeps.json

{
    "ImportPath": "github.com/otiai10/marmoset",
    "GoVersion": "go1.5.3",
    "Deps": []
}

Update Godeps/Godeps.json or choose a different version tag

  • ほら、godep使うからそういうことになんねん
  • タグ無しのheroku/goイメージは1.5.2なのに対して、自分のローカルでgodep saveを実行した環境のGoは1.5.3だったのでこうなる

解決

Godeps/Godeps.json

-    "GoVersion": "go1.5.3",
+    "GoVersion": "go1.5.2",

image指定のheroku/goheroku/go:1.5.2にしといたほうがよさそう

stat ./examples/pygmy/main.go: no such file or directory

  • Procfileで指定するエントリポイントを、go run ./examples/pygmy/main.goとしていた
  • heroku/goのDockerfileを見る限り、カレントdirを/app/.tempにCOPYとかしてる
  • なんかworkdirがどこなのかよくわからんし、main.goを叩くのはよくなさそう
  • また、/app/.cache/gotools/bin/compile 内では、 godep go install -tags heroku ./...が走っているので、プロジェクト内のmain.mainを置いて、installによってつくられたbinを叩いてもらったほうがよさそう

解決

Procfile

- web: go run ./examples/pygmy/main.go
+ web: pygmy

docker-compose.yml

web:
  build: .
-  command: 'bash -c ''go run ./examples/pygmy/main.go'''
+  command: 'bash -c ''pygmy'''
  working_dir: /app/user

Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch

解決

main.go

-      http.ListenAndServe(":8080", r)
+      http.ListenAndServe(":"+os.Getenv("PORT"), r)
}

雑感

好きなイメージを立てれるわけじゃないのだったら、repositoryにdocker-compose.ymlだけ置いといて、「あとお前ら勝手にupしてくれ」のほうがサンプルページとしての価値高いんじゃないかと思った。herokuでdocker動きました、やったー、以上の成果が無い気がする。

DRYな備忘録

MacでPostgresの停止

いろいろやったけど結局これでした

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

ログ

% pg_ctl stop
pg_ctl: no database directory specified and environment variable PGDATA unset

oh...

% pg_ctl stop -D /usr/local/var/postgres
waiting for server to shut down............................................................... failed
pg_ctl: server does not shut down
HINT: The "-m fast" option immediately disconnects sessions rather than
waiting for session-initiated disconnection.

oh...

liblog.seesaa.net

ユーザが接続してるのか

% pg_ctl stop -D /usr/local/var/postgres -m fast
waiting for server to shut down............................................................... failed
pg_ctl: server does not shut down

もうちょいなんか言えよ理由とか

killだ

% pg_ctl status -D /usr/local/var/postgres
pg_ctl: server is running (PID: 96268)
/usr/local/Cellar/postgresql/9.4.5_2/bin/postgres "-D" "/usr/local/var/postgres" "-r" "/usr/local/var/postgres/server.log"
% pg_ctl kill QUIT 96268
% pg_ctl status -D /usr/local/var/postgres
pg_ctl: server is running (PID: 96301)
/usr/local/Cellar/postgresql/9.4.5_2/bin/postgres "-D" "/usr/local/var/postgres" "-r" "/usr/local/var/postgres/server.log"

なんだこの復活劇

まじで殺す

% brew uninstall postgres
Uninstalling /usr/local/Cellar/postgresql/9.4.5_2... (3021 files, 40M)
% ps aux | grep postgres
otiai10         96362   0.0  0.0  2432772    668 s002  S+    3:52PM   0:00.00 grep postgres
otiai10         96337   0.0  0.0  2487700    644   ??  Ss    3:52PM   0:00.00 postgres: stats collector process
otiai10         96336   0.0  0.0  2623340   1480   ??  Ss    3:52PM   0:00.00 postgres: autovacuum launcher process
otiai10         96335   0.0  0.0  2631532    768   ??  Ss    3:52PM   0:00.00 postgres: wal writer process
otiai10         96334   0.0  0.0  2623340   1132   ??  Ss    3:52PM   0:00.01 postgres: writer process
otiai10         96333   0.0  0.0  2623340    824   ??  Ss    3:52PM   0:00.00 postgres: checkpointer process
otiai10         96331   0.0  0.1  2623340  14704   ??  S     3:52PM   0:00.03 /usr/local/opt/postgresql/bin/postgres -D /usr/local/var/postgres -r /usr/local/var/postgres/server.log
% pkill postgres
% ps aux | grep postgres
otiai10         96366   0.0  0.0  2432772    656 s002  R+    3:52PM   0:00.00 grep postgres
%

brew install postgres したら同じ現象。Macのlaunchctlとかでは

hack.aipo.com

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

なおった

Linuxサーバ上でdocker-composeを使う

ゴール

TL;DR

  1. Linuxサーバ上でdockerをインストールする
  2. Linuxサーバでdocker-composeをインストールする
  3. docker-compose.ymlを含むプロジェクトをcloneしてくる
  4. docker-compose upする

dockerをインストールする

記録あった。サンキュー俺

otiai10.hatenablog.com

docker-composeをインストールする

docs.docker.com

$ pip install docker-compose

まじ。pipで入るの。

% pip install docker-compose
# 略
error: could not create '/usr/local/lib/python2.7/dist-packages/compose': Permission denied

oh...

% pyenv versions
* system (set by /home/oppai/.pyenv/version)
  2.6.6
  3.4.1

あーそりゃあかんわ

% pyenv global 3.4.1
% pyenv rehash
% pyenv versions
  system
  2.6.6
* 3.4.1 (set by /home/oppai/.pyenv/version)

気を取り直して

% pip install docker-compose
# 略
Successfully installed docker-compose docopt PyYAML requests texttable websocket-client docker-py dockerpty six jsonschema
Cleaning up...
% which docker-compose
docker-compose not found
% pyenv rehash
% which docker-compose
/home/oppai/.pyenv/shims/docker-compose

やったぜ

docker-compose.ymlを含むプロジェクトをclone

今回はこれをcloneしてくる

github.com

docker-compose up

ビビってまずはbuildする

% cd hisyotan
% docker-compose build
mongodb uses an image, skipping
Building hisyotan
Step 1 : FROM ruby:2.2.3
2.2.3: Pulling from library/ruby
9ee13ca3b908: Pull complete
23cb15b0fcec: Pull complete
# 以下色々...
# buildできたっぽい

upする

% docker-compose up
mongodb  | MongoDB起動したよ的なログ
hisyotan | hisyotan起動したよ的なログ

うごいた

雑感

  • わりと簡単だった

DRYな備忘録

docker-machine envがこける

問題

docker-machine envすると、

There was an error validating certificates for host ~

と叱られる

Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host "192.168.99.100:2376": x509: certificate is valid for 192.168.99.101, not 192.168.99.100
You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'.
Be advised that this will trigger a Docker daemon restart which will stop running containers.

原因

言われてる通り

There was an error validating certificates for host "192.168.99.100:2376": x509: certificate is valid for 192.168.99.101, not 192.168.99.100

解決

言われてる通り

You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'.
% docker-machine regenerate-certs oppai

雑感

  • エラー出力はちゃんと読もう

docker-compose内でmongodbがFailed to connect to a master node at 0.0.0.0:27017となる

問題

docker-compose.yml

mongodb:
  container_name: mongodb
  image: mongo:3.2.0
  ports:
    - "27017:27017"
myapp:
  container_name: myapp
  build: .
  dockerfile: Dockerfile
  links:
    - mongodb # まずはもちろんこれが必要

main.rb(抜粋)

require 'mongo_mapper'
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = 'myapp-dev'

以下のようなエラーが出る

# 略(mongodbは普通に立ってる)
mongodb  | 2016-01-12T05:47:48.839+0000 I NETWORK  [initandlisten] waiting for connections on port 27017
mongodb  | 2016-01-12T05:47:48.839+0000 I NETWORK  [HostnameCanonicalizationWorker] Starting hostname canonicalization worker
myapp    | /usr/local/bundle/gems/mongo-1.12.5/lib/mongo/mongo_client.rb:417:in `connect`: Failed to connect to a master node at localhost:27017 (Mongo::ConnectionFailure)
myapp    |    from /usr/local/bundle/gems/mongo-1.12.5/lib/mongo/mongo_client.rb:656:in `setup`
myapp    |    from /usr/local/bundle/gems/mongo-1.12.5/lib/mongo/mongo_client.rb:179:in `initialize`
myapp    |    from /usr/local/bundle/gems/mongo-1.12.5/lib/mongo/legacy.rb:52:in `initialize`
myapp    |    from main.rb:20:in `new`
myapp    |    from main.rb:20:in `<main>`
myapp exited with code 1
# アプリケーションがモンゴディビにつながってない

調査

Note: Environment variables are no longer the recommended method for connecting to linked services. Instead, you should use the link name (by default, the name of the linked service) as the hostname to connect to. See the docker-compose.yml documentation for details.

解決

# ↓うごかんやつ
# MongoMapper.connection = Mongo::Connection.new('localhost', 27017)

# ↓うごくけどno longer the recommended methodなやつ
# MongoMapper.connection = Mongo::Connection.new(ENV["MONGODB_PORT_27017_TCP_ADDR"], 27017)

# ↓どういう理屈かしらんけどhostnameがdocker-composeのservice name
MongoMapper.connection = Mongo::Connection.new('mongodb', 27017)

MongoMapper.database = 'myapp-dev'

DRYな備忘録として