Raspbian Jessie Lite で Docker する - インストール編

Raspberry の ベース環境が構築でき、いよいよ自作のアプリや検証などを始めたいところですが、アプリ等の動作環境に当たっては Docker を 使いたいと思います. まずは、その Docker が 動作する環境の構築と動作確認をします.

作業環境

  • Raspbian Jessie Lite
  • Docker

なぜ Docker ?

Docker は ホスト の Linux系 OS が 動作している環境に、コンテナと呼ばれる仮想環境でソフトウェアを動作できるようにする技術です. コンテナ型の仮想化 は、ざっくり言うと ホスト OS 上で隔離された環境(コンテナ)を作り出し、その隔離された環境で動かすソフトウェアなどは ホスト OS の プロセスとして実行される形態になります. そのため 完全な 別 OS の 実行環境を作るハイパーバイザー型の仮想化に対して軽量で動作させることができます.

では、なぜ ラズパイ で Docker を 使おうとしているのか. まずラズパイで GPIO の 実験をしたりだとか、クラウドと連携させて IoT デバイスのような実験をしたりといったことをしたいと考えています. その際に Python や Node.js など使ったり、そのライブラリ、クラウド の SDK に、Web サーバー など の ミドルウェア と 様々なソフトウェアを入れるということが考えられます.
また、その中でうまくいったものは稼働できるよに整理して残しつつ、また他の事をするといったことも考えられるでしょう.

もし、ここまで整理してきた Raspbian の 環境だけで行うとすると、環境がごちゃごちゃになってしまうでしょうし、時には 各種 SDK や ライブラリ の バージョンが競合して問題が発生するといったことも出てくるでしょう. そのために環境を切り替えられるようなライブラリを入れたり、ディレクトリ分けしたりといったこともできるかと思いますが、Docker のような コンテナに閉じ込めてしまえば、そのような問題の多くは解決できます.
また、うまくいって残しておきたいものは環境構築のためのファイル Dockerfile として残しておくこともできるので、外部公開や異なる環境 (ラズパイ上には限るでしょうが) に 移すことも容易になります.

今回は、このような考えから ラズパイ に Docker で アプリ や 検証環境を載せるようにしたいと考えました.

Docker の インストール と 起動実験

Docker comes to Raspberry Pi - Raspberry Pi に従って、Docker の サイトから Shell Script を 落として実行します. curl -sSL https://get.docker.com/ | sh だけで簡単にインストールできます.

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
pi@raspberrypi:~ $ curl -sSL https://get.docker.com/ | sh
...(省略)
+ sudo -E sh -c docker version
Client:
Version: 17.03.1-ce
API version: 1.27
Go version: go1.7.5
Git commit: c6d412e
Built: Fri Mar 24 00:19:15 2017
OS/Arch: linux/arm
Server:
Version: 17.03.1-ce
API version: 1.27 (minimum version 1.12)
Go version: go1.7.5
Git commit: c6d412e
Built: Fri Mar 24 00:19:15 2017
OS/Arch: linux/arm
Experimental: false
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:
sudo usermod -aG docker pi
Remember that you will have to log out and back in for this to take effect!

続いて、インストーラーのスクリプトの出力にあったように、ルートでない pi ユーザで Docker を 実行できるように pi ユーザ を docker グループに追加します. 出力にあったコマンドを、そのまま実行します. その後、デーモンの再起動では聞かないようなので sudo reboot します.

1
2
pi@raspberrypi:~ $ sudo usermod -aG docker pi
pi@raspberrypi:~ $ sudo reboot

コンテナ起動!

Docker は CPU の アーキテクチャ が ホスト と コンテナのイメージ で 同一である必要があります. そのため 2017年3月現在では Docker Hub に ある、ほとんどのイメージが x86_64 のため利用できません.

それでは困るのですが、Get Started with Docker 1.12 on Raspberry Pi の 記事によると、Docker チーム が armfh という prefix で 実験的なイメージを用意しているとのことです.
その記事に則り、Alpine Linux の イメージを使ってコンテナを起動してみたいと思います. オプションは -it-i の インタラクティブモード と -t の tty 接続になり コンテナ内に入って作業ができる状態になります. --rm で 終了時にコンテナを削除します. 後からコンテナにアクセスしたい場合は --rm は 外す必要があります.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pi@raspberrypi:~ $ docker run -it --rm armhf/alpine /bin/sh
Unable to find image 'armhf/alpine:latest' locally
latest: Pulling from armhf/alpine
7c863ad23cb7: Pull complete
Digest: sha256:d90337a24ddb9e72c44b84006cacd57205986a26a3384d6c68653adf2a0d62ba
Status: Downloaded newer image for armhf/alpine:latest
/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.5.2
PRETTY_NAME="Alpine Linux v3.5"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"
/ # exit

参考にさせて頂いた情報


Docker が Raspbian に 対応してくれていたおかげで簡単に動作させることができました. これで様々な環境を作っては壊すということができ、いろいろと試せそうです. 次はラズパイの魅力である GPIO を Docker の コンテナ側からちゃんと使えるかの確認です.

いつか消えた PPT の アバター とか、 Style 1541 とか

パワーポイントで図を描く際にクリップアートの検索を使い、アイコンや画像を探して使っています. このクリップアートの検索がいつの間にか思うような結果を返さなくなりました… なぜ? そして、どうしたら?
現在は「パワポマン」の検索で手に入るようになりましたが、ふと思い出すツイートがありましたので、まとめ.

クリップアートの検索 は 終了した

思い起こすと、いつの間にか終了していました. 普段からパワポなどを使っている方は知っていたのかもしれませんが、パワポと開発環境とを行ったり来たりしていて、ちょうど開発環境のシーズンに終了したようでした…
この件についてはマイクロソフトからの大きなアナウンスは無かったように記憶しています. また、いろいろあるウェブサイトやニュースでも取り上げられていなかったようにも思います.

何が起こったのか改めて探してみたところ、こちら クリップ アートの提供を終了し、Bing イメージ検索に移行 – Office Blogs が マイクロソフトからのアナウンスになっていたようです. 2014年12月に終了した とのこと. そして Bing の イメージ検索を使うようにとのことでした.
うーん、なるほど、通りでクリップアートの検索をいろいろ試すと Bing へ 飛ばされるケースがあったわけですね. そして、その Bing が これまでのクリップアートと同じものは返してくれてなかったと.

マイクロソフトからのアナウンス は あまりにあっさりしていましたが、こちら News & Trend - 要注意!MSオフィス 「クリップアート」の「ひっそり終了」がもたらす混乱:ITpro の 記事では “ニーズ減少で終了、「問い合わせがあったのは日本だけ」 – ITpro” と 具体的というか、直接の話が書かれています. なんと、使っていたのは日本だけだったということでしょうか!? なんてこったい.

その他、改めて検索すると終了の情報がありました. 当時は何で気づかなかったかなぁ…

さぁ 困った Style 1541

さて、そんな中で困ったのが Style 1541、私たちは アバター と 呼んでましたが、人を表す顔のないアイコンです. 本ポストのアイキャッチに使わせていただいているクリップアートさんです.

サーバーのクリップアートなどは何とかなりますし、クラウドについては公式で提供されているものもあり、システムの構成図などはあまり困らなかったりします. (それでも Style 1542 が なくなったのはつらい)

しかしながら、人を表すためのアイコンはどうしても困ってしまう… ビジネスやら、運用やらと、なんだかんだで人を表すシーンはあります. いろいろ探したのですが、どうしてもアイコンセットの画像みたいなものばかりで、個別のアイコンが手に入らずでした.
何とか過去の PPT から サルベージして使いまわしていましたが、全てがそろっているわけでもないですし、縮小していたりすると、もはや元の大きさに戻せない orz

他の素材集を探したり、手に馴染ませるのも、めんどくさい物でして困り果てました.

そして、パワポマン!

そんなある日、どの様な経緯か忘れましたが「パワポマン」というキーワードが引っかかり、念願の Style 1541、アバター の 復刻版 を 見つけることができました!!

マイクロソフト クリップアート 復刻 さん の ウェブサイトです. こちらで消えてしまったクリップアートのアバターさん達を パワポマン として復活させてくださっていました. 復刻の経緯は マイクロソフト クリップアート 復刻: Microsoft クリップアート復旧サイト の ページで詳しく説明されています. 復刻してくださり、ありがとうございます! とてもとても助かりました.

なお、検索ワードは「パワポマン」が よいようです.


と、いうことで、1541 とか、アバター とかで使っていたクリップアートさんは、マイクロソフトの方針で消滅し、マイクロソフト クリップアート 復刻 さん の お力で復活してました.

パワポマンには、いつもいつも お世話になっております. そして、本ポストがパワポマンにたどり着けていない方の導線になれば幸いです.

そもそも元のクリップアートの呼び名自体分からないですし、パワポの丸い人とか、人のアイコンとか、特定のものを指さないような呼び方をしていたように思います. ましてや 1541 なんて知ってる人のが少ないでしょうし、アバターは違うのが引っかかるしと、検索が難しいですよね.

Raspberry Pi 3 を WiFi アクセス・ポイント化する

Raspberry Pi 3 には、有線 LAN と 無線 LAN の 両方が搭載されています. これの両方を活用して 有線 LAN を 既存ネットワークへ接続し、無線 LAN を アクセスポイント化してみたいと思います.
今回は 有線 LAN を 接続する側 の 既存ネットワーク(光ルーターとか)で DHCP などを提供しているものとして、ブリッジ接続の形にしたいと思います.

作業環境

  • Raspberry Pi 3 Model B
  • Raspbian Jessie Lite

ネットワーク・インターフェース の ブリッジ作成

Raspberry Pi 3 に 搭載されている 無線 LAN と 有線 LAN を つなぐブリッジを作成します. これによって 無線 LAN を アクセス・ポイント化した際に、そのまま 有線 LAN 側のネットワークに接続することができます.

ブリッジを作成するには bridge-utils を インストールして設定します. ネットワーク・インターフェースの設定に、ブリッジ・インターフェースを追加して eth0wlan0 を ブリッジさせる設定をします.
設定は /etc/network/interfaces で 下記のように 3行を追加します. 今回の設定は最小限でしました. 設定の詳細は man bridge-utils-interfaces で 確認できます.

1
2
3
4
5
6
7
pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get install bridge-utils -y --no-install-recommends
pi@raspberrypi:~ $ sudo nano /etc/network/interfaces
auto br0
iface br0 inet dhcp
bridge_ports eth0 wlan0

設定後にブリッジのインターフェースをアップさせると状態を確認できます. ifup したら SSH (というか、ネットワーク) が 切断されましたが、問題なく再接続できました. なんだろ…

1
2
3
4
5
pi@raspberrypi:~ $ sudo ifup br0
pi@raspberrypi:~ $ brctl show
bridge name bridge id STP enabled interfaces
br0 8000.13f62a24d4XX no eth0

アクセス・ポイント の 作成

いよいよ 無線 LAN に アクセス・ポイントを作成します. これを稼働させることで WiFi 機器 が 接続できるようになり、上記設定のブリッジを通して既存ネット側につながります.

アクセス・ポイントを作成するには hostapd を インストールして設定します. 設定はサンプルが用意されているのでコピーして変更します. 設定ファイルに説明が書かれているので詳細が確認しながら設定できます. また日本語に訳してくださった方がいらっしゃり、こちら hostapd.conf 覚書 - Qiita @JhonnyBravo も 参考にさせて頂きました. 約 1,700行にものぼるファイルを丁寧に翻訳してくださり、ありがとうございます!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pi@raspberrypi:~ $ sudo apt-get install hostapd -y --no-install-recommends
pi@raspberrypi:~ $ sudo bash -c "zcat /usr/share/doc/hostapd/examples/hostapd.conf.gz > /etc/hostapd/hostapd.conf"
pi@raspberrypi:~ $ sudo chmod 600 /etc/hostapd/hostapd.conf
pi@raspberrypi:~ $ sudo nano /etc/hostapd/hostapd.conf
interface=wlan0
bridge=br0
driver=nl80211
ssid=[SSID]
country_code=JP
hw_mode=g
channel=7
auth_algs=1
ieee80211n=1
wpa=2
wpa_passphrase=[PASS]
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

設定が完了したら起動して確認します. 無事起動したら接続する事ができるので、スマホなどで接続して確認します.

1
2
3
4
5
6
7
8
pi@raspberrypi:~ $ sudo hostapd /etc/hostapd/hostapd.conf
Configuration file: /etc/hostapd/hostapd.conf
Failed to create interface mon.wlan0: -95 (Operation not supported)
wlan0: interface state UNINITIALIZED->COUNTRY_UPDATE
wlan0: Could not connect to kernel driver
Using interface wlan0 with hwaddr f9:15:ac:e4:XX:XX and ssid "[SSID]"
wlan0: interface state COUNTRY_UPDATE->ENABLED
wlan0: AP-ENABLED

起動と接続確認ができたら、ラズパイ起動時に自動的にアクセス・ポイントを起動できるようにします.

1
2
pi@raspberrypi:~ $ sudo nano /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"

クリーンアップ と 再起動

1
2
3
4
5
6
7
pi@raspberrypi:~ $ sudo apt-get autoremove
pi@raspberrypi:~ $ sudo apt-get autoclean
pi@raspberrypi:~ $ sudo apt-get clean
pi@raspberrypi:~ $ sudo rm -rf /var/lib/apt/lists/*
pi@raspberrypi:~ $ sudo rm -rf /var/cache/apt/archives/*
pi@raspberrypi:~ $ sudo reboot

Raspberry Pi 3 を アクセス・ポイントにすることができました! 二つのネットワーク・インターフェースを持っているので、こんなことも簡単にできるのが助かります.

Raspbian Jessie Lite その他 設定

Raspberry Pi の SD 延命化対策もでき、だいぶ設定ができました. 最後に細かい設定をしておきたいと思います.

作業環境

  • Raspbian Jessie Lite

不要なパッケージの削除

今回は Raspbian Jessie Lite なので X Window System などは入っていないので もともと軽量ですが、使っていないパッケージが入っているとアップデート時に時間がかかったりするので、不要なパッケージは削除しておきます… が、あんまり不要なパッケージがなかったです. 一応メモ.

現在入っているパッケージの一覧を取得するには dpkg -l コマンドを使用します.

1
2
3
4
5
6
7
8
9
10
pi@raspberrypi:~ $ dpkg -l
要望=(U)不明/(I)インストール/(R)削除/(P)完全削除/(H)保持
| 状態=(N)無/(I)インストール済/(C)設定/(U)展開/(F)設定失敗/(H)半インストール/(W)トリガ待ち/(T)トリガ保留
|/ エラー?=(空欄)無/(R)要再インストール (状態,エラーの大文字=異常)
||/ 名前 バージョン アーキ 説明
+++-=============-=============-========-========================================
ii acl 2.2.52-2 armhf Access control list utilities
ii adduser 3.113+nmu3 all add and remove users and groups
ii alsa-utils 1.0.28-1 armhf Utilities for configuring and using ALSA
...(省略)

とりあえず削除できそうなのは triggerhappy ぐらいでしょうか. 音声が不要な場合は alsa-utils、固定 IP 化 するなどして Bonjour による hostname.local で アクセスする費用がなければ avahi-daemon も 削除できます. 今回は音声 と Bonjour は 残したいと思います.
dbus は 削除してよいという話がありましたが、avahi-daemon* bind9-host* bluez* bluez-firmware* pi-bluetooth* あたりが巻き込まれて消えるので削除しないほうがよさそうです.

ということで、削除のメモ. (1つだけなら削除しなくても…)

1
pi@raspberrypi:~ $ sudo apt-get purge -y --auto-remove triggerhappy

不要なデーモンの停止

使っていないサービスは停止することでメモリを有効活用!と、思い立つのですが、こちらも、あまり無くメモ.
まずは、稼働しているサービスの一覧を取得. 以下は Raspberry Pi 3 で triggerhappy 削除前の結果. Raspberry Pi Zero では bluetooth.service hciuart.service が なく、serial-getty@ttyAMA0.service が 増えてました. 環境に合わせて不要なら止めておいてくれるみたいですね.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pi@raspberrypi:~ $ systemctl | grep running
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
bluetooth.service loaded active running Bluetooth service
cron.service loaded active running Regular background program processing daemon
dbus.service loaded active running D-Bus System Message Bus
dhcpcd.service loaded active running dhcpcd on all interfaces
getty@tty1.service loaded active running Getty on tty1
hciuart.service loaded active running Configure Bluetooth Modems connected by UART
ntp.service loaded active running LSB: Start NTP daemon
rsyslog.service loaded active running System Logging Service
ssh.service loaded active running OpenBSD Secure Shell server
systemd-journald.service loaded active running Journal Service
systemd-logind.service loaded active running Login Service
systemd-udevd.service loaded active running udev Kernel Device Manager
triggerhappy.service loaded active running LSB: triggerhappy hotkey daemon
avahi-daemon.socket loaded active running Avahi mDNS/DNS-SD Stack Activation Socket
dbus.socket loaded active running D-Bus System Message Bus Socket
syslog.socket loaded active running Syslog Socket
systemd-journald-dev-log.socket loaded active running Journal Socket (/dev/log)
systemd-journald.socket loaded active running Journal Socket
systemd-udevd-control.socket loaded active running udev Control Socket
systemd-udevd-kernel.socket loaded active running udev Kernel Socket

不要なデーモンを停止する場合は下記. ここでは triggerhappy を 例に.

1
pi@raspberrypi:~ $ sudo systemctl disable triggerhappy

NTP に 日本のサーバを設定

時刻合わせの NTP サーバ、当然近い場所にあるサーバの時刻に合わせたほうが良いので設定… たぶん、しなくて大丈夫だと思われます. pool.ntp.org が 使われており、近い場所の NTP サーバを返してくれるためです. 最近のディストリビューションはいろいろと設定済みで助かりますね.

一応 ntpq で 見てみると下記でした. US の NIST に 行っているのもありますが NTT も あるので、まぁよさそうです.

1
2
3
4
5
6
7
pi@raspberrypi:~ $ ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
*timpany.srv.jre 133.243.238.244 2 u 431 1024 377 8.083 -0.138 0.527
+7.83.198.104.bc 169.254.169.254 3 u 1488 1024 372 8.453 0.292 0.833
+153-128-30-125. 133.243.238.244 2 u 357 1024 377 10.422 -0.117 5.420
-y.ns.gin.ntt.ne 249.224.99.213 2 u 470 1024 377 14.798 -4.433 1.423

とはいえ、pool.ntp.org で “pool.ntp.orgは世界中全てのタイムサーバを指定しているので、時間の正確さは理想的ではありません。 もしもうちょっと良い時刻精度 大陸毎のゾーン名や国のゾーン名を指定するとより正確な時刻が得られます。 – pool.ntp.org: プールを利用するためにNTPを設定する方法は?“ と 説明されている通り日本に明示してもよさそうです. 2017年3月現在で 日本 は 66 サーバ なので、使うのはアジアではなく日本でよさそうです.

1
2
3
4
5
6
7
8
9
10
11
pi@raspberrypi:~ $ sudo nano /etc/ntp.conf
#server 0.debian.pool.ntp.org iburst
#server 1.debian.pool.ntp.org iburst
#server 2.debian.pool.ntp.org iburst
#server 3.debian.pool.ntp.org iburst
server 0.jp.pool.ntp.org iburst
server 1.jp.pool.ntp.org iburst
server 2.jp.pool.ntp.org iburst
server 3.jp.pool.ntp.org iburst
pi@raspberrypi:~ $ sudo systemctl restart ntp

カーネルのログを抑制

コンソールに表示されるカーネルのログを抑制します. コンソール出力の抑制であり、ログ自体は /var/log/syslog へ 出力されています. これにより、若干起動速度が上がることが期待できます.
/boot/cmdline.txt の 末尾に quiet を 追記します.

1
2
pi@raspberrypi:~ $ sudo nano /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet

Raspberry Pi 起動時 に HDMI 接続 の テレビを連動させない

Raspberry Pi を HDMI で テレビにつないでいると、Raspberry Pi の 再起動に応じてテレビの電源が入ったり、テレビ番組を見ていたのに HDMI に 切替ったりします. 常時つないでいるわけでなければよいのですが、常時つないでいると不便な面もあったりします.
/boot/config.txthdmi_ignore_cec_init=1 を 追記します.

1
2
pi@raspberrypi:~ $ sudo nano /boot/config.txt
hdmi_ignore_cec_init=1

CPU の 動作クロック設定

たまたま何かの調べて物をしている際に 俺のラズパイ2がこんなに遅いわけがない - 電子計算記 さん の 記事を発見し、気になったことから設定しました.
ちなみに、今回の環境での初期設定は ondemand だったので あえて変更する必要はないかもしれないですが…

cpufrequtils を インストールしコマンドラインから設定します.

1
2
3
pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get install cpufrequtils -y --no-install-recommends
pi@raspberrypi ~ $ sudo cpufreq-set -g performance

続いて再起動しても設定が反映されるよう設定ファイルを作成します. MAX_SPEEDMIN_SPEEDcat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies から出てきた数字を設定します. 下記は Raspberry Pi 3 の ものになります.

1
2
3
4
5
6
pi@raspberrypi:~ $ sudo cp /usr/share/doc/cpufrequtils/examples/cpufrequtils.sample /etc/default/cpufrequtils
pi@raspberrypi:~ $ sudo nano /etc/default/cpufrequtils
ENABLE="true"
GOVERNOR="performance"
MAX_SPEED=1200000
MIN_SPEED=600000

ここで指定する Governor については、以下のようです.

Governor 説明
ondemand cpu の負担が 95% の時に CPU を動的に切り替えます
performance 最大周波数で cpu を動作させます
conservative 負担が 75% の時に CPU を動的に切り替えます
powersave 最小周波数で cpu を動作させます
userspace ユーザーが指定した周波数で cpu を動作させます

※ 参考 CPU 周波数スケーリング - ArchWiki

設定に当たり以下のサイトを参考にさせて頂きました. 有益な情報ありがとうございます!

.bashrc

最後に .bashrc、こちらは、各々 の お好みなので…
今回はラズパイ環境なので、あまり手を入れず最低限の設定をしました.

1
2
3
4
5
6
7
8
9
10
11
pi@raspberrypi:~ $ nano ~/.bashrc
alias ls='ls --color=auto'
alias ll='ls --color=auto --format=verbose'
alias la='ls --color=auto --format=verbose --all'
alias cp='cp --interactive'
alias mv='mv --interactive'
alias rm='rm --interactive'
alias free='free -h'
alias grep='grep --color=auto'
pi@raspberrypi:~ $ sudo reboot

いろいろな環境ごとに .bashrc はじめ、設定ファイルのばらつきがあるので、いずれは本格的に取り組みたいとは思いますが、なかなか手が出せず…

興味津々ではあるが、いつかホンキ出すときに参考にさせて頂きます.

どうでもいい余談ですが、Windows で ドット・ファイル や ドット・フォルダを作るには、エクスプローラーの新規作成で .name. と ドットでファイル名、フォルダ名を挟むと作れます.

クリーンアップ

1
2
3
4
5
pi@raspberrypi:~ $ sudo apt-get autoremove
pi@raspberrypi:~ $ sudo apt-get autoclean
pi@raspberrypi:~ $ sudo apt-get clean
pi@raspberrypi:~ $ sudo rm -rf /var/lib/apt/lists/*
pi@raspberrypi:~ $ sudo rm -rf /var/cache/apt/archives/*

細かい設定を施そうと思っていましたが、思いのほか そのままで良さそうだったのでビックリしました. 世界中の凄い人たちが、より良い設定・環境を作ってくださっているおかげですね. 感謝感謝です!

Raspbian Jessie Lite の SDカード 延命化

Raspberry Pi を サーバのように連続稼働させておくとなると、SD カードの寿命が気になってきます. ちょっと心配なので SD カードへの書き込みを減らして、少しでも延命させたいと思います.

作業環境

  • Raspbian Jessie Lite

Swap 領域 を 無効化する

Raspberry Pi 2 と 3 は メモリが 1GB あり、Zero と Zero W は 512MB あります. 十分な量とは言い難いかもしれませんが、こんな小さなデバイスに様々な機能を押し込めるよりも、機能を絞って乗っているメモリで間に合うようにするのも手です.
そのため、まずは Swap 領域を無効にして SD カードへの退避書き込みをなくしたいと思います.

まず、Swap で 確保されている量を確認します. 約 100MB Swap に 割り当てられてるようです.

1
2
3
4
5
pi@raspberrypi:~ $ free -h
total used free shared buffers cached
Mem: 923M 77M 846M 6.2M 6.9M 39M
-/+ buffers/cache: 30M 892M
Swap: 99M 0B 99M

続いて、現在使用している Swap 領域を無効化し、また Swap 領域のマネージャをパケージごと削除して完全に使用しないようにします.

1
2
3
pi@raspberrypi:~ $ sudo swapoff --all
pi@raspberrypi:~ $ sudo apt-get purge -y --auto-remove dphys-swapfile
pi@raspberrypi:~ $ sudo rm -fr /var/swap

テンポラリ領域 を RAM へ 配置する

テンポラリ領域 /tmp/var/tmp、そうしょっちゅう置かれている感じは無いのですが、わずかとはいえ SD カードへの書き込みは減らしたいところ. これらは自動的に削除されることが前提の場所なので、電源を切った際に消えても問題は無いでしょう.

/etc/fstab/tmp/var/tmp に それぞれ tmpfs で メモリ上のファイルシステム を割り当てます. エディタで /etc/fstab を 開き、下記の 2行を追加します. 追加後は sudo reboot して新しいファイルシステムで起動します.

1
2
3
4
5
6
7
pi@raspberrypi:~ $ sudo nano /etc/fstab
tmpfs /tmp tmpfs defaults,size=32m,noatime,mode=1777 0 0
tmpfs /var/tmp tmpfs defaults,size=16m,noatime,mode=1777 0 0
pi@raspberrypi:~ $ sudo rm -fr /tmp
pi@raspberrypi:~ $ sudo rm -fr /var/tmp
pi@raspberrypi:~ $ sudo reboot

rsyslog の ログ出力を抑制する

続いてログ出力を抑制します. Raspberry Pi の 用途にもよりますが、必要なログだけに絞り込むことで SD カードへの書き込みを減らすことができます.
/etc/rsyslog.conf を エディタで編集します. 編集箇所は #### RULES #### 以降で、下記のように先頭に # を 付けてコメントアウトします. 保存後は rsyslog を 再起動します.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pi@raspberrypi:~ $ sudo nano /etc/rsyslog.conf
#daemon.* -/var/log/daemon.log
#kern.* -/var/log/kern.log
#lpr.* -/var/log/lpr.log
#mail.* -/var/log/mail.log
#user.* -/var/log/user.log
#mail.info -/var/log/mail.info
#mail.warn -/var/log/mail.warn
#mail.err /var/log/mail.err
#news.crit /var/log/news/news.crit
#news.err /var/log/news/news.err
#news.notice -/var/log/news/news.notice
#*.=debug;\
# auth,authpriv.none;\
# news.none;mail.none -/var/log/debug
pi@raspberrypi:~ $ sudo systemctl restart rsyslog

ログ出力ディレクトリ を RAM へ 配置する

ログ出力ディレクトリ を RAM へ 配置し SD カードへの書き込みを抑制します. なお、これをやると電源を切るとログがなくなってしまうので、必要なログがある場合は SD カード側に出すようにするか、定期的&シャットダウン時に退避する仕掛けが必要となります.

まずは /etc/fstab/var/logtmpfs で マウントするように設定します.

1
2
pi@raspberrypi:~ $ sudo nano /etc/fstab
tmpfs /var/log tmpfs defaults,size=32m,noatime,mode=0755 0 0

起動時に /var/log の ディレクトリ構成を復元するスクリプトを設置します. これを忘れるとエラーが発生したり、起動できないプロセスがあったりするので、忘れないようにします.
/etc/rc.localexit 0 の 手前に下記を追加します.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pi@raspberrypi:~ $ sudo nano /etc/rc.local
mkdir -p /var/log/apt
mkdir -p /var/log/fsck
mkdir -p /var/log/ntpstats
mkdir -p /var/log/samba
chmod 750 /var/log/samba
chown ntp:ntp /var/log/ntpstats
chown root:adm /var/log/samba
touch /var/log/btmp
touch /var/log/lastlog
touch /var/log/wtmp
chmod 600 /var/log/btmp
chmod 664 /var/log/lastlog
chmod 664 /var/log/wtmp
chown root:utmp /var/log/btmp
chown root:utmp /var/log/lastlog
chown root:utmp /var/log/wtmp
exit 0

最後にリブートします.

1
2
pi@raspberrypi:~ $ sudo rm -fr /var/log
pi@raspberrypi:~ $ sudo reboot

ext4 ファイルシステム の ジャーナル を 無効化する

ファイルの変更ログの記録で SD カードへ書き込みが発生するので無効化し、抑制します. 本格的なサーバ運用でしたら必須の機能ですが、そうゆのはキチンとしたサーバ用 H/W で 稼働させるとして、ラズパイにはカジュアルな感じで動いてもらおうと思い止めます.

1
2
3
4
5
pi@raspberrypi:~ $ sudo umount /dev/mmcblk0p2
pi@raspberrypi:~ $ sudo tune2fs -O ^has_journal /dev/mmcblk0p2
tune2fs 1.42.12 (29-Aug-2014)
pi@raspberrypi:~ $ sudo reboot


とりあえず考えられそうな書き込み元を止めてみました. それでも Raspberry Pi 3 の ACT LED が かなり点滅しているので、何かしら読み書きしているのかなぁと.
本格的にやるなら監視用のツールでも入れるなり、読み込み専用のファイルシステムにするなりした方がよいのでしょうが、かなりの手間になってしまうので追々と.

GitHub の Private Repository から デプロイキーを使って Read-only clone を 許可する

GitHub の Private Repository に 置いてあるソース を clone させて使いたいケースがあります. そんな場合はデプロイキーを使うことで Read-only な clone を 許せます.

作業環境

  • Windows 7
  • GitHub

背景

今回は Slack の ボット開発で使っているリポジトリから、稼働環境 で clone して実行したいというものになります. Slack の ボット開発では Node.js を 使っています. Node.js は JavaScript なのでリポジトリから clone して直接実行することができ、とても手軽です.
Public Repository でしたら直接ダウンロードできるので特に問題は無いのですが、Private Repository の場合はアクセスするための権限が必要となります.
通常、開発者は自分のアカウントがあり自前の SSH Key を 登録しています. とはいえ稼働環境で、この開発者のキーを使うわけにはいきません. 開発者がアクセスできる全ての権限を稼働環境に置いてしまうことになります.
そこでリポジトリごとに Read-only で clone できる方法が必要となります.

※ 多くの場合は CI と 組み合わせて、自動ビルド・テストからのデプロイを実現しているかと思いますが、今回は簡易ボットの運用なので CI 無しの、clone - 直実行 で 行っているものになります.

SSH Key の 生成

ssh-keygen は Microsoft が 開発している Win32-OpenSSH を 使いました. 生成する鍵の種類と強度は Raspbian Jessie Lite の SSH/公開鍵認証 設定 での調査に則り ed25519 に したいと思います.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
c:\> ssh-keygen -t ed25519 -C ""
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\[username]/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\[username]/.ssh/id_ed25519.
Your public key has been saved in C:\Users\[username]/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:T69X1O58qiKv7Sp/aPJTI+PpzUdOZDO+EcD5ldc8ON8
The key's randomart image is:
+--[ED25519 256]--+
| . . .o.|
| + oo.+|
| o .ooo|
| B ..E|
| S .+ = . |
| ooo.= . .|
| . *.=.+ o |
| o B+o.= +|
| B*OB+...XX|
+----[SHA256]-----+

GitHub の リポジトリ に Deploy Key を 追加

Deploy Key を 登録するリポジトリの設定 https://github.com/[username]/[repository]/settings/keys に アクセスします. ウェブからは [Settings] - [Deploy keys] を たどります.
画面から [Add deploy key] ボタンをクリックします.

Deploy Key 追加画面が表示されるので、[Title] に この鍵のタイトルを付けます. [Key] に id_ed25519.pub の 内容(※ id_ed25519(.pub なし) ではないことに注意)を貼り付けます.
今回は Read-only の Deploy Key にするため、[Allow write access] は チェックせず、[Add key] を クリックします.

GitHub に Deploy Key が 追加されました. Read-only が ついているところがポイントになります.

Deploy Key の 利用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
user@host:/tmp$ mkdir ~/.ssh
user@host:/tmp$ chmod 700 ~/.ssh
user@host:/tmp$ mv /mnt/id_ed25519 ~/.ssh
user@host:/tmp$ chmod 600 ~/.ssh/id_ed25519
user@host:/tmp$ echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
user@host:/tmp$ git clone git@github.com:[username]/[repository].git
Cloning into '[repository]'...
Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts.
remote: Counting objects: 216, done.
remote: Compressing objects: 100% (95/95), done.
remote: Total 216 (delta 56), reused 0 (delta 0), pack-reused 121
Receiving objects: 100% (216/216), 54.22 KiB | 0 bytes/s, done.
Resolving deltas: 100% (123/123), done.
Checking connectivity... done.
user@host:/tmp$ ls -l
total 8
drwxr-xr-x. 6 user user 4096 Mar 13 04:53 [repository]

まずは生成した Deploy Key の Private Key id_ed25519 を 使えるようにします. 今回は /mnt/id_ed25519 に 配置しておいたとして、ホームディレクトリに .ssh ディレクトリを作成して、Private Key を 移動します. パーミッションが正しく設定できていないと鍵が読み込めない場合があるので chmod を 忘れないようにします.

続いて、~/.ssh/config に github.com への接続はホストキーの確認をしない設定します. これを行わない場合 ~/.ssh/known_hosts に github.com の ホストキーが登録されていない場合、以下のようにホストキーの確認を求められ入力待ちとなります. Shell Script などで 自動化する場合に都合が悪いのでホストキーの確認をしないようにしています.

1
2
3
4
5
user@host:/tmp$ git clone git@github.com:[username]/[repository].git
Cloning into '[repository]'...
The authenticity of host 'github.com (192.30.253.113)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)?

後は git clone git@github.com:[username]/[repository].git で clone できるので、Node.js の 実行をするなり自由にできます.

ホントに Read-only なの?

1
2
3
4
5
6
user@host:/tmp/[repository]$ git push origin master
ERROR: The key you are authenticating with has been marked as read only.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.

リポジトリに Push したところ marked as read only と言ってエラーが返るので Read-only に なっているようです.


これで Private Repository でも 稼働環境で git clone で ソースを取得して実行できるようになりました. スクリプト言語などで CI を 組み合わせずに簡易的に動作させる場合は、Deploy Key を 使うことで、ユーザ追加などをせずにアクセス権を絞って clone できるので便利ですね.
本当は CI を 使って、ちゃんと自動テストをしてからデプロイしたほうが良いのですが、お遊びのボットで多少壊れてても許されるような場合には使っていきたいところです.

Botkit が 自動切断されなくなった、みたい

Botkit で Slack の ボットを作成した際に、ボットがいつの間にか止まっているということがあり、ワークアラウンドのコードで対処していました.
2017年3月現在 の 最新 v0.5.1 に したところ、自動停止しないようになったようです.

作業環境

  • Slack
  • Node.js 6.9.1 LTS
  • Botkit 0.5.1

稼働状況を確認

コネクションの接続/切断時にコンソール・ログを出力するだけのボットを設置し放置してみました.

1
2
3
4
5
6
7
8
9
'use strict';
const Botkit = require('botkit');
const controller = Botkit.slackbot();
controller.spawn({
token: process.env.bot_access_token
}).startRTM((err, bot, payload) => { console.log(`start: ${new Date()}`) });
controller.on('rtm_close', (bot, err) => { console.log(`close: ${new Date()}`) });

稼働時のログは下記となります. v0.5.0 から Botkit の バージョンがログ出力されるようになったみたいです.

1
2
3
4
5
6
7
Initializing Botkit v0.5.1
info: ** No persistent storage method specified! Data may be lost when process shuts down.
info: ** Setting up custom handlers for processing Slack messages
info: ** API CALL: https://slack.com/api/rtm.start
notice: ** BOT ID: bot ...attempting to connect to RTM!
notice: RTM websocket opened
start: Fri Mar 03 2017 13:15:21 GMT+0000 (UTC)

開始日時のログ start: Fri Mar 03 2017 13:15:21 GMT+0000 (UTC) が 出ている通り、3月3日 に 稼働をさせて、このポストを書いている時点 3月10日まで rtm_close イベントは呼ばれておらず、また Slack 上でもボットがオンラインであることを確認しています. このボットを仕掛けたのは発言の少ない Slack チームだったので、この期間はボットの連続稼働実験のために完全に会話をしない状態を作り出すことができました. そのため会話に関することは無通信だったと考えてよいはずです.
前回の v0.4.2 では 6時間ぐらいで自動切断されていたのに対して、今回は 7日間は稼働しているので自動切断されなくなったと考えてよさそうです.

Botkit v0.4.2 から v0.5.1 までの更新

何時、何処で自動切断されなくなったのか Change Log を 確認したところ、v0.4.4 で “Make stale connection detection configurable PR #505“ を マージしています.
このタイトルからは、コネクションの自動切断の改善には思えないのですが、他にはコネクションに関する話はなさそうなので、これが気になります.

また コードの比較 からも、コネクションに関係しそうなのは lib/Slackbot_worker.js 周りの変更だと思われます.

これらに関連しているであろう Pull Request #505 を 確認したいと思います.
確認したところ… いきなり出てきた THRASHLIFE に 圧倒、なかなか凄いプルリクです.

それはさておき、肝心の内容ですが、どうもコネクションを維持するための Ping/Pong の 処理が正しく行えていないことについて改善のプルリクに思われます. ただプルリクの書き出で “A LOT of work that was maxing out CPU” と CPU 負荷をかけたケースであることや、最後 jonchurch さん の コメントで “weird edge case” と あるので、今回のように無通信が続いたことによる自動切断とは関連があるとは思えないのですが “the node process wasn’t processing the pong response” が どうしても気になります.

v0.4.2 を 使っていた時も、ほぼ暇なボットで会話の通信も少なかったので CPU 負荷はかかってなかったとは思うので、説明からすると関係はなさそうではあるのですが、他のコード変更が影響しているとは思えないですし. なんだろう…

diff を 確認したいと思います.

pingIntervalId = setInterval((...), 5000)pingTimeoutId = setTimeout((...), 5000); に 変わったところが大きい違いでしょうか. setInterval による繰り返しから、setTimeout の 遅延処理にして処理内で setTimeout を 再呼び出しに変わっています. プルリクでも “replace the use of an interval with a timeout” と言っているので、そう変更したのでしょう.

はたして、この変更が自動切断を防止してくれるようになったのでしょうか… わからない orz

関連する記事の更新


結局 よくわからない、という結論で何とも情けないところではありますが、とりあえず自動切断されなくなり、ワークアラウンドも削除できるので良しとしよう…

最近インストールした Raspbian Jessie Lite が SSH 接続できない?

Crystal Signal Pi が 届いた ので、さっそく Raspbian を セットアップし、Crystal Signal Pi の ソフトウェアを入れて発光色を変えてみたいと思ったところ、まさかの SSH ログインができないというトラブルがあり、意外とはまったのでメモしておきます.

作業環境

  • Windows 7
  • Raspbian Jessie Lite (Release date: 2017-03-02)

トラブルの状況

新規に Raspbian Jessie Lite を SD カードに焼いて(いや、SD だから焼かないですがイメージとして…)、Crystal Signal Pi を 搭載した Raspberry Pi 3 Model B を 起動しました.
そして初期設定のために SSH を したところ、どうしてもつながらないという状況が発生.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
c:\Temp> ssh pi@raspberrypi.local
ssh: connect to host raspberrypi.local port 22: Unknown error
c:\Temp> ssh -v pi@raspberrypi.local
OpenSSH_7.3p1 Microsoft_Win32_port_with_VS, OpenSSL 1.0.2d 9 Jul 2015
debug1: Connecting to raspberrypi.local [ea13::2f1:0d1:adXX:dab%10] port 22.
debug1: socket:444, io:000000000030EE60, fd:3
debug1: finish_connect - ERROR: async io completed with error: 107, io:000000000030EE60
debug1: connect to address ea13::2f1:0d1:adXX:dab%10 port 22: Unknown error
debug1: close - io:000000000030EE60, type:1, fd:3, table_index:3
debug1: Connecting to raspberrypi.local [192.168.0.1XX] port 22.
debug1: socket:404, io:000000000030EE60, fd:3
debug1: finish_connect - ERROR: async io completed with error: 107, io:000000000030EE60
debug1: connect to address 192.168.0.1XX port 22: Unknown error
debug1: close - io:000000000030EE60, type:1, fd:3, table_index:3
ssh: connect to host raspberrypi.local port 22: Unknown error

デバッグ・ログを出してみましたが私のレベルではよくわからず… SSH の デバッグログに出ている IP が 取れているのは ルーター側でも確認できていますし、Ping も 届いていました. ネットワーク的には正しく接続できているようです.

これまでのラズパイは?

久々にインストールから作業したので、だいぶ間が空いてましたが当時使っていた古いイメージ 2016-09-23-raspbian-jessie-lite.img が 残っていたので、こちらを新規で使ったところ SSH 接続できました. あれ?

ということは、これまでのバージョンアップの中で何かが変わったのかもしれません. ということで、ようやくリリースノートをあたります. (もっと早く見ようよ、自分 orz)
以下 http://downloads.raspberrypi.org/raspbian/release_notes.txt より抜粋.

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
2017-03-02:
* Updated kernel and firmware (final Pi Zero W support)
2017-02-16:
* Chromium browser updated to version 56
* Adobe Flash Player updated to version 24.0.0.221
* RealVNC Server and Viewer updated to version 6.0.2 (RealVNC Connect)
* Sonic Pi updated to version 2.11
* Node-RED updated to version 0.15.3
* Scratch updated to version 120117
* Detection of SSH enabled with default password moved into PAM
* Updated desktop GL driver to support use of fake KMS option
* Raspberry Pi Configuration and raspi-config allow setting of fixed HDMI resolution
* raspi-config allows enabling of serial hardware independent of serial terminal
* Updates to kernel and firmware
* Various minor bug fixes and usability and appearance tweaks
2017-01-11:
* Re-release of the 2016-11-25 image with a FAT32-formatted boot partition
2016-11-25:
* SSH disabled by default; can be enabled by creating a file with name "ssh" in boot partition
* Prompt for password change at boot when SSH enabled with default password unchanged
* Adobe Flash Player included
* Updates to hardware video acceleration in Chromium browser
* Greeter now uses background image from last set in Appearance Settings rather than pi user
* Updated version of Scratch
* Rastrack option removed from raspi-config and Raspberry Pi Configuration
* Ability to disable graphical boot splash screen added to raspi-config and Raspberry Pi Configuration
* Appearance Settings dialog made tabbed to work better on small screens
* Raspberry Pi Configuration now requires current password to change password
* Various small bug fixes
* Updated firmware and kernel

ありました! ちょうど、これまで使っていた 2016-09-23 の 次のリリース 2016-11-25 で変わったようです.
SSH は デフォルトで起動しないようになっていて、ブート・パーティション に “ssh” というファイルを置くことで有効にできるようです. これによって、接続ができなかったのですね…

1
2
2016-11-25:
* SSH disabled by default; can be enabled by creating a file with name "ssh" in boot partition

これからのセットアップ

セットアップについては、これまで通り SD カードをフォーマットして、イメージを書き込むところまでは同じになります. 最後に “ssh” というファイルを置くという手順が増えました.

Windows からは、エクスプローラー で SD カード の ドライブを開いて、”ssh” というファイルを作ります.

作るファイルのもとは何でもよく拡張子を削除して作るだけになります. 今回はビットマップ イメージを選び、最初から入力されていた 新しいビットマップ イメージ.bmp を 消して ssh としました. “拡張子を変更すると、ファイルが使えなくなる可能性があります。” と 警告表示されますが、今回は特に問題ないので [はい] を クリックして進めます.

“ssh” というファイルが置かれました. これで完了、後は起動するだけです.

関連する記事の更新


ファイルを置いたら何時もと変わりなくアクセスできるようになりました. SSH 接続できないと各種設定ができないように思いますが、どうして SSH を デフォルトで無効にしたのだろう…

Crystal Signal Pi が 届いた!

Raspberry Pi に 約 7cm ぐらいの 四角柱 を 立て、マルチカラー の LED を で光らせることができるモジュール Crystal Signal Pi が 届き、ようやく組み立てができました. 本来はサーバなどの監視を行い、警告をわかりやすく表示してくれるものですが、いろいろな使い方に挑戦してみたいと思います. まずは、早速組み立てから.

作業環境

  • Raspberry Pi 3 Model B
  • Crystal Signal Pi

Crystal Signal Pi とは?

Crystal Signal Pi は、Raspberry Pi に 約 7cm ぐらいの 四角柱 を 立て、マルチカラー の LED を で光らせることができるモジュールです.
クラウド・ファンディングで購入者を募集されていることを知って、興味を持ち応募しました. クラウド・ファンディングの仕組みを使っていたとはいえ、製造は確定していたので普通に購入する形です.

光で監視するソリューション“ を キーワードに、2016年11月 の オープンソースカンファレンス 2016 Tokyo/Fall で デモをされたようです.
その際の資料はこちら、でしょうか. → “あらゆるイベントを可視化する! RaspberryPiで作るLED警告灯ソリューション

Crystal Signal Pi 到着 & 組立

開発元のインフィニットループさんの封筒で届きました. 写真では宛名部分を折り返していますが、 2つ購入で A4 の 封筒半分ちょっとぐらいです.

中身は緩衝材でしっかり保護されています.

1つ 1つ パッケージングされています. 丸穴をあければお店に そのまま吊るせる感じです. こんな感じで手軽に購入できるようになってほしいですね.

パッケージの中身は以下になります. 丁寧に部品ごとにも袋に入っています.

  • 説明書など書類 3枚
  • 基盤 1枚
  • ケースのアクリル板 2枚 と ネジ、滑り止め
  • LED で 発光する 四角柱 と ゴムバンド

説明書があるので、そう迷わず組立できました. 今回は Raspberry Pi 3 Model B を 使いました. なお組み立ての説明書 は PDF で 公開 されています. PDF は カラーなのでイメージがつかみやすいかもしれません.
まずケースのアクリルにネジとスペーサー入れ、ラズパイを載せ、続いてラズパイとCrystal Signal Pi 基盤の間用のスペーサーで留めます. ネジ穴が切ってあるのでクルクルして簡単に仮留めできます.

続いて Crystal Signal Pi の 基盤を載せます. GPIO に合わせたソケットが取り付けられているので、そのまま差し込みます.

最後にカバーのアクリル板をかぶせますが、四角柱を通してからカバーを載せます. 後は しっかり、ねじ止めして完成!

いざ、点灯!

Crystal Signal Pi の ソフトウェアが用意されていますが、インストールしなくても通電すると、緑とオレンジに交互に点滅した後、緑で光り続けます.
明るいところでは四角柱の側面部分は光がとおっている感じで発光感は強くないです.

天頂部は強く光っており斜めから見てもかなり眩しいです.

明るさ調整するにはソフトウェアが必要ですね. ソフトウェアを入れていないので、こちらも当然ですが、オレンジ色の丸ボタンも反応しません. また、shutdown した後も光続けています.


ラズパイで簡単な状態通知をできる Crystal Signal Pi、面白いプロダクトだと思います. API も 用意されているのでアイデア次第でいろいろな使い方ができそう.

2017年 3月現在、初期ロットのクラウド・ファンディングが終わったところで、次回ロットについては、オフィシャル・サイトでメール登録することで連絡をもらえるとのことです. 思った以上にすごくよかったので、さっそくメール登録しました!

Hexo の フッター に ソーシャル・アイコン を 設置

Hexo の デフォルト・テーマ Landscape に Twitter の 設定を追加した話では、ソーシャル・アイコンが追加されると早とちりをしてしまいました. 改めて思うと、ソーシャル・アイコンは、やはり どこかに配置しておきたいなぁと思うので、設置してみます.

作業環境

  • Hexo 3.2
  • Disqus
  • Twitter

設置場所 の 検討

トップのタイトル・カバーやサイド・バーに配置されているケースが多いように感じます. そういった場所に配置しようかと思ったのですが、現在のレイアウトから手ごろな配置が浮かばなかったので、今回はフッターのコピーライトの横あたりにひっそりと置いておくことにします.

アイコン集 の 検討

アイコン、アイコンはいろいろあるので悩みます. 素敵なデザインのサイトから頂戴しようかと思いましたが、まずは Font Awesome を 使って設定したいと思います.

Font Awesome は 各種アイコンをフォントとして用意してくれています. フォントなので大きさを変えても崩れませんし、色を変更することもできます. 単色の色設定にはなってしまいますがシンプルなテイストでまとめるとも考えられますし、とても使いやすいツールです.

ライセンスは、こちら で 2017年3月現在 の Version 4.7.0 では、フォント は SIL OFL 1.1、CSS などのコードは MIT と、今回のようなブログに設定するにはフリーで使わせていただけます. ただし企業や組織のブランド系のアイコンについては、注意書きがあるので確認およびそれに従った運用が必要です. Font Awesome の ライセンス を ご確認ください.

Hexo Landscape は /themes/landscape/source/css/fonts に Font Awesome の フォントが入っています. そのため新たに追加しなくても使えるのが嬉しいところです.

Hexo Landscape に 設置、も?

設置場所、アイコン集も決まったので Hexo Landscape に 配置していきます.
フッターに配置することにしたので、編集するファイルは /themes/landscape/layout/_partial/footer.ejs に なります. コピーライトの部分は以下のコードになっており &copy; 行 の <br> の 前に置くことでコピーライト表示に並べて行けそうです.

1
2
3
4
<div id="footer-info" class="inner">
&copy; <%= date(new Date(), 'YYYY') %> <%= config.author || config.title %><br>
<%= __('powered_by') %> <a href="http://hexo.io/" target="_blank">Hexo</a>
</div>

続いて、Font Awesome の アイコン ですが、こちらは Icons ページ から利用したいアイコンをクリックし、表示されたコードをコピペすることで簡単に利用することができます. たとえば Font Awesome の アイコン は <i class="fa fa-font-awesome" aria-hidden="true"></i> です.

とりあえず GitHub と Twitter を 配置するとして、以下のようなコードを置きました.
必要なソーシャルアイコンのタグを調べて配置して終了!

1
2
3
4
5
6
7
<div id="footer-info" class="inner">
&copy; <%= date(new Date(), 'YYYY') %> <%= config.author || config.title %>
<a href="https://github.com/[username]" target="_blank" title="GitHub"><i class="fa fa-github" aria-hidden="true"></i></a>
<a href="https://twitter.com/[username]" target="_blank" title="Twitter"><i class="fa fa-twitter" aria-hidden="true"></i></a>
<br>
<%= __('powered_by') %> <a href="http://hexo.io/" target="_blank">Hexo</a>
</div>

いざ表示!と、行きたかったのですが、残念ながら表示されませんでした…
コードは追加されており、配置されている場所こそ気にはなるもののレンダリングもされているようです. しかし、<i> の スタイルシート が user agent stylesheetfont-style: italic; に なっています.

なんと、Hexo Landscape には Font Awesome の フォント は 入っているものの、CSS が 入っていない… 読み込んでいないではなく、物理的にファイルもない のでした. そのため、Font Awesome の タグ ではアイコンが入ってくれないという事象が発生したものになります.

Unicode 指定 による CSS で 設置

タグ による指定できないので、フォントから直接 Unicode で 指定する方法を取りたいと思います.
Unicode による指定は、CSS で font-family に Font Awesome の フォントを指定し、content に Unicode で 使用する文字を指定します. Unicode は Icons ページ に コードが書かれているので、そちらを指定します. たとえば Font Awesome の アイコン は f2b4 なのでエスケープを入れて content: "\f2b4"; と なります.

CSS の クラス定義は、ちょうどソーシャルへシェアするためのアイコンのクラス定義があるので、それに習って作成したいと思います.
ファイルは /themes/landscape/source/css/_partial/article.styl で、$article-share-link.article-share-twitter などがソーシャル・シェアのアイコンになります. こちらをまねて $article-link.article-link-twitter.article-link-github を 作成しました.
フォント・カラー を 直前のコピーライトと合わせ、文字をやや大きくしています. Unicode は Twitter が f099 で、GitHub が f09b なので、それぞれ content に 指定しています.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$article-link
color: #999 !important
&:before
font-size: 24px
font-family: font-icon
text-align: center
&:hover
color: #fff !important
text-decoration: none !important
.article-link-twitter
@extend $article-link
&:before
content: "\f099"
.article-link-github
@extend $article-link
&:before
content: "\f09b"

/themes/landscape/layout/_partial/footer.ejs は 先ほどのリンクを作る <a> タグ に クラス定義をあてるだけになります.

1
2
3
4
5
6
7
<div id="footer-info" class="inner">
&copy; <%= date(new Date(), 'YYYY') %> <%= config.author || config.title %>
<a href="https://twitter.com/[username]" class="article-link-twitter" target="_blank" title="Twitter"></a>
<a href="https://github.com/[username]" class="article-link-github" target="_blank" title="GitHub"></a>
<br>
<%= __('powered_by') %> <a href="http://hexo.io/" target="_blank">Hexo</a>
</div>

いざ、表示!


無事表示することができました. Font Awesome は よく利用させていただいています. 絵心やデザイン・センスががない身としてはとても助かっています. ありがとうございます!
普段はタグで指定しているので Font Awesome の CSS が 無いケースでの設定は初めてでしたが、ちょうど ソーシャル・シェア の 定義があり流用できたので助かりました.
テーマへの手入れが増えてきたので、そろそろテーマを切り替えて本格的にやっていきたいのですが、なかなか手が出せず、今しばらくは Hexo Landscape に ちょくちょく手を入れつつお世話になりそうです.