satococoa's blog

Web や iOS アプリを作るエンジニアの日記です

Angular で作った SPA を Docker の nginx を使って動かす

このサイトにある手順をまるっと使わせていただきました。

medium.com

追加したのは以下の3ファイル

.dockerignore

node_modules

nginx.conf

server {
  listen 80;
  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    try_files $uri $uri/ /index.html =404;
  }

  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }
}

Dockerfile

FROM node as build-stage
WORKDIR /app
COPY package*.json /app/
RUN npm install
COPY ./ /app/
ARG configuration=production
RUN npm run build -- --output-path=./dist/out --configuration $configuration

FROM nginx
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build-stage /app/dist/out/ /usr/share/nginx/html

以下の手順でビルド & 公開

$ docker build -t <IMAGE_TAG> .
$ docker run -p 8080:80 <IMAGE_TAG>

これで localhost:8080 でアクセスできる。

一般公開だったら Firebase Hosting とかで良いのですが、今回は社内イントラ内での公開だったのでこのようにしました。

Kubernetes の CronJob で bundle update して PR 投げてくれるようにした

bundle update を定期的に実行し差分がある場合は pull request を投げる、というよくある仕組みを k8s の cronjob で実装しました。

clone ( or pull ) -> 何らかの処理を行う (ここでは bundle update) -> [差分があったら] -> commit & push -> Pull Request を出す、という処理は今回の bundle update に限らず汎用的に使えるものだと思うので、コマンドラインツールとして Go で実装しました。

github.com

あとは任意のコンテナの中で上記 prbot のバイナリを取得して実行すれば OK。

以下のような manifest を書きます。 Clone や PullRequest の送信に GitHub の Personal Access Token が必要になるので取得して Secrets として登録しておいてください。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: bundle-update
spec:
  schedule: "0 2 * * WED" # cron式
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - image: library/ruby
            name: ruby
            command: [ "/bin/sh" ]
            args:
            - "-c"
            - |2
              set -e
              wget https://github.com/satococoa/prbot/releases/download/v${PRBOT_VERSION}/prbot_${PRBOT_VERSION}_linux_amd64.tar.gz
              tar -xvzf prbot_${PRBOT_VERSION}_linux_amd64.tar.gz
              mv prbot /bin/prbot
              chmod +x /bin/prbot
              gem install bundler
              prbot
            env:
            - name: PRBOT_VERSION
              value: "0.1.2"
            - name: GITHUB_REPOSITORY
              value: "org/repository"
            - name: GITHUB_ACCESS_TOKEN
              valueFrom:
                secretKeyRef:
                  name: bundle-update-secret
                  key: githubAccessToken
            - name: BASE_BRANCH
              value: "master"
            - name: COMMAND
              value: "bin/bundle update"
            - name: TITLE
              value: "pull request のタイトル"
            - name: AUTHOR_NAME
              value: "prbot"
            - name: AUTHOR_EMAIL
              value: "prbot@example.com"

以上です。 使うイメージについては native extension を含む gem なんかが含まれる場合は library/ruby じゃビルドできないかもしれないので、実際にアプリケーションを動かすコンテナで実行する方が確実だと思います。 library/rubybuildpack-deps を基に作られていて mysql-client なんかは入ってるため、僕の場合は library/ruby で大丈夫でした。

学び

  • GoReleaser が超便利。
    • マルチプラットフォーム向けにビルドして バイナリを GitHub の Release にアップロードして、さらに Docker イメージとか Homebrew 用のレシピとかも作れちゃう。
  • buildpack-deps という Docker image を知れた。

複数の pod で並列に kubectl exec を実行する

こんな感じで OK

kubectl get pods -l name=app -o jsonpath="{.items[*].metadata.name}" | xargs -n1 -P4 -I{} kubectl exec {} bin/rails r 'Rails.logger.info(Rails.env)'

xargs の P オプションの値は最大プロセス数。

参考: JSONPath Support kubernetes.io

Rails 5.1 で rails test と rails test:system の RAILS_ENV に関する挙動の違いメモ

RAILS_ENV が指定されている場合 rails test コマンドと rails test:system コマンドの挙動が違う。 おそらくそれぞれ rails command として実装されているか、rake タスクとして実装されているかによる違い。

  • rails test で実行 → RAILS_ENV が test に上書きされて実行される
  • rails test:system で実行 → RAILS_ENV に指定された環境で実行される
    • rails test:db も同様

docker-compose.yml で RAILS_ENV=development としていたコンテナでシステムテストを実行して気づいた。 今はテスト実行のコマンドを rails test test/* とすることで回避している。 (ちなみに rails testシステムテストを実行しないのは rails の意図した動作である。)

これは rails の意図した動作なのか、それとも意図していない動作なので rails/rails を直すべきなのか、またはコンテナに RAILS_ENV を指定しないべきなのか判断がつかなかったけれども、あとで忘れるといけないのでメモだけ残す。

Firebase Unity SDK を .NET 4.6 で使おうとしたら Task でハマった

@see https://groups.google.com/d/msg/firebase-talk/2w1Lk62VIcg/1ysauzl9CwAJ

2018-06-13 追記 Unity 2018.1 以降に Firebase SDK 5.0.0 以降を入れることで特に苦労することなくちゃんと動作させることができるようになりました。IL2CPP とかその辺りで不具合があったみたい?

追記終わり

2017-10-27 追記

コード中で async/await 使わない場合は (ContinueWith でコールバック書いた場合は) 以下の対応をしなくても、普通に使えた。 合わせて Firebase SDK 4.2.1 にアップデートしているのでそちらの影響かも。。不確かでアレですが、メモとして残しておきます。

追記終わり

どうも System.Threading.Tasks.Task が古い .NET では提供されていないため、Firebase Unity SDK 側が同梱してくれていて、それ関連でうまくいってなかった。

最初に出てたのはこんなエラー。

The type 'Task' exists in both 'Unity.Tasks, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' [Assembly-CSharp]

で、上記 URL の指示に従って Unity 上で作業

  • Assets/Parse/Unity.Tasks を削除
  • Assets/Parse/dotNet45/Unity.Tasks を選択してインスペクタから以下のように設定して有効化

f:id:satococoa:20171025160009p:plain

これで動いた。

第22回 RubyMotion もくもく会に参加した

rubymotionjp.connpass.com

東京開催は約1年と8ヶ月ぶり?となる RubyMotion もくもく会に参加しました。 今回は @youchan さん主催の元、ユビレジさんのオフィスを使わせていただく形でリスタートしてます。

僕は最近はほとんどクライアント側のコードに触れておらず、Web と API ばかり開発しています。 ということで今回はすっかり古くなってしまった知識をアップデートするとともに、RubyKaigi での @lrz さんの発表 の動画を見てました。

ここ2年くらいの間に変わったことなどを箇条書きで。

  • 料金プランが変わり、無料版 (starter) や Professional 版 が出ています。 Download | RubyMotion
    • Starter の制限としては iOSAndroid の最新の安定版しかサポートされていなかったり、スプラッシュスクリーンがカスタマイズできなかったり、、という程度です。
  • 対応プラットフォームが増えています。 iOS, Android, OSX, watchOS, tvOS に対応しています。

久しぶりだったので以前自分が書いた チュートリアル記事 を参考に簡単なテーブルビューにデータを表示するだけのアプリを作ってみましたが、特にハマりどころもなく普通に動きました。

iPhone 6 が出て AutoLayout & Storyboard がほぼ事実上必須 (しかも結構大変) となったあたりで、「どうせ Xcode 開くし長い時間 Xcode で作業するならそのまま ObjC / Swift で書けばいいかー」と思ってしばらく RubyMotion から離れていたのですが、iOS9 で UIStackView が来たおかげで Storyboard でごにょごにょ頑張る部分がだいぶ楽になったのではーと思っています。

そうすると相対的にロジックの実装に集中出来る時間も増えるわけで、また RubyMotion を見直してみてもいいかな、と思いました。

pplog の Push通知 (Apple Push Notification Service) の証明書を更新した

年に一回やらないと Push 通知が送れなくなっちゃうあれですね。

新しく生成してみたら期限が1年と1ヶ月になってました。 f:id:satococoa:20160124154646p:plain

この手の証明書の生成はポチポチブラウザでやってもいいのですが、最近は fastlane シリーズの pem gem を使っています。 pem と一発打つだけで自動的にキーペア、Certificate Request を作って要求し、生成された証明書をダウンロードして pem ファイルまで作ってくれる便利なコマンドです。出来上がった pem ファイルだけをサーバに上げれば Push 通知が送れます。(ちなみに development 環境の証明書を作りたい場合は pem --development と打つ)

あとは PR 出して終わり。 f:id:satococoa:20160124155511p:plain

Nice Cert.