Docker for MacをやめてVM(Ubuntu 16.04)の中でDockerを動かして開発する
はじめに
どうも@konchanSSです。今回はDocker for Macをやめて、VMを立ててその中でDockerを動かして開発を進めた話をしたいと思います。
なぜDocker for Macやめたのか
- Docker for Macのvolumeのマウントが重い
- マウント遅い問題を解決するためにDocker syncを導入したが、同期が不安定
Dockerにdocker-syncを導入して遅い問題を解決する - こんちゃんブログ
準備
今回VMの環境を構築するのにVirtualBoxとVagrantを使用するのでインストールしていきます。
- VirtualBoxのインストール
Downloads – Oracle VM VirtualBox
- Vagrantのインストール
Download - Vagrant by HashiCorp
VM(Ubuntu 16.04)設定のセットアップ
まずはVM用のディレクトリを用意しましょう。
先ほどいれた vagrant
コマンドを使ってインスタンスの初期化と生成をします。
$ vagrant init bento/ubuntu-16.04 $ vagrant up
上の vagrant init
をしたディレクトリに Vagrantfile が生成されます。
ゲストOSの設定はここに書いて再起動することで反映されるようになります。
インスタンス立ち上げ際のはまりポイント
ホストとゲスト間のGuestAdditionsのバージョンが違うとVMの起動やSSHできないことがあるので vagrant vbguest
入れておくと便利です。
詳しくはこちらの記事がわかりやすいので詰まった方は読んでみてください。
qiita.com
また、もともとVagrantもしくはVirtualBox使ってたよって人はバージョンが違うと怒られが発生したりするので最新のやつを入れときましょう。
GUIとデスクトップ環境の設定
Ubuntu GUIも必要なのでその設定を追加していきますが、 生成されたVagrantfileにはあらかじめGUIなどの設定がコメントアウトされた状態であるのでそのコメントアウトを外しましょう。
config.vm.provider "virtualbox" do |vb| # Display the VirtualBox GUI when booting the machine vb.gui = true # Customize the amount of memory on the VM: vb.memory = "1024" end
あとは vagrant ssh
コマンドを使ってVMの中に入り、Ubuntuのデスクトップ環境をインストールしましょう。
$ vagrant ssh $ sudo apt-get install ubuntu-desktop
Ubuntu大地に立つ
以上の設定が一通り終わったら再起動して動かしてみましょう。
$ vagrant reload $ vagrant up
UbuntuにDockerを入れる
Ubuntuを起動することがあとはDockerを入れるだけですね。
必要なパッケージのインストールします。
$ sudo apt-get update $ sudo apt-get install apt-transport-https ca-certificates
GPG鍵の取得します。(これないとapt-get updateできなくなる)
$ sudo apt-key adv \ --keyserver hkp://ha.pool.sks-keyservers.net:80 \ --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
依存パッケージのインストールします。
$ sudo apt-get update $ sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
sourceの更新します。
$ echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
これでdockerのインストール準備が整ったのでインストールしていきます。
$ sudo apt-get update $ sudo apt-get install docker-engine
apt-get update
忘れるとうまくいかなかったりするのでコマンド叩いてみてください。
これでインストールが終わると docker
コマンドが使えるようになっています。
vagrant@vagrant:~$ docker Usage: docker COMMAND A self-sufficient runtime for containers ...
毎回docker叩く時にsudo打つのめんどくさい
グループに追加しておきましょう。
$ sudo usermod -aG docker $USER
最後に
これであとは好きなエディター入れたりして開発進めていけそうです!
本当はDocker for Macが快適に使えるようになると良いんですけどね〜
Dockerにdocker-syncを導入して遅い問題を解決する
はじめに
どうもこんちゃんです。最近開発環境にDockerを使用するようになって、いざ使ってみるとdocker for Macだと同期がクソ遅い問題(ページのロードで20秒)が発生してイライラしてたのが、docker-syncの導入で遅い問題が解決されたのでそれについて話していきたいと思います。
docker sync
docker sync はホスト側のファイルを rsync
や unison
もしくは native_osx
を使って転送するという仕組みを導入しています。なので、重たくなる原因でもあったホスト側のディレクトリをマウントしていません。
github.com
いざ導入
インストール
公式によるとこれだけ
gem install docker-sync
docker syncの設定を追加する
下記の docker-compose.yml
を例に設定を進めていきます。
docker-compose.yml
version: '2' services: app: image: test volumes: - $DEV_DIR : /var/dev command: yarn build:dev
まず、docker-sync.yml
というファイルを追加します。
わかりやすくするためにdocker-syncの設定は docker-sync.yml
書いていきますが、docker-compose.yml
自体に書いていくこともできます。
僕の周りではDockerをLinux仮想環境を自分で用意してその中で動かしている人も一定数いたため、
既存の人は既存のまま使えるようにdocker-compose.yml
はそのままにDockerの上書き用のymlである docker-compose-dev.yml
に設定を追加していきます。
docker-sync.yml
version: '2' syncs: sync-volume: src: $DEV_DIR sync_strategy: native_osx sync_excludes: [ '.git', '.idea', '.vagrant' ]
docker-sync.yml
では、まず src
でホスト側のディレクトリを指定します。
sync_strategy
では同期方法を選択できます。今回は native_osx
という方法を選択しました。 native_osx
はUnison
とDocker用のファイル共有システムである OSXFS
の組み合わせです。
sync_excludes
では同期しないファイルもしくはファイル形式を配列で渡すことができます。指定されたファイルもしくはファイル形式は同期対象外になります。
* sync-volume
は任意の名前で構いませんが、ここでの名前がDockerの名前付きvolumeとして作られます。
docker-compose-dev.yml
version: '2' volumes: sync-volume: external: true services: app: volumes: - sync-volume:/var/dev
docker-compose-dev.yml
では、docker-sync側で作るvolume
を external
として宣言し、それを sync-volume:/var/test
としてマウントするように設定しています。
設定は以上になります。
とりあえず動かしてみようぜ
設定追加できたらとりあえず動かしてみましょう。
docker-sync-stack start
で動きます。
内部的にやっていることはdocker-syncを起動してupしてるだけらしい
内部的にはこういうこと
docker-sync start docker-compose -f docker-compose.yml -f docker-compose-dev.yml up
2.2 sync stack commands · EugenMayer/docker-sync Wiki · GitHub
ここで指定している -f
オプションが先ほど言っていた上書き設定のオプションで、ここでファイルを複数指定すると指定された順番に設定を反映します。
なので docker-compose.yml
-> docker-compose-dev.yml
という順番に設定を反映していきます。
同じ設定があった場合は後に反映された設定が前の設定を上書きされるようになります 。
このあとこの上書きした項目の1つが原因でえらいことになる
動かしてみると...
実際に動かしてみると 20秒ぐらいだったページのロードが1秒ぐらい になりました。やっほー!めっちゃ快適やんけーって思いながら開発を進めていると.....
ファイルの変更が反映されてないぞ という問題が発生しました。実は先ほど上書きした設定の中に問題の原因が隠れていました。
それは volumeの設定です 。
下記のissueコメントなどを参考に話をしていくと、どうやらupしたymlが複数指定されていると volume
は上書きされないっぽい。
Your issue is, that you think you can override volume defintions, but you cannot. So ${SYMFONY_APP_PATH}:/var/www/symfony stays in charge and supersync-sync:/var/www/symfony:nocopy never gets used.
volumeオーバーライドされない問題を解決しよう
ここでvolumeをオーバーライドされない問題を解決する手段は2つあります。
そもそも、ymlの設定を複数に渡ってせずに docker-compose.yml
に統一してしまう。もしくは、 volumes
の設定を他の設定ファイルに切り出すことです。
今回は後者の volumes
の設定を切り出すことを選択しました。(先ほどにもあげたようにdocker-syncを使わなくても良いユーザも一定数いるため)
Dockerにはデフォルト上書きしてくれるymlファイルがある
では、volumes
の設定をどこに書くのかというと、Dockerではデフォルトで2つのファイルを読みます。
それは docker-compose.yml
とdocker-compose.override.yml
です。 今回はこの docker-compose.override.yml
に volumes
を切り出しました。
docker-compose.override.yml
version: '2' services: app: volumes: - sync-volume:/var/dev
これでdocker-syncを使わない人と使う人で特に意識することなく利用できそうです。
サービスの拡張と Compose ファイル — Docker-docs-ja 17.06.Beta ドキュメント
追記(2018/7/5)
volumeオーバーライドされない問題はどうやら解決されたらしいです。(下記issue参照)
Docker Compose 1.17 fixed volumes override 🕊 · Issue #507 · EugenMayer/docker-sync · GitHub
しかし、同時に同期が安定的でないというissueもあります。 僕の方でも同期がうまくいかないという場面が度々見受けられました。 とりあえずこの問題が解決次第また記事に追加していこうと思います。
Synchronization stops. · Issue #517 · EugenMayer/docker-sync · GitHub
IntelliJで利用するReact Nativeのスニペットを作った
React NativeにFlowを導入する
こんにちは、こんちゃんです。
最近React Nativeを書き始めて、その中でFacebook製の静的解析ツールであるFlowを導入した時の話をしようと思います。
はじめに
React NativeでFlowを選んだ理由としては導入のしやすさとメルカリの記事を見たからでした。
環境 2018/3/8現在
react-native ver 0.54.0
yarn ver 1.5.1
flow-bin ver 0.66.0
いざ導入
公式のドキュメントを見てやれば余裕やろ(鼻ほじ)って思ってました。
ドキュメントに従って yarn run flow
(タンッ!) って打つと大量のエラーが押し寄せてきました。
なんじゃこれーーって思って見ると node_module
が解析対象内になっていたらしくそこでエラーが出ていました。
とりあえず、node_moduleを解析対象外にするために .flowconfig内の[ignore]セクションの設定をしました。
[ignore] .*/node_modules/.*
これで大丈夫かと思ってもう一度走らせて見るとまた別のエラーが。。。
node_moduleを解析対象外にしたせいでreact-nativeのモジュールが見つからないと言われてしました。
解決策
まず、libdefs.jsというファイルを作成しましょう
touch libdefs.js
libsdef.jsでは必要なライブラリの定義を行います。
declare module 'react-native' { declare module.exports: any; }
そのあとは.flowconfig内の[libs]セクションに設定を追加します。
.flowconfigファイルの[libs]セクションは、コードの型チェック時に指定されたライブラリ定義をインクルードします。
また、libdefs.js自体は静的解析の対象にしたくないので[ignore]セクションに追加します。
[ignore] .*/node_modules/.* ./libdefs.js [libs] ./libdefs.js
これで yarn run flow
を走らせると
今度はうまくいきました。 次回以降ではReact Nativeで開発していく上での困ったことやTipsを記事にできればと思っています。
内定先のインターンでTAをしてきた話
今日は内定先で行われたインターンでTAをしてきたのでTA業で思ったことについて書いていきたいと思います。 読者が今度どこかのイベントなどでTAなどをするときに参考にしてもらえると幸いです。
はじめに
僕は内定先であるVOYAGE GROUPで行われるTreasureというインターンに参加してきました。 Treasureは「Go言語を使って学ぶ、価値のあるもの創りとチーム開発」をテーマとして3週間でユーザーにとって価値あるサービスをトップエンジニアのサポートを受けつつ開発します。インターンについての詳しいことは下記のリンクに書いてあるので割愛します。 今回僕はTreasureの中でも前半8日間で行われるトップエンジニアによる講義のTAをしてきました。僕自身去年のTreasureに参加しています。 TAとして参加したのも去年の経験からTreasure参加生にとってかけがえのない経験をするサポートをしたいという思いがあったからというのもあります。 voyagegroup.com
基本的な業務内容
TAとしての基本的な業務は前半に行われる講義の内容に関して参加者がわからないところがあった場合や演習の際に詰まったときにサポートをして参加者が滞りなく講義を受けれる状態にすることです。
講義について
Treasureの講義内容としては
1日目 ~ 3日目 Goの講義 by @suzu_v
4日目 Web APIの講義 by @gomachan46 @brtriver
5日目 中間課題
6日目 中間課題の発表、セキュリティの講義 by @co3k
7日目 データベースの講義 by @hironomiu @larufa @takeru0911
8日目 チーム開発の講義 by @katzchang @ara_ta3
となっています
Web APIの講義は公開されています speakerdeck.com
わからなくてもなかなか質問できない子がいる
Treasureの参加者には様々なバックグラウンドの人がいるので、人によってスッと理解できる子もいれば初めて聞く内容だという子もいます。 こちらとしてはわからなかったら気軽にTAに質問してくださいと言っていますが、なかなか質問できない子はいます。また、わからないことがわからないという子も一定層いるのでそういう子たちが置いていかれないようにTAがサポートしてあげる必要があります。具体的には
参加者に「今何してるの?」って声をかけてみる
定期的に参加者のことを見回るのもいいのですが、参加者が警戒していて質問できない場合もあるのでこちらから警戒をといてあげるという意味で気軽に声をかけてみると意外と詰まっていたりします。
わからなくても一緒に悩んで解決方法を探す
TA自身も人なので質問された内容全てに対して答えられない場合もあると思います。そういう場合はわからないと突き放すのではなく、質問者と一緒に調べたり、解決策を探ることで少しでも質問者の不安を解消してあげましょう。 相談に気軽に乗る姿勢 ってすごい大事だと思いました。
講師に参加者の状況を報告する
講義を受けている人数が多いとどうしても参加者側からの反応が薄かったりするので、TAが講師にどのくらい参加者が理解しているかなどを都度報告してあげることで講義がより良いものになると思いました。また、前もってTAには次の講義内容を伝えておくことで講義全体を把握しつつ、詰まりそうなポイントがわかるのでサポートしやすく講義がスムーズになるのではないかと思いました。
さいごに
色々ありましたが、Treasure参加生にとって最高の3週間になって欲しいです。また、今後Treasureに応募しようとしている人も、僕たちVOYAGE GROUPのクルーは参加者にとってかけがえのない経験になるよう全力を尽くしているので是非受けてみてください。
SupervisorでGolangで書かれたアプリケーションのデーモン化をした話
今回は前回の記事に関連してGoで書かれたアプリケーションをSupervisorを使ってデーモン化した時の話を書いていきたい思います。
はじめに
開発環境
- CentOS 7.3
- Go 1.8
- Supervisor 3.3.3
前提条件
Goのアプリケーションがデプロイされている、 go build
したバイナリがある
Supervisorとは
そもそもSupervisorってなんぞや?っていう人もいると思うので説明します。
Supervisorはpythonで書かれているプロセス管理ツールです。
Supervisorは設定ファイルをちょこっと書くだけで簡単にデーモンプロセスの生成ができるのでとても楽です。
Supervisor: A Process Control System — Supervisor 3.3.3 documentation
インストール
yumでインストールしておきましょう
yum install supervisor
設定ファイルに新しく追加する
Supervisorがinstallされると /etc/supervisord.conf
が作成されています。これが設定ファイルなので編集していきましょう。
設定ファイルの中にはsupervisor自身の設定も含まれています。
早速ですが、これが完成形です。詳しい内容については後述していきます。
※ 今回はSupervisor自身の設定は省きます。
;/etc/supervisord.conf [unix_http_server] file = /run/supervisor.sock chmod = 0777 chown= root:root [supervisorctl] serverurl = unix:///run/supervisor.sock [supervisord] logfile=/var/log/supervisor/supervisord.log logfile_maxbytes=50MB logfile_backups=10 loglevel=info pidfile=/var/run/supervisord.pid nodaemon=true minfds=1024 minprocs=200 user=root ehildlogdir=/var/log/supervisor/ [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface ; Goアプリの設定 [program: sample] command=sample-go-app autostart=true autorestart=true user=sample-user startsecs=5 redirect_stderr=true stdout_logfile=/var/log/sample-go-app.log
[program:]
アプリをデーモン化する際はこのprogramセクションを使用します。
command
ここで設定したコマンドが起動時に実行されるようになります。
Goはビルドするとそれ自体で実行可能なバイナリになるのでここではバイナリを指定します。
autostart
Supervisor起動時に自動的にprogramセクションが起動するように設定できます。
autorestart
プロセスが死んだ時にSupervisorが自動的に再びプロセスを立ち上げるように設定できます。
user
programセクションを実行するユーザーを指定することができます。
redirect_stderr
エラー出力を標準出力にリダイレクトできます。
stdout_logfile
標準出力のログをファイルを指定することで保存できます。
Supervisorを起動してみる
設定を追加し終わったら次は実際に起動してみましょう。
supervisord
を叩くと起動することができます。
もし、本当に起動しているのか確認したい場合は supervisorctl
を叩くと確認することができます。
Supervisor自身の自動起動設定
最後にSupervisor自身を自動起動できるようにしましょう。
ありがたいことに起動時のスクリプトを書いてくれている方がいたのでこれをcloneしてきてコピーしましょう
git clone git://github.com/Supervisor/initscripts.git cd initscripts/ cp redhat-init-jkoppe /etc/init.d/supervisord cp redhat-sysconfig-jkoppe /etc/sysconfig/supervisord chkconfig --add supervisord chkconfig supervisord on
Golangで書かれたWebアプリをWerckerでVPSにデプロイした話
今回はGoで書かれたWebアプリケーションをWerckerを使ってビルドとデプロイをしたのでその時のWerckerのデプロイ設定などについて書いていきたいと思います。
はじめに
開発環境
前提条件
Werckerの全体像
WerckerのPipelineという概念があります。
下記画像のようにBoxという仮想環境の中でBuildフェーズとDeployフェーズが順番に実行され、その中でstep と呼ばれる個別の処理で発生します。
今回はmasterにpushされたタイミングでBuildフェーズとDeployフェーズが実行されるように設定します。
Wercker側でDeployフェーズの追加
werckerのアプリケーションのページに移動します。 開くとWorkFlowsというタブがあるのでそれを選択します。
続いて選択して移動したページにAdd new pipelineと書いてあるボタンがあるので選択します。
新しいpipelineのNameを入力します。今回はDeployフェーズの追加なので deploy と入力しましょう。
YML Pipeline Nameも同様で良いです。
Hook Typeですが、今回はBuildフェーズが通った後にDeployフェーズを実行するため Default を選択しましょう。
必要な項目を全て入力したら Create しましょう。
作成すると下記画像のようにdeployが追加されるので確認してみてください。
秘密鍵の設定
VPSにログインするために秘密鍵の設定をする必要があります。先ほどの画像の deploy をクリックして詳細のページに飛びます。
詳細のページに移動すると Generate SSH Keys というボタンがあるのでそれを押すと秘密鍵の生成ができます。
鍵の名前は自由でいいのですが、今回は DEPLOY_KEY
とします。
RSAですが、2048と4096がありますが、どちらでも構いません。
Create を押すと公開鍵と秘密鍵のペアがこのように生成されます。
DEPLOY_KEY_PUBLIC
は後でVPSの方で鍵を設定するのに必要なのでコピーしておきます。
VPS側の設定
VPSの方にSSH接続し、今回Deployする用のユーザーを作成します
#今回はdeploy用のユーザーはwerckerとします $ adduser wercker # wheelグループにwerckerを追加 $ gpasswd -a wercker wheel $ su - wercker $ cd ~/ $ mkdir .ssh # ここで先ほどコピーした公開鍵を貼り付ける $ vi .ssh/authorized_keys $ chmod -R 700 .ssh $ chmod 644 .ssh/authorized_keys # deploy用のディレクトリの用意 $ mkdir /srv/rsync $ chmod 755 /srv/rsync
これで一旦VPS側の設定は終わります。
wercker.ymlにDeployフェーズを追加
次にwercker.ymlを編集していきます。
box: golang build: steps: - setup-go-workspace #何かしらの処理(今回はBuildフェーズの詳細については省きます) deploy: steps: # デプロイするファイルの表示 - script: name: deploy info code: find . # VPSのIPもしくはドメインを入力しましょう - add-to-known_hosts: hostname: IPアドレスもしくはドメイン名 #ここでは先ほど登録した鍵の変数名を入力しましょう - add-ssh-key: keyname: DEPLOY_KEY # 今回はrsyncというファイル同期ができるコマンドを使って転送します - install-packages: packages: rsync # 転送 - script: name: rsync code: rsync -azvv --delete -e "ssh -v -o StrictHostKeyChecking=no -o UserKnownHostsFile=no" $WERCKER_ROOT/* wercker@ IPアドレスもしくはドメイン名 :/srv/rsync
以上でwercker.ymlの設定は終了です。
Buildフェーズが通ったらDeployフェーズが実行されるようにする
これまででほとんどの設定は終了しました。あとはBuildフェーズ後にDeployフェーズが実行されるようにすればいいだけです。
もう一度アプリケーションのページから WorkFlows のページに飛んでください。
WorkFlowsのページから下記画像のように+ボタンを押してpipelineを追加することができます。
これはWorkFlowと言って1つのCIのプロセスを複数のパイプラインに分割することのできる機能です。これを使ってbuildフェーズの後にdeployフェーズの追加をしてあげます。
on branch でDeployフェーズが実行されるブランチを決めることができます。今回はmasterにします。
Execute pipeline はdeployを選択しましょう。
これでGithubからmasterにpushされたらdeployされるようになりました。
追記
デプロイ用に作ったユーザーのロックされているとデプロイできないです。
passwd -S デプロイ用のユーザー
passwdコマンドでユーザーがロックされていないか確認して見ましょう