Dockerにホームディレクトリをマウントしちゃおう

.NET Core RC2が、Ubuntu 14.04には対応しているが、Ubuntu 16.04にはまだ対応しておらず、自分のノートPCはもう16.04にあげてしまったため、なんとかDockerの力を借りて動かせないかと試行錯誤したところ、動かすことに成功した。 このノウハウは他にも使えると思いました。

PATHの通ったところに、dotnetというファイル名で以下のファイルをおいた。

#!/bin/bash
docker run -it --rm \
    -u $UID:`id -g` \
    -v $HOME:$HOME \
    -e "HOME=$HOME" \
    --workdir=`pwd` \
    --entrypoint=dotnet \
    microsoft/dotnet:1.0.0-preview1 \
    $*

ポイントは以下の通り。

  • このコンテナの中に動かしたいプログラムが入っている(今回はdotnet
  • docker run -it --rmにより、実行後すぐにコンテナを削除し、コンテナを残さないようにする
  • -u $UID:`id -g`により、コンテナ内でもホストのユーザID、グループIDで実行できる(しないとroot権限になる)
  • -v $HOME:$HOMEにより、コンテナ内にホストのホームディレクトリがそのままマウントされ、使える
  • -e "HOME=$HOME"により、ホームディレクトリを認識させる(コンテナ内でexport HOME=/home/74th/した効果)
  • --workdir=`pwd`により、カレントディレクトリで実行させる。ホームディレクトリをまるごとマウントしているため、そのディレクトリが存在している状態になる。
  • --entrypoint=dotnetにより、コンテナ実行時に動かしたいプログラムを指定する
  • 最後の$*により、このシェルスクリプトの引数をそのままdocker内のコマンドに渡す

これにより、.NET Coreのプロジェクトを以下のようにビルド、実行できる。

$ dotnet restore
$ dotnet build

前にも同じことをしていたが、以下の問題があった。

  • dockerコンテナ内はroot権限で実行されるため、docker内で作成したファイルなどの権限がrootになってしまう
  • ホームディレクトリ上の設定ファイルを参照するプログラム(dotnetでは$HOME/.nuget/を使う)では、そのユーザのホームディレクトリがないため、うまく動かない

こうやって小さく使っても、やっぱりdockerは便利っすね!

ChromebookC720を購入して、Linuxをインストール

f:id:j74th:20160529211634j:plain

Chromebook上でLinuxが動くと知り、Chromebook C720を購入した。 今の自分のMacBookProからは半分の重さの1.2kgになり、気軽に持ち運べるPCになった。 C720はSSDが交換できるため、128GBSSDに交換し、Galiumosをインストールした。

acer C720はヤフオクで落札したが、これが入手できない場合、acer CB3-131をamazon.comにて購入する予定だった。日本に発送しても2万ちょいで手に入る。

www.amazon.com

ChromebookはARMではなくIntelのCPUならばどれでもLinuxがインストールできるようである。そういえば、ChromebookAndroidアプリが動くと発表があったが、きっとARMでしか使い物にならないだろう。

Galiumosのインストール

chrxという簡単にLinuxをインストールできるツールがあるので、これを利用する。

GitHub - reynhout/chrx: Chromebook Unix

Linuxをインストールするまでにやった手順は以下の通り。というか、chrxに書いてあるとおり。

  • ChromeWebStoreからChromebook Recovery Utilityをインストール。SDカードにリカバリディスクを作成する。作成後、SDカードは抜いておく。

chrome.google.com

  • ESC+F3+Powerで起動する。OSが見つからないよと出るが、Ctrl-Dを押す。するとOS VerificationをOFFにするリカバリが始まる。この時にSDカードが必要かも。
  • 次に起動した時、起動前画面にて危ないモードだよとでるが、Ctrl-Dを押す。これでDeveloperModeになる。
  • Ctrl+左上の「→」キーを押すと、コンソールが開く。ユーザ名:chronos でログインできる。
  • chrxに記載のあるとおり、以下のコマンドでインストールする。1回目はインストールの準備のみで、再起動後2回目に同じコマンドを入れるとインストールできる。なお、sudoは不要だった。
curl -Os https://chrx.org/go && sh go -z Asia/Tokyo

これでしばらくすると、再起動して、起動前画面にてCtrl+Lをタイプすると、Galliumosが立ち上がる。他にもLubuntuなども選択できるが、GalliumosはChromebook用に作られたUbuntuベースのディストロで、タッチパッドをいい感じにしてくれるツールやChromebook用のKeymapなどが自動でインストールされて快適さが違うので、Galliumosを使うようにしている。ただしUbuntu15.04ベース。

(2016/06/04追記) 2.0betaは16.04ベースで、sh go -r nightlyとするとインストールできる。特に不具合はないのでこちらを使っている。

Galiumosの設定でやったことを記載する。

日本語IMEをインストールする

Synaptic Package Manager->ibus-mozcをインストール

Language Support->Install/RemoveLanguage->Japaneseを選択

Language Support->Keyboard Input Method System->Ibusを選択

Keyboard Input Methods->Input Methodタブ->Japanese-MozcをAdd

キーボードのキーをF1-F10として動作させる

Galiumosデフォルトでは、それぞれ音量キーや液晶の明るさなど目的通りのキーになる。しかし、F1-F10キーとして使いたいので、設定を変える。

Keyboard->Layoutタブ->Use system defaultsにチェック

検索ボタンをCtrlとして使う

Galiumosでは検索ボタンはmetaキー(Winキー)として動作する。これを、xmodmapで左下のCtrlキーと入れ替えを行う。

~/.xmodmapに以下を記載する(C720の場合)。あと、このファイルには実行権限をつけておく必要がある。

remove mod4 = Super_L
remove control = Control_L
keycode 133 = Control_L
keycode 37 = Super_L
add control = Control_L
add mod4 = Super_L

参考:

bearmini.hatenablog.com

さらに右AltでIMEのオンオフを切り替える

僕は最近英語キーボードを使っていて、IMEのオンオフを右Altで行うようにしている。Macの場合は、Karabinarを使う。Windowsの場合は、ChangeKeyを使って右AltにF13キーを割り当て、IMEのオンオフをF13キーで行えるように設定することで実現している。

Linuxの場合は、~/.xmodmapを書き換えて、右AltをF13キーとして認識させる。

keycode 108 = F13

さらに、MozcのPreferenceのKeymapのcustomizeにて、以下の設定を追加。

Mode Key Command
DirectInput F13 Activate IME
Precomposition F13 Deactivate IME

終わりに

Linuxノートを使っていると、MacがなくてもLinuxがあれば結構平気なことに気づく。

Google Cloud Storage で静的ウェブサイトを公開する

Google Cloud Storage でウェブサイトを公開してみました。最終的には、以下を実現しました。

  • 独自ドメインにて、Google Cloud Storageにアップロードしたファイルを閲覧できるようにする
  • 最初は、Mac上のリソースをrsyncにてアップロードする
  • Debian上のJenkinsにて、リソースを自動アップロードできるようにする。この時Jenkinsには、Google Cloud Storageにアップロードする権限だけを付与するようにする。

Amazon S3よりもGoogle Cloud Storageの方が2割程度安くなります。

  • Google Cloud Storage : $0.026 /GB/month
  • Amazon S3 東京リージョン : $0.0330 /GB/month

公式ドキュメントは以下になります。

Hosting a Static Website - Cloud Storage — Google Cloud Platform

1. プロジェクトを作る

Google Cloud Platform では、このプラットフォーム全体で、Projectという単位でリソースを区切る必要があります。以下のリンクからぷとジェクトを作成します。

プロジェクト

2. 独自ドメインGoogleに認証させる

独自ドメインを利用できるようにするには、ウェブマスターセントラルにて所有していることを認証させる必要があります。

ウェブマスター セントラル

ドメインは、mydomain.comで取得し、サブドメインwww.mydomain.comを利用する場合であっても、domain.comで登録します。

お名前.comの場合は、確認方法で「GMO.jp」を選択すれば、ログイン画面が現れて認証できるようですが、うまく行きませんでした。私は表示されたTXTレコードを登録する方法で確認を実施しました。

3. バケットを公開するホスト名で作成し、公開の設定を追加する

以下のページから、作成したプロジェクトを選択し、バケットを作成します。この時バケットの名前は、公開するサブドメイン www.mydomain.com に設定します。

ストレージ ブラウザ - personal-storage

上記の画面から、作成したバケットに対して、右端のオプションボタンから「オブジェクトの規定の設定」を表示し、以下の設定を追加します。

  • エンティティ:ユーザ
  • 名前:allUsers
  • アクセス権:読み取り

この設定は、アップロードをする前に必要があります。

5. gcloudを使ってアップロードする

Macの場合は、homebrewを使って簡単にインストールできます。インストール後、初期設定を行ってgcloudコマンドが使えるようにします。表示されるままに記載のURLにアクセスし、キーを入力します。

brew install gcloud
gcloud init

アップロードするには、gcloudのrsyncを使います。

gsutil -m rsync -d -r <アップロードディレク取取り> gs://<バケット名>

この時点で、以下のURLにアクセスすると、確認できるようになります。

https://storage.googleapis.com/<バケット名>/

6. ドメインGoogle Cloud Platformを指すようにする

ドメインを取得したレジストラにて、DNSレコードを以下のようにします。

  • ホスト名: <公開ホスト名>
  • TYPE: CNAME
  • VALUE: c.storage.googleapis.com

これで、目的のドメインにて、静的ウェブサイトを公開できました。

7. Debian/UbuntuのJenkinsにて、自動アップロードを出来るようにする

自分はDebianサーバにてJenkinsを立てており、Gitリポジトリをポーリングさせ、Jenkinsから自動でGoogle Cloud Storageにアップロードされるようにします。

まず、Jenkins用のサービスアカウントを作成します。

権限

サービスアカウント名に「Jenkins」などと入れると、自動的サービスアカウントIDが作成されます。「新しい秘密鍵の提供」を選び、キーのタイプを「JSON」とすると、秘密鍵が書かれたJSONファイルがダウンロードできます。

サービスアカウントIDをコピーしておきます。

バケットの一覧の画面から、目的のバケットの「バケットの権限の編集」を選び、以下のように先ほど作ったサービスアカウントに編集権限をもたせます。

ストレージ ブラウザ

  • エンティティ: ユーザ
  • 名前: サービスアカウントID
  • アクセス権: 書き込み

Debian/Ubuntuに、Google Cloud SDKをインストールします。Debian/Ubuntuの場合には、リポジトリを追加すると、apt-getでインストールできます。無理してCentOSなどを使わずに、Debianを使いましょう。

Quickstart for Debian and Ubuntu - Cloud SDK — Google Cloud Platform

このJSONファイルをJenkinsサーバに移動し、Jenkinsにしかアクセス出来ないところへ配置します。そして、JenkinsユーザにてこのJSONキーの有効化をします。

sudo su jenkins
gcloud auth activate-service-account --key-file <鍵のjsonファイル>

これで、Jenkinsからもgsutil rsyncが使えるようになります。

困った点

  • AWS S3と異なり、https://storage.googleapis.com/<バケット名>/とプラットフォームの方でドメインを割り振ってくれないため、サイトによってはCNAMEを設定するまでサイトをきちんと確認できない。
  • 「オブジェクトの規定の設定」はアップロード時に付く権限らしく、アップロード後に設定しても、公開設定されない。なので、アップロード前に権限設定をする必要がある。
  • まだ東京リージョンがないので、ちょっと遅いかもしれない。

最後に

一時、github.ioでサイトを公開していましたが、なんとなくオープンソースでもないのに無料のサービスに間借りするなんてという気分になり、Google Cloud StorageのWebサイトへ移行しました。