NAKKA-Kの技術ブログ

技術に関する知見や考え方などを投稿します。

電動昇降デスクでスタンディング環境とシッティング環境を両立させる健康のための夢の作業環境を作った話

最近引越しをする機会があったので、そのついでに健康に配慮した作業環境を作りました。 これからの時期引っ越す人も多いと思うので、この機会に少しでも健康に配慮した作業環境を作ってみてはいかがでしょうか?

f:id:NAKKA-K:20200221014731j:plain

基本的には以下の記事を参考にしましたが、DIYではなく全て既製品で済ませたかったのと健康に配慮した+αが欲しかったので少しカスタマイズしました。 izm-11.hatenablog.com

作業環境の概要

電動昇降デスク

まず、座りっぱなし、立ちっぱなしの両極端ではなく、数時間ごとで交互に簡単に切り替えられる環境を作りたかったので電動昇降デスクを選びました。

その中でもボタン一つで環境を切り替えられ3箇所の位置を記憶してくれる機能がついているものです。 特に天板は20kgほどの重量だったりするため、手動で昇降させるタイプのものはキツイですし、頻繁に環境を切り替えるのは難しいです。 位置記憶機能で一番気をつける必要があるのは、ものによってボタンを押し続けないと記憶した位置で止まってくれる簡略タイプの物があることです。

昇降音に関しては深夜でもあまり気にならない程度なので心配はありません。

個人的に使う時の高さなどを書いておきますので、参考になればと思います。 私の身長が175cmで、机の高さ65cmでPC作業、75cmで書き作業、110cmでスタンディング作業という形にしています。 机の高さは最大128cmなのでもっと身長が高い人でも問題ないと思います。

天板

天板は既製品の中でそれなりに大きいもの、そして何よりウォールナット材の物が欲しかったので140*70cmのウォールナット天板を選びました。 140cmだと24インチモニターをまっすぐ配置すると2.5枚分入るくらいの大きさです。

厚さは2.5cm、材質はウォールナット、表面にメラミン樹脂が見た目を損ねない程度に薄く塗られています。 後から穴を開けたりもできますし、材質が材質だけに耐久性も期待できます。

デスクトップPCホルダー

デスクの昇降に合わせてPCを追従させるためにデスクの下につるす用のホルダーも購入しました。

実はこれだけ注意が必要で、上に書いた天板に設置する場合は穴あけが必要になります。 私は友人にインパクトドライバーを借りて穴を開けましたが、割と簡単に開けられるのでキリとかでも大丈夫だと思います。

椅子

どうしても腰を痛めたくなかったので、先行投資として高めのオフィスチェアを買いました。 今回選んだのはオカムラのBaronチェアですが、以前使っていた2万円程度の椅子とは腰の楽さが全く違います。

椅子を選ぶときは絶対実際に座って確かめた方がいいので、近くの家具屋さんなどに行って見るのがいいと思います。 私の場合はオフィスチェア専門店に行ってコンシェルジュの方にアドバイスをもらいながら、一番自分に合った椅子を選びました。

私が買ったのは以下のオプションですが、人によって合う合わないが180度変わるので試してから買うのをお勧めします。

Baron グラデーションメッシュ / エクストラハイバック / 可動ヘッドレスト / ボディカラー:ホワイト / アジャストアーム / シルバーフレーム / 座面:メッシュ

  • Baronは比較的座面が固めでメッシュの方が少し柔らかい印象です。ですが体重が軽い女性などにはクッションタイプの方がお勧めだったりするそうです。
  • 腰のサポートがもっと強い方がいい場合はサポートがオプションでつけられます。
  • ヘッドレストは幅が広いメッシュのため、柔軟性がありつつも受け止めてくれる感の強いものになっています。
  • 椅子の後傾具合は自由に調整でき、カッチリ位置を止めるモードと後ろまで緩やかにリクライニングするモードを切り替えられます。

その他健康器具

家で簡単にでき、場所をあまり取らないおすすめの物を紹介します。

  • 肩や足腰の健康、普段の荷物持ちに役立つトレーニングができる可変式ダンベ
  • 弛んだ二の腕やお腹をシェイプアップさせるトレーニングができるアブローラー
  • スタンディング環境で歩きながら作業することで脳の働きを活性化させることができるステッパー

可変ダンベ

ダンベルはかなり万能なトレーニング器具で肩、足腰、腕、様々なトレーニングができます。 肩を鍛えれば肩こりが解消しますし、足腰を鍛えればむくみや将来立てなくなると言った危機を回避できますし、腕を鍛えればMacBookPro16インチを持ち歩いても全く重くならないんです。

可変じゃないダンベルを買うと死ぬほど面倒くさいので、可変ダンベルを買うか、さもなくば家にあるペットボトルで妥協してください。 物足りなくなったら可変ダンベルを買いましょう。

よく重量を変える人は少し高いですが、ワンアクションで重量を変えられるタイプのものがおすすめです。

たまにしか変えないなら少々手間ですが安いので、私が使っているものを貼っておきます。

アブローラー

アブローラーでは主にお腹、そして腕の後ろ側、場合によっては足や背中も鍛えられたりします。 普段座っていることが多いためお腹が出たり、二の腕がたゆんたゆんになったりしている人が多いですよね。 この器具だと負荷を変えやすいので長期間使っていくことが可能ですし、他の器具より安いので手が出しやすいです。

ステッパー

海外ではスタンディングかつステッパーや回し車で歩きながら作業をする会社が増えているそうです。 やはり立ちながら、そして歩きながらの方が頭の働きが格段に良いので自ずとそうなるのでしょう。

ステッパーに関してはまだ購入していないのでAmazonランキングが高い物を貼っておきます。

まとめ

  • 6万くらいで電動昇降デスクは揃う
  • 身体には気をつけよう
  • 筋トレは良いぞ!

1~2時間おきに立てったり、座ったりと体勢を変えながら作業をし、そして休憩がてら筋トレを挟むことによって普段の健康にも気を使うことができますしリフレッシュもできます。 筋トレによる健康化や脳の働き向上、精神の安定など様々な効果が確認されているので、作業環境を整えるのと同時に初めてみてはいかがでしょうか?

途中から筋トレの啓蒙活動になっていた気もしますが、結局作業や健康に繋がる部分なので紹介させていただきました。

Elastic BeanstalkのMultiContainer環境にRails+Nuxtをデプロイする

Elastic BeanstalkでMultiContainer環境を構築し、RailsとNuxt.jsをデプロイします。

今回の環境

  • ElasticBeanstalk(Multi-container Docker)
  • Rails 5.2 (ruby:2.6)
  • Nuxt.js 2.11 (node:12-alpine)
  • PostgreSQL (RDS)

目次

初期設定

AWSのアカウント登録

アカウント登録については以下の記事を参考にしてください。

www.wakuwakubank.com

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/iam-servicerole.html

ElasticBeanstalkの環境を作成する

AWSマネジメントコンソールからElasticBeanstalkを検索し開く。

最初に新しいアプリケーションを作成する必要があります。 「アプリケーション名」はそれぞれのElasticBeanstalk環境をグルーピングするためのグループです。 特にこだわりがないならアプリケーション名だけ適当に入力して「作成」します。 f:id:NAKKA-K:20200131140720p:plain

次に右上のアクションから「環境の作成」をクリックする。 f:id:NAKKA-K:20200131130611p:plain

ウェブサーバー環境を選択したまま「選択」をクリック。 f:id:NAKKA-K:20200131130632p:plain

アプリケーションの情報を決めて設定していきます。 プラットフォームをMulti-container Dockerに設定します。 f:id:NAKKA-K:20200131135548p:plain f:id:NAKKA-K:20200131141826p:plain

DBやインスタンスなど、追加の設定をしたい場合「より多くのオプションの設定」をクリックします。 この中で重要な点をいくつか紹介します。

  • ソフトウェアでは環境変数を設定できます。
  • 容量ではEC2のインスタンスタイプを変更できます。
  • データベースではその名の通りどのDBを使用するか設定できます。
  • 設定のプリセットをカスタムにするとロードバランサーを設定できます。HTTPSの設定やポートの設定もこちらです。(環境作成時に設定しないとその後、EBから設定できないので気をつけましょう) f:id:NAKKA-K:20200131143144p:plain f:id:NAKKA-K:20200131143155p:plain

環境変数系の用意

ソフトウェアをクリックして環境変数を設定しましょう。 デプロイ環境では以下の環境変数を個別に指定する必要があります。

  • NODE_ENV = production
  • RAILS_ENV = production
  • RAILS_MASTER_KEY = (これはbackend/config/master.keyの値)

f:id:NAKKA-K:20200203102252p:plain

データベースを設定する

今回のプロジェクトではデータベースをPostgreSQLに設定します。 データーベースの項目をクリックして、データベースの変更とユーザー名・パスワードの設定をしましょう。

f:id:NAKKA-K:20200203102620p:plain

ロードバランサー の設定

まずApplication Load Balancerに必要なポートを列挙します。 それぞれにHTTP、HTTPSのどちらにするのか設定し、HTTPSにする場合はACM(AWS Certificate Manager)で発行した証明書を設定する必要があります。(既存の証明書をインポートすることもできます)

以下の写真では全てHTTPになっていますが、私の環境の場合80番以外HTTPSに設定します。

f:id:NAKKA-K:20200207143033p:plain

f:id:NAKKA-K:20200207143753p:plain

環境を作成する

設定が終わったら「環境の作成」ボタンをクリックして確定しましょう。

すると環境の作成を始め、初期設定のままならサンプルアプリケーションがデプロイされることになります。 環境の作成には5分~10分くらいかかるので気長に待ちましょう。

アプリケーションを確認する

構築が完了するとアプリケーションを管理する画面に遷移します。 画面上部にあるURLを開くとサンプルアプリケーションに接続できます。

f:id:NAKKA-K:20200203124842p:plain

このような画面が見えるかと思います。

f:id:NAKKA-K:20200203124908p:plain

本番アプリケーションをデプロイする

ここからはサンプルアプリケーションではなく実際のアプリケーションをデプロイしていきます。 私がデプロイ時に困ったことや気をつけた方がいいなと思った細かい事象はこの章の最後に一覧化しておきますので参考にしてください。

まず今回ElasticBeanstalkの設定をするに当たって必要なファイルは以下の通りです。 順番に設定していきましょう。

  • Dockerrun.aws,json
  • .ebextentions/
    • elb-listener.config
    • elb-secure.config
  • .elasticbeanstalk/
    • config.yml

Dockerrun.aws.json

全体の説明は複数コンテナの Docker 設定を参照してください。

docker-compose.ymlとDockerrun.aws.jsonはある程度互換性があります。

docker-compose.yml Dockerrun.aws.json
services以下のサービス名 name
image image
hostname hostname
該当なし memory
ports portMappings
volumes volumes+mountPoints
depends_on links
environment environment
command command

まず3行目のvolumesでホスト側のどのソースをマウントしたいのか設定します。 nameは任意の識別子なので自分でわかるものを指定してください。 hostにはどのパスをマウントするのか設定します。

そしてここで設定したnamecontainerDefinitionsにあるmountPointsで使用します。sourceVolumeに対して先ほど設定した任意の識別子を記述し、containerPathにマウント先のコンテナ内のパスを設定します。

次にenvironmentについてです。 containerDefinitions配列内のオブジェクトがそれぞれ1つのコンテナになっています。あるコンテナに書いたenvironmentはそのコンテナ内でしか展開されないようになっていますので気をつけてください。 そしてこのDockerrun.aws.jsonは基本的にGit管理下に含めるため、重要なキーなどを絶対に含めないように気をつけてください。秘密にしなければいけない環境変数AWSコンソールから環境プロパティに設定しましょう。

最後にmemoryに関してです。 これに関しては具体的にどうと言えるわけではありませんが、t2.microのメモリ1GiBを超えないように気を付けることだけは徹底しましょう。 合計で1GiBよりも小さく設定している理由としては、限界まで設定すると逆にパフォーマンスが悪くなる可能性、そしてインスタンスsshをした時にコマンドを走らせる猶予を考慮してのことです。 感覚的な話ですがmemoryを256に設定した時はメモリが足りずに動かなくなってしまっていた状況が見られたので低すぎるのは厳禁です。

.ebextentions/elb-listener.configと.ebextentions/elb-secure.config

APIコンテナに接続するために8080番の設定を別途します。 他には基本HTTPS通信にする予定なので443ポートの設定も書いておきましょう。

SSLCertificateArnsACMで取得した証明書のIDに書き換えておきましょう。 重要な値なので.ebextentions/elb-secure.configは.gitignoreでGit管理下から外しておきましょう。

.elasticbeanstalk/config.yml

このファイルはコマンドを使用して生成します。 以下の記事を見ながらawsebcliをインストールしてください。

qiita.com

インストール後、デプロイしたいプロジェクトのルートディレクトリでeb initを実行して対話的に設定してください。 コマンドの実行が完了するとファイルが生成されていますので完了です。

デプロイする

Dockerrun.aws.jsonのあるプロジェクトルートからeb deployコマンドを実行しましょう。 git archiveコマンドが実行されZIP化されたソースコードがS3にアップロードされます。その後S3からECSを通してDockerコンテナの立ち上げなどが行われます。 Dockerコンテナの起動にはDockerrun.aws.jsonが参照されて、設定通りに起動されます。

このコマンドには1分程度かかり、その後反映まで少し時間がかかります。 デプロイが完了したら、AWSコンソールでヘルスチェックがグリーンになっていることも確認できます。

(補足)デプロイ時に気を付けること一覧

順不同なのでざっと見て必要なところだけ確認してください。

私も詰まった部分が多すぎて全てを詳細に書ききれません。 内容についてコメントで聞いていただければ、答えられる部分に関しては答えたいと思っています。

EC2やDocker

Nuxt

HTTPS

Rails

まとめ

今回のデプロイでは全ての工程が長く、かつその他の問題も複雑に絡んできたせいで多くの障害がありました。 その苦難を少しでも解決するためにこの記事を書きました。

このデプロイで得た教訓としては、結局地道に見当・検証することが重要でした。 そして実際の細かな動きをトレースして全体の構成を想像すれば大体解決しました。

既に記憶から薄れ始めている部分もあるので、聞かれないと思い出さない箇所もあって全てを詳細に書ききれていません。 そのため追加で詳しく聞きたい箇所などあればコメントください。 少しでも解決の一助になればと思います。

引用

vuex-persistedstateを使っていると、ストアを変更しても前のデータがlocalStorageに残って困る

VueやNuxtのプロジェクトでよく使われるvuex-persistedstateというストア永続化プラグインがあります。 このプラグインはストアの内容をlocalStorageに永続化してくれるものです。

問題

ストアの内容を永続化し、ページを開いた時ストアに再展開してくれるのですが、開発中ストアの構造を変更した時などに問題が発生します。

例えばストアにAというデータを保存しているとします。 開発の都合でAというデータを消したとします。 しかしlocalStorage上にはvuex-persistedstateがストアの内容を保存している為、ページをロードした時点でAというデータをストアに格納してしまします。 しかもlocalStorageに保存している為、リロードやキャッシュクリア、ブラウザの再起動では消えません。

これに気づかず変更が読み込まれていないのかと戸惑いました。

解決策

今のところ解決策は2つです。

  1. ブラウザからlocalStorageを初期化する
  2. コード上でlocalStorage.clear()をする

1. ブラウザからlocalStorageを初期化する

ブラウザごとに方法が違うのでこちらの外部サイトをご覧ください。

doc.arcgis.com

2. コード上でlocalStorage.clear()をする

このコードはアプリケーション上で実行してもいいですし、開発者ターミナルから実行することもできます。

以下の1行でサイトのlocalStorageを全て初期化することができます。

window.localStorage.clear();

localStorageにはストアの内容以外にも保存されている場合があります。 それらは消さずにストアの内容だけを消したい場合は以下のようにすると良いです。

window.localStorage.removeItem('vuex');

別の方法

localStorageに保存されるのが面倒な場合は保存先を変更することもできます。 sessionStorageやcookieに設定することもできる為、開発中だけそちらにするといった方法もあるかもしれませんね。

DockerとNuxtのSSRでConnectionRefusedが発生する問題の原因を解説する

Docker上でAPIサーバーとNuxt(SSR)を動かす環境で、connection refusedが発生したりしなかったりする問題に遭遇しました。 今回はその問題の発生原因について書いていきます。

一言で

今回の問題は直アクセス時nuxt-linkなどでのclientだけで完結する遷移時でasyncDataメソッドの実行場所が違うためです。

どういうこと?

前者のパターン

まずURLをアドレスバーに直打ちしてアクセスします。 この場合、クライアントでは表示すべきHTMLファイルやjsファイルが存在しない状態から処理が始まり、NuxtサーバーではSSRとしてasyncDataメソッドが実行されます。 そのためasyncDataメソッドにAPIアクセス処理があった場合、Dockerとして動くNuxtサーバー上から行われるためコンテナ~コンテナ間通信になります。

後者のパターン

このパターンでは既にクライアントに表示すべきHTMLファイルやjsファイルが存在していてページが表示されている状態とします。 ページが表示された状態からnuxt-link$router.pushを使って画面遷移をした場合、NuxtサーバーではなくクライアントでasyncDataメソッドが実行されます。 そのためasyncDataメソッドにAPIアクセス処理があった場合、クライアントからDockerコンテナに対してアクセスされるのでホスト~コンテナ間通信になります。

何が問題?

ホストからDockerコンテナへアクセスする場合localhost:8080のような形でアクセスできます。

f:id:NAKKA-K:20191010123923p:plain
クライアントからDockerコンテナへアクセス

しかしDockerコンテナ間のアクセスではコンテナの名前を元にドメインを解釈するため、api:8080のようなアドレスが必要になります。

f:id:NAKKA-K:20191010123951p:plain
Dockerコンテナん間のアクセス

そのためasyncDataメソッドでAPIアクセス処理を書いていると、Nuxtサーバー内で実行される時とクライアントで実行される時の2パターンでは実行結果が変わってしまうといった問題が発生してしまいます。

解決策

サーバー上での実行時と、クライアント上での実行時でURLを変えると解決します! サーバー上ではDockerコンテナ間の通信をする為、コンテナ名依存でURLを設定します。 クライアント上ではDockerコンテナの外からアクセスする為、解釈された後のURLを設定します。

nuxt.config.js

  axios: {
    baseURL: process.env.API_URL,
    browserBaseURL: process.env.API_URL_BROWSER
  },

.env

API_URL='http://api:8080/'
API_URL_BROWSER='http://localhost:8080'

まとめ

SSRをする場合は常に「APIアクセスがどこから行われるのか?」、「どういう環境で行われるのか?」、「本当にそのアドレスで正しいのか?」を意識するようにしましょう。 理解できればそんなに難しい話ではないということがわかります。

参考

env設定忘れでDBが動かず、Dockerを初期状態から立ち上げた

Dockerでpostgresを起動。 同じくDockerでRailsを起動しdocker-composeで接続。

ActiveRecord::NoDatabaseError

FATAL: role "myuser" does not exist

docker-compose up -dした時に環境変数をセットするのを忘れていました。 postgresにボリュームを設定していたので、環境変数をセットしていない間違った状態のまま作成されていました。

$ docker-compose down

これではボリュームなどの永続設定のデータは削除されず上手く初期状態から立ち上げることはできません。

完全に再度作成し直す必要がありました。 以下のコマンドで一度全て削除することができます。

$ docker-compose down -v --rmi all

これで永続化されたボリュームもう一度初期から立ち上げることができます。

$ docker-compose up -d
$ docker-compose run server rake db:create

これで解決しました。

独立したGitリポジトリのマージをすると発生するfatal: refusing to merge unrelated historiesの解決

  1. GitHubリポジトリを作る。
  2. ローカルでリポジトリを作る。

その後、マージしないとと思い立ちgit pull origin masterをすると、fatal: refusing to merge unrelated historiesが表示されてしまいました。

そんな時はということで、git merge --allow-unrelated-histories origin/masterを走らせると見事にマージしてくれました。

完全に独立した2つのブランチがマージされている様子が見られるGitログ
完全に独立した2つのブランチがマージされている様子が見られるGitログ

参考

GoModuleを使ったgo getができない問題を解決する

$GOPATH以下ではデフォルトでGO111MODULE=ofになるため依存パッケージがインストールされておらず、明示的にGO111MODULE=on go get -uをする必要があった。

参考