Railsのcookies serializerの設定変更時には heroku の preboot の設定を確認しておくこと

1
Rails.application.config.action_dispatch.cookies_serializer = :marshal

から

1
Rails.application.config.action_dispatch.cookies_serializer = :hybrid

にして、移行は完璧!と思っていても

https://devcenter.heroku.com/articles/preboot

enabledのままだと、大変なことになるから気をつけろ!

基本的に新旧バージョンのサーバインスタンスが共存し得る場合に困るような更新がある場合はdisabledにしておかないとrollbackしてもdeployしなおしても、状況がつかめず悪化するだけになるので気をつけねばならない。

今までのリモートワークで起きた問題を整理してみる

とある会社でリモートワーク導入前にポエんだ記事をシェア。

ポエム/今までのリモートワークで起きた問題を整理してみる - esa-pages.ioをそのまま雑アウトプットへ持ってきた。

経歴

惚れさせ355 「飽き」 マジ飽きたわー ほんと飽きた あれまだやってる奴いるの? ほんと飽きたわー! 俺が一番先に飽きたわー

  • 2009.09-2011.06
    • 2009年にフリーランスになってから手伝っていた会社(その後その会社へJOIN)でリモートワークを1年半ほど。
    • 3.11はたまたまMTGがあって出社日だったけども、出勤しようとしたタイミングで担当のサービスのサーバーが言うこと聞いてくれなくてヨシヨシしてたらアノ地震がやってきた。
  • 2012.07-2014.09
    • その会社を辞めた後にその会社の同僚と一緒に契約社員でとある会社に1年限定JOINした後、自分だけその会社にフリーランスで残った。その後起業した。どちらもリモートワークが主でMTGのあるときだけカフェで関係者と会ったり間借りしてたオフィスへ行ったり。

環境

2009-の方は、自分たちでとにかくイロイロ環境を作ってたので、HPの格安サーバーにVMware ESXiを突っ込んで、OpenVPN張って、IRCやgitやdeploy環境、本番への踏み台サーバへアクセスという感じだった。

2012-以降は、割りとSaSSが便利になってきており、skypeとgithubとherokuがあればokという環境。

仕事しない問題

リモートワーク初期に起こりうる仕事しない問題。会社側の懸念の上位にありそう。リモートワーク初心者、特にフリーランス初心者の場合は更に特にある問題で、特定の期日までに成果を上げればいいので土壇場まで仕事しなくなるという問題があった。コレは、フリーランスの場合やらなきゃ食べていけないっので割と直ぐ仕事しだす。会社勤めだと厄介。どうしてもやる気が出なければ、まずは好きなだけ寝てみたり漫画でも読めばいいんだけど、そんなことに時間使いたかったのか?とう自問自答が割と早くやって来るので安心していい。完全に自由な状況になると人はむしろ今一番時間を使うべき問題に時間を使いはじめるようになるので、放っておけば勝手に仕事はし始める。効率的に仕事をしようという気になるだろう。どうしても、しない場合はもう辞めればいい。仕事がそもそも向いてないかも知れない。もしくはもはや出社すればいいかもしれない。

目的をしっかりと持って、取り組むことで、ちゃんと成果を出せるようにすべき。何故リモートワークをするんだっけ?という出発点が大事。

仕事し過ぎ問題

逆に仕事し過ぎることも問題である。なんせ、起きた瞬間から寝る瞬間までいくらでも仕事が出来る環境となるので、今日はここまでやるぞという気持ちが大事。よく考えるとそれは出社しても同じだった。

個人的には集中しまくっているときは寝ずに朝まで走りきって次のはセーブみたいなのが一番効率が良かった。

週1リモートワークの場合は、始業時間を早めるのと同時に終業時間もメリハリをもって設定すべきかと思う。いつもの働き方にプラスαぐらいの変化がちょうどよいだろう。

コミュニケーション問題

口頭でのコミュニケーションが減ることによってむしろ会話がアーカイブされて良い。普段からのコミュニケーションもなるべくアーカイブ性が高まる方向性を意識するようになる。

むしろ普段から口頭だけでコミュニケーションを終わらせちゃダメ。ちゃんと記録に残す

どうしても必要なMTGも事前のアジェンダ準備をキチンとして口頭で話すべき内容だけをMTGで話せばそれが対面だろうがリモートだろうが変わらないけども唯一補完出来ないのがアイコンタクト。相手の表情などが汲み取れない。なのでそこだけは必要以上に補足することが必要となる。もしくはそのためだけに会えばいい。後はナンカ絵文字とかで感情を伝えればいいんじゃない?(要出典)

また積極的なチャットやgithub上でのコミュニケーションが必要となるので、コミュニケーションを不要なコストと考えているとリモートワークは難しい。そもそもチームにおいてコミュニケーションは必要コストであるという感覚が必要。1人で仕事するとそのコストが全くなくなるので体感するといいかも知れない。

話しかけられない問題

気を使わずメンションすればいい。

気分転換に近所を歩くと仕事してないのかなって思われる問題

フルリモートだと、最初の1週間ぐらいソワソワするけど、慣れる。

リモートMTGで部屋のクローゼットが映る問題

みんなそう。扉を閉めるといいかも。

太る問題

ほんとそう。気をつけないといけない。

自宅のほうがマシンが強い

あるある。

Unityで「もぐらたたきゲーム」を作ってみる2

#270: blog/uGUIについて学んだ 結果、2DゲームはuGUIで作った方が楽ぽいので、作り直しはじめた。

学び

わからん

  • Animatiorのtriggerの発動のさせ方
  • 重ならないようにいい感じにprefabを配置する方法
    • そりゃまあ頑張ればできるのは分かる

感想

ほとんど、フォトショさわってた。

uGUIについて学ぶ

2Dゲーム作るのは、uGUIの方が調整しやすいのではないか?と思い、uGUIを勉強してみることにした。

UnityのuGUIで作る2Dゲーム -基本編/CanvasにUIを配置してみよう- - Schoo(スクー)

  • uGUI
    • Unity Graphical User Interface
    • 公式マニュアルにはuGUIという名前は登場しない
    • ユーザーのあいだで呼ばれていた
  • 出来ること
    • UIの配置
    • 2Dゲーム要素の描画
    • 画像などへのポインタイベント処理
  • Canvas
    • ここにuGUIを配置していく
    • ヒエラルキーの上においてあるほど、後ろ

2DのレベルにGameObjectを置いて、MainCameraで描写される範囲を考慮して画面設計するよりも、Canvasの方が柔軟かもなあと思った。

Rect Transformで直感的な配置もしやすそう。

前回作ったものを捨てて、1から作り直してみよう。

Unity初心者で、2Dゲーム作る際には@monry

UnityのuGUIで作る2Dゲーム
個人開発者から大手ゲームメーカーまで幅広い層のデベロッパーが利用しているゲームエンジン「Unity」が提供する2D関連機能のuGUIを用いて2Dゲームを作る方法について学びます。

Unityの使い方は何となく分かってきたけどUIの配置に悩んでいる方、Unity上でGUIの構築を助けてくれる機能「uGUI」のより高度な使い方を学びたい方、Unityを用いてUI配置を行いプログラマーと協働したいUIデザイナーの方向けに、分かりやすくUnityのuGUIを解説していきます。

これみるのマジおすすめ!

Unityで「もぐらたたきゲーム」を作ってみる1

Unityさっぱりわからん。

そもそもわからん

わからないことを、たまたま近くにいたおじさんに質問して見た。(おじさん is @monry

  • オブジェクトを置く、この世界をなんていうんだ
    • monry said: レベルと言う
  • SceneにまたがったGameObjectの配置ってどうやんの
    • ppworks said: Scene切替時でもGameObject等を破棄せずに保持しておく方法 - Qiita」を見つけましたよ。
    • monry said: DontDestroyOnLoadでやるのはありだけど、専用シーンが出来上がって管理しづらい。
    • monry said: うちのプロジェクトではSceneManager.LoadScheneの第二引数でLoadSceneMode.Additiveを渡す作戦を使っている。Sceneが合成されるイメージ。いわゆるモーダル表示みたいなことをしたいときにはこれ!
    • ppworks said: ところで、Sceneごとにカメラが置いてあるけど、合成された時はどうすんの?
  • 2Dで、Spriteのスケール設定は、Spriteの設定にあるPixels Per UnitGameObjectTransformScaleでやるのどっちがいいの?
    • monry said: Scaleは階層構造の配下のGameObjectにも影響するから避けたい。
    • monry said: そもそも、2Dは、GUIで構築しちゃうと言う手も
    • ppworks said: な、なんだってー!!!その発想はなかったでござるよ。にんにん。
  • カメラの画角計算がわからん。カメラに写る範囲にぴったり置きたい。たとえば、最初から置いてあるMain Cameraをz: -10の位置においたとき画面に描写される範囲の計算方法は?
    • ppworks said: Unity - Manual: CameraからリンクされているUnity - Scripting API: Camera.orthographicSizeに書いてあった。Camera's half-size when in orthographic mode.な。
    • ppworks said: orthographicモードにしている際のsizeに縦方向の半分に収めるunit数を入れてやればいい。
    • ppworks said: 例えば、16:9の画面のカメラにピッタリ16unit x 9unitを写したければ、4.5と入力する。
  • Build Setting
    • ppworks said: 追加したsceneしか使えない?
    • monry said: そうそう。プロジェクトに含まれるすべてのものがビルド対象というわけではない。ここで指定したシーンに含まれるものがビルド対象となるので、気をつけて。

ほう。@monry便利。

設計してみる

  • レベル上に登場するGameObject
    • 背景などのハリボテ
      • 各Sceneを通じて、最初に用意したらとっておきたい
    • Prefab
      • もぐら
        • 穴からもぐらが出てくるアニメーションを持つ
        • 3種類ぐらいいる(猫、おじさん、もんりぃ)
  • シーン
    • トップ
      • 処理
        • ワールドの準備
      • UI
        • ゲーム開始ボタン
        • レコード表示ボタン
    • ゲーム
      • 処理
        • ゲーム開始
        • ユーザーの操作イベントを受付開始
        • もぐらをランダムに生成する
        • タイマーのセット
        • スコアの記録
        • 終了イベントを検知して
          • レコードを記録
          • ゲームを終了し結果へ移動
            • UI
        • 残り時間表示
        • スコア表示
    • 結果
      • UI
        • 得点の表示
        • タイトルへ戻るボタン
        • 再度ゲーム開始ボタン
    • レコード
      • 処理
        • 過去のレコードを表示
      • UI
        • レコード表示リスト
        • トップへ戻るボタン

2Dゲームなので、GUIですべて対応できる予感もするけど、今回はあえてハリボテのSpriteを配置して作ってみようかな。

ソース

MainSceneController.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MainSceneController : MonoBehaviour {

void Start () {
Debug.Log ("Hi, I'm MainScene!!!");
}

void Update () {

}
}

TitleSceneController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class TitleSceneController : MonoBehaviour {
// https://qiita.com/momomo/items/f8c16004123f38e86fc0 を参考に変更する!
public Button startButton;
public GameObject background;

void Start () {
Button button = this.startButton.GetComponent<Button>();
button.onClick.AddListener(ClickStartButton);

DontDestroyOnLoad (this.background.transform.gameObject);
}

void Update () {
}

void ClickStartButton() {
Debug.Log("You have clicked the button!");
SceneManager.LoadScene ("scenes/MainScene");
}
}

今回は、Unityの概念の謎を調べたり試行錯誤して、設計をしただけで終わってしまった。

esaのslideをembedする



以下みたいな感じで、マークアップする。

1
2
3
4
<div style="position: relative;width: 100%;border: 1px solid #999; border-radius:7px;overflow:hidden;">
<div style="padding-top: 75%;"></div>
<iframe src="https://esa-pages.io/p/sharing/3/posts/1117/1901213944ee86efdaea-slides.html#/" style="border-style: none;position: absolute;top: 0;left: 0;width: 100%;height: 100%;" scrolling="no" frameborder="no" />
</div>

こんな感じのマークアップを書く。esa側でいい感じにすべきだよなあ、します。

Hexo の archives の表示順序を変える

hexo-generator-indexにはあるorder_byオプションがhexo-generator-archiveには、なかったので足した。

Enable archives to sort by custom order by ppworks · Pull Request #9 · hexojs/hexo-generator-archive

1
2
3
4
5
6
7
   var config = this.config;
var archiveDir = config.archive_dir;
var paginationDir = config.pagination_dir || 'page';
- var allPosts = locals.posts.sort('-date');
+ var allPosts = locals.posts.sort(config.archive_generator.order_by || '-date');
var perPage = config.archive_generator.per_page;
var result = [];

0.1.5以降を使うとorder_byオプションが使えるようになるので、こんな感じで_config.ymlorder_byを追加する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
diff --git a/_config.yml b/_config.yml
index 9c306f1..232f072 100644
--- a/_config.yml
+++ b/_config.yml
@@ -53,6 +53,9 @@ index_generator:
per_page: 10
order_by: -number

+archive_generator:
+ order_by: -number
+
# Category & Tag
default_category: uncategorized
category_map:

このhexoはesaと連携しているので、indexと同じようにnumberの降順にした。

Dockerでrails s

#250: blog/Dockerでrails new 出来たので今回は、rails sしたくていろいろ調べながら、最低限のDockerfiledocker-comose.ymlが出来上がったのでメモ。

Dockerfile-dev

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
FROM ruby:2.4.2-slim
MAINTAINER Naoto Koshikawa <koshikawa@ppworks.jp>

ENV DEBIAN_FRONTEND noninteractive

# set locale and timezone
RUN apt-get update -qq && \
apt-get -y upgrade && \
apt-get -y install locales && \
apt-get clean && \
apt-get autoclean && \
apt-get autoremove && \
echo en_US.UTF-8 UTF-8 > /etc/locale.gen && locale-gen && dpkg-reconfigure locales && \
echo "Asia/Tokyo" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata

ENV TZ Asia/Tokyo

RUN apt-get -y --no-install-recommends install \
build-essential \
libpq-dev \
nodejs \
wget

ENV ENTRYKIT_VERSION 0.4.0
RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
&& tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
&& rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
&& mv entrykit /bin/entrykit \
&& chmod +x /bin/entrykit \
&& entrykit --symlink

RUN mkdir /app
WORKDIR /app

ENTRYPOINT [ \
"prehook", "bundle install -j4 --quiet", "--"]

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: '3'
services:
rails: &app_base
build:
context: .
dockerfile: Dockerfile-dev
environment:
DATABASE_URL: "postgres://postgres:@db:5432/your_app_development"
volumes:
- ".:/app"
ports:
- "3000:3000"
depends_on:
- db
command: ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]
db:
image: "postgres:10.0"
volumes:
- pg-data:/var/lib/postgresql/data
volumes:
pg-data:
driver: local

.dockerignore

1
2
3
4
5
6
7
.git
doc
docker-compose.yml
log
tmp
Dockerfile
Dockerfile-dev

config/database.yml

雑に環境変数DATABASE_URLで繋ぐようにしてみた。

1
2
3
4
5
6
7
8
9
10
11
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
url: <%= ENV['DATABASE_URL'] %>
development:
<<: *default
test:
<<: *default
production:
<<: *default

使い方

Dockerfileを更新した場合は

1
2
docker-compose build
docker image prune # 必要に応じて

普段の開発は

1
docker-compose up -d

migrationなどの実行

1
docker-compose exec rails db:migate

DBに入る

1
docker-compose db psql -u postgres

みたいな感じ。

参考にした

この辺のQiita記事を参考にしつつも、そもそもDockerfileの記述方法もよくわからないし、docker-compose.ymlの記述方法もよくわからなかったので、公式ドキュメントを読みまくった。

buildしまくっていると、imageの差分が出来まくるので、不要なものを消したいと思って色々調べた結果

Dockerの不要なコンテナ・イメージを一括削除する方法

がとても参考になった。

1
docker image prune

をよく使う。

次はいまConoHa VPSで雑に動かしているアプリをDocker化してみようと思う。
本番も、docker-compose使うことになるのかな。だとしたら、今回作った開発用のものはdocker-compose-dev.ymlみたいな感じになるだろうか。試行錯誤してみよ。

Dockerでrails new

Macのローカルでrails newする際に、最初にどこかにrailsが必要なのが嫌で、rails newで出来たディレクトリだけ欲しくて、Dockerfileを書いてみた。

https://github.com/ppworks/docker-rails_new

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
FROM ruby:2.4.2-slim
MAINTAINER Naoto Koshikawa <koshikawa@ppworks.jp>

ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update -qq && \
apt-get -y install build-essential # nio4r

RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
RUN bundle install -j4

Gemfile

1
2
3
ruby '2.4.2'
source 'https://rubygems.org'
gem 'rails', '>= 5.1'

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
version: '3'
services:
rails-new:
build:
context: .
dockerfile: Dockerfile
volumes:
- ".:/app"
tty: true
stdin_open: true

rails new

1
2
3
cd ~/docker
git@github.com:ppworks/docker-rails_new.git dev
cd dev
1
docker-compose run --rm rails-new rails new your-awesome-app --skip-bundle

Dockerよくわかってないので、もっとかっこいい方法があるかもしれない。
次は、Docker上でrails sしてみたいと思う。

追記

2017-11-02 16:12
https://github.com/ppworks/docker-rails_new/pull/1
の内容を反映した。

Heroku SSL EndpointからAutomated Certificate Managementへ移行する

Heroku SSL EndpointからAutomated Certificate Managementへダウンタイムなしで移行したので、その記録。

Heroku SSL化を挟まないと、heroku certs:auto:enableしてからstatus: OKになるまでの間にダウンタイムが発生する。そのあたりの注意点は公式ドキュメントに書いてあった。

https://devcenter.heroku.com/articles/automated-certificate-management#migrating-from-ssl-endpoint
Migrating from the SSL Endpoint addon to Automated Certificate Management requires a DNS change. However, you can use Heroku SSL (SNI) as an intermediate step to avoid downtime for your custom domain. Start by following these instructions to migrate from SSL Endpoint to Heroku SSL (SNI). Once that process is complete, you can enable ACM with no downtime as described above.

いちど、Heroku SSLへ移行してから、ACM(Automated Certificate Management)へ移行すればいい。

Heroku SSLを使うには、heroku certs:addコマンドに--type sniオプションを付けて証明書を追加する。

このとき、既存の証明書と同じものをアップロードしてオッケー。

1
heroku certs:add example.com.crt example.com.key --type sni

すると、こんな感じで2つの証明書が表示される。

1
2
3
4
5
heroku certs -a pplog
Name Endpoint Common Name(s) Expires Trusted Type
────────────────── ──────────────────────── ──────────────────────── ──────────
gifu-1545 gifu-1545.herokussl.com www.pplog.net, pplog.net 2018-01-30 03:10 UTC True Endpoint
camarasaurus-91097 (Not applicable for SNI) www.pplog.net, pplog.net 2018-01-30 03:10 UTC True SNI

ドメインを確認すると

1
2
3
4
5
6
7
8
9
heroku domains -a pplog
=== pplog Heroku Domain
pplog.herokuapp.com

=== pplog Custom Domains
Domain Name DNS Record Type DNS Target
───────────── ─────────────── ───────────────────────────
www.pplog.net CNAME www.pplog.net.herokudns.com
pplog.net ALIAS or ANAME pplog.net.herokudns.com

CNAMEALIASに設定すべき項目が表示されるので、これらをDNSの設定に反映する。

1
dig CNAME www.pplog.net

TTLの設定に寄るけども、DNS反映されたら、Heroku SSL Endpointのアドオンを削除する。(焦らなくてもいいので次の日にでも)

1
heroku addons:destroy ssl -a pplog

Automated Certificate Managementを有効にする。

1
2
heroku certs:auto:enable -a pplog
Enabling Automatic Certificate Management... done

すぐに確認すると、In Progressになっている。

1
2
3
4
5
6
7
heroku certs:auto -a pplog
=== Automatic Certificate Management is enabled on pplog

Domain Status
───────────── ───────────
www.pplog.net In Progress
pplog.net In Progress

しばらくすると、OKになる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
heroku certs:auto -a pplog
=== Automatic Certificate Management is enabled on pplog

Certificate details:
Common Name(s): pplog.net
www.pplog.net
Expires At: 2018-01-30 04:51 UTC
Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Starts At: 2017-11-01 04:51 UTC
Subject: /CN=pplog.net
SSL certificate is verified by a root authority.

Domain Status
───────────── ──────
www.pplog.net OK
pplog.net OK

証明書のTypeACMになっていれば完了。

1
2
3
4
heroku certs -a pplog
Name Common Name(s) Expires Trusted Type
────────────────── ──────────────────────── ──────────────────── ─────── ────
camarasaurus-91097 pplog.net, www.pplog.net 2018-01-30 04:51 UTC True ACM