glibcを更新しても大丈夫な「正しい」タイムゾーンの設定方法 (2/3追記あり)

RHEL, CentOS, Amazon Linux (6以前)

/etc/localtime を /usr/share/zoneinfo 以下から上書きしたりシンボリックリンク張ったりという手法が横行していますが、 /etc/localtime は glibc パッケージに含まれるためパッケージを更新すると上書きされてESTとかに戻ってしまうわけです。

当然ながら、ディストリビューションとして正しい設定方法が用意されているので、こちらを使います。

  1. /etc/sysconfig/clock にタイムゾーンを書きます。*1
    sudo sed -i -e "s/^ZONE/#ZONE/g" -e "1i ZONE=\"Asia/Tokyo\"" /etc/sysconfig/clock
  2. tzdata-update を実行します。
    sudo /usr/sbin/tzdata-update

これだけです。glibcのパッケージをアップデートした時にも、glibc-commonのトリガスクリプトとしてtzdata-updateが自動で呼ばれます。sysconfigで設定してコマンドで現状に反映させるという普通のRHELの世界観そのままですね。

ちなみに、よりRHELの世界観に沿うために、CUIのグラフィカルインターフェースとして system-config-date が用意されていますが、忘れて良さそうな気がします。

(補足) EL7以降というかsystemd系ディストリビューションはtimedatectl(man)使うとのこと。

Ubuntu, Debian GNU/Linux

Debian系というぐらいでdebconf ベースですが、 /etc/timezone を参照してdebconfのデータベースに反映してくれるようになっています。Debianは使っていないので未確認ですが、同じで良いとのこと。

  1. /etc/timezone にタイムゾーンをベタで書きます。
    echo "Asia/Tokyo" | sudo tee /etc/timezone
  2. dpkg-reconfigureでdebconfの設定処理を走らせます。
    dpkg-reconfigure --frontend noninteractive tzdata

CUIでカーソル選択とかしたくない人がほとんどだと思うので、 noninteractive 積極的に使っていきましょう。

ディストリの世界観

今回の「glibc更新するとタイムゾーンがリセットされる!?」とかそうですが、普通に作業して明らかに面倒とか不便とか問題があったら、そのまま回避策を採るのでは無く、まずその設定方法がディストリビューションの世界観に沿っているかを疑ったほうが「急がば回れ」になります。

というか、こういうの探すときに、「ディストリビューションが提供しようとしている世界観」を意識するかどうかで探し方全然変わるので、誰かまとめて欲しい。

超ざっくりこれ:

  • EL系: 設定は/etc/sysconfig 以下に書く。反映方法は割と適当。
  • Debian系: 設定は debconf のデータベースに登録し、dpkg-reconfigureで反映
  • systemd系: なんちゃらctl
  • Gentoo: emergeがなんとかしてくれる

追記: 2015-01-31 01:21

/etc/sysconfig/clock の既存設定を残すよう、tee -a に変更しました。
「正しい」とか煽りながら非互換だしていてすみませんorz

さらに追記 2015-02-03 17:12

tzdata-update は、/bin/sh等に依存しないようにC言語で書かれた小さなプログラムなのですが、最初のZONE指定が有効になるようです*2。安易にtee -aで追記にしたら反映されないというご指摘を頂きました。

sysconfig 以下のファイルは通常はシェルスクリプトとして解釈されるという思い込みがあったのですが、記事修正するときに検証を怠った結果がこれです。
ざっと確認した範囲では見つけられなかったのですが、自前で /etc/sysconfig/clock を呼んでいるシェルスクリプトがあると危険なので、記事無いの置換コマンドは、単純な追記で無く既存のZONE行を潰してから先頭に追記するようにしました。

というわけで、/etc/sysconfig の一般的な文法(これも「世界観」の一部)から外れることもあるので、盲信せずきちんと検証しましょうという良い教訓でした。記事書いて良かった……。

*1:tzdata-update は最初の記述が有効になりますが、シェルスクリプトとして他のソフトウェアから読まれる可能性があるため、他のZONE行は消して置いた方が良いと思います。

*2:たぶんこの辺。見つかったら即breakしてる。 https://www.sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=fedora/tzdata-update.c;h=33bb8c67e379c88dc4af0fcbf5dc33c55973302f;hb=9da0dd7c81b1cedd383e0eba09c9452d2874f862

あけましておめでとうございます

今年で35歳を迎えるので、引き続きフルスタックエンジニア目指して頑張ります*1

今年の抱負

「明確な成果を出す」
細かい目標はあとで決めます。

読書目標

昨年は無事500冊の目標を505冊で達成できた*2ので、今年も500冊目指して読みます。
ただラノベに偏りすぎたので、サブKPIをいっこ追加で。

  • 月40冊
  • 追加: 技術書(雑誌除く) 10%

ブクログだけだと達成管理できないのどうしようかなあ。

2014年に読んだ本

2014年は505冊読みました。

技術書 24冊 (5.0%)

nekoruri bookshelf - 2014年01月〜2014年12月 (24作品)
テスタブルJavaScript開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質説得とヤル気の科学 ―最新心理学研究が解き明かす「その気にさせる」メカニズムITロードマップ2014年版: 情報通信技術は5年後こう変わる!Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)【改訂新版】 サーバ/インフラエンジニア養成読本 [現場で役立つ知恵と知識が満載!] (Software Design plus)【改訂新版】 サーバ/インフラエンジニア養成読本 管理/監視編 [24時間365日稼働を支える知恵と知識が満載!] (Software Design plus)【改訂新版】 サーバ/インフラエンジニア養成読本 仮想化活用編 [クラウドな現場で役立つ知恵と知識が満載!] (Software Design plus)フロントエンド開発徹底攻略 (WEB+DB PRESS plus)Ruby徹底攻略 (WEB+DB PRESS plus)フロントエンドエンジニア養成読本 [HTML、CSS、JavaScriptの基本から現場で役立つ技術まで満載! ] (Software Design plus)Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)Amazon Web Services 基礎からのネットワーク&サーバー構築すべてわかる4G大全 (日経BPムック)ITナビゲーター2014年版パターンによるソフトウェア構成管理 (IT Architects’ Archive―ソフトウェア開発の課題)パーフェクトPython (PERFECT SERIES 5)AngularJSリファレンスAngularJSアプリケーション開発ガイドクラウドデザインパターン Azureを例としたクラウドアフリケーション設計の手引きOpenStack Swift: Using, Administering, and Developing for Swift Object StorageImplementing Cloud Storage with OpenStack SwiftSoftware Defined Storage with OpenStack Swiftインフラエンジニア教本 ~ネットワーク構築技術解説 (Software Design 別冊)
powered by booklog

技術書(雑誌) 21冊 (4.2%)

nekoruri bookshelf - 2014年01月〜2014年12月 (21作品)
週刊 アスキー 2014年 3/11号 [雑誌]Software Design (ソフトウェア デザイン) 2014年 03月号 [雑誌]週刊 アスキー 2014年 3/18号 [雑誌]WEB+DB PRESS Vol.78週刊アスキー 4/29増刊号日経 Linux (リナックス) 2014年 05月号Software Design (ソフトウェア デザイン) 2014年 05月号 [雑誌]Software Design (ソフトウェア デザイン) 2014年 04月号 [雑誌]Software Design (ソフトウェア デザイン) 2014年 06月号 [雑誌]WEB+DB PRESS Vol.81Software Design (ソフトウェア デザイン) 2014年 07月号 [雑誌]週刊 アスキー 2014年 7/22号 [雑誌]Software Design (ソフトウェア デザイン) 2014年 08月号 [雑誌]週刊アスキー 2014年 8/12増刊号WEB+DB PRESS Vol.82Software Design (ソフトウェア デザイン) 2014年 10月号 [雑誌]Software Design (ソフトウェア デザイン) 2014年 11月号 [雑誌]WEB+DB PRESS Vol.83Software Design (ソフトウェア デザイン) 2014年 12月号 [雑誌]Software Design (ソフトウェア デザイン) 2015年 01月号 [雑誌]WEB+DB PRESS Vol.84
powered by booklog

ライトノベル 424冊 (84.0%)

nekoruri bookshelf - 2014年01月〜2014年12月 (424作品)


powered by booklog

コミック 29冊 (5.7%)


nekoruri bookshelf - 2014年01月〜2014年12月 (29作品)
ノーゲーム・ノーライフ 1 (アライブ)魔法科高校の劣等生(1) (Gファンタジーコミックススーパー)魔法科高校の劣等生(2) (Gファンタジーコミックススーパー)魔法科高校の劣等生 (3) (Gファンタジーコミックススーパー)魔法科高校の劣等生 入学編 (4)(完) (Gファンタジーコミックススーパー)魔法科高校の優等生 (2) (電撃コミックスNEXT)魔法科高校の優等生 (3) (電撃コミックスNEXT)

Ameba等で利用しているOpenStack Swiftを利用したオブジェクトストレージ

CyberAgent エンジニア Advent Calendar 2014 5日目です。
5日目は、インフラ&コアテク本部の@nekoruriが担当します。

私たちが所属するインフラ&コアテク本部は、「(^q^)くおえうえーーーるえうおおおwwwwwwwwwwwwwww」でお馴染みアニメ放映中のガールフレンド(仮)アメブロを初めとするAmeba755などグループ会社に対して、最適化されたサービスインフラとその運用ノウハウを提供する組織です。自社開発のプライベートクラウドの開発・運用だけでなく、パブリッククラウドCDNなどの外部サービスの活用支援や、サービスに関するセキュリティプロセスなど、「サービスを動かす基盤」全体の向上に責任を負っています。

今日は、インフラ&コアテク本部が提供しているサービスの一つである、AOS(Airforce Object Storage)と呼ばれるオブジェクトストレージについて紹介します。

AOS: Airforce Object Storage

以前エンジニアブログで紹介した画像配信基盤とは別に、変換など画像に特化した機能がない代わりに汎用に使えるAOSという汎用データストアを運用しています。

スマホ専用電子コミックサイト「読書のお時間です」や「アメーバピグ」などで使われているほか、自社のネットワーク内にあり、通信費を掛けずに大量に高速の転送が可能という利点を活かし、各サービスのバックアップデータなども保管しています。ざっくり比較すれば、某氷河系ストレージほど安くは無いが柔軟に利用でき、某低冗長化ストレージよりは安価で気楽に利用できる、という感じの位置付けを目指しています。

こんな感じの目的を実現するため、クラウド基盤OSSのOpenStackに含まれるSwiftをベースに、キャッシュや管理機能を追加したものがAOSです。

AOSの全体像がこちらです。

OpenStack Swiftを中心に、キャッシュとパス変換のためのVarnishを前段に置き、それらを管理する管理画面を自作しています。また、独自の認証基盤へ繋ぎ込むため、Keystone等は利用せず、管理画面からswauthへの同期を行っています。

VarnishマジVarnish

静的なファイルの配信と言えばキャッシュです。あらゆる段階でキャッシュをどれだけ活かすことができるかに、サービスの品質やコストが直結します。AOSではVarnishによるキャッシュを標準で提供することで、そういった要求に対応しています。
データストアの人柱として有名な弊社ですので、もちろんVarnishのバックエンドストレージとしてもpersistentを利用しています。他のmallocやfileではvarnishdを再起動するとキャッシュデータが消えてしまうのですが、persistentであれば永続化されているためカジュアルにrestartできます。とはいいつつ、persistentはやむを得ない理由が無ければ使うなという状況になっているため、今後はどうしようかなというところです。
特徴的な使い方としては、AOSへはいくつかのホスト名を付与していて、ホスト名ごとにVarnishのキャッシュポリシーを変更しています。例えば、さらに上位にAkamai等のCDNを挟む場合は、中間層でのキャッシュがトラブルの元となる可能性があるため、一切キャッシュをしないホスト名を用意しています。簡単なVCLでこのような柔軟な対応ができるのもVarnishならではですね!

認証にswauthを利用しているため、Swiftそのままだと、URLに
http://example.jp/AUTH_12345678-1234-1234-1234-1234567890ab/file.jpg
のような「AUTH_」で始まるアカウントの識別子が含まれてしまい、ちょっと格好悪いです。そこで、Varnishに変換ルールを仕込み、管理画面からその変換ルールを設定できるようにしています。また、キャッシュのパージも管理画面から実施できます。このように、開発者がインフラエンジニアの手に頼らず自力で設定できる環境を整備していくのも、インフラ&コアテク本部のミッションの一つです。

ちなみに、varnishには「うわべだけ取り繕う」「ごまかす」という意味があるそうです。今知りました。

細かすぎて伝わらないSwiftのTIPS

まさかのGREEさんとのネタ被りですが、オブジェクトストレージの根幹となっているのがSwiftです。

Swiftは、とにかくHTTPちっくなAPIでファイルを置けてパーミッションとかも良い感じに掛けられてサーバ増やせばいくらでも冗長性・拡張性が確保できる夢みたいなストレージで、ぶっちゃけるとAmazon S3みたいな奴です。国内だとGMOインターネットこのはちゃん採用しているのでご存知の方が多いと思います。

今更Swiftの紹介とか書いても、SwiftStackのドキュメントより分かりやすいものができるわけもないので、AOSの担当になってから今までに得た細かいTIPSを書いていきます。

ゾーン追加とレプリカ数

Swiftはデータの冗長性を確保するため、「極力遠くに同じデータ(標準では3つのレプリカ)を保存する」という仕組みになっています。この「遠さ」を表現するために、以下のような階層が用意されています。

  1. Region (最上位)
  2. Zone
  3. Node (1IPアドレスで特定される1サーバ)
  4. Disk (サーバ上のマウントポイント)
  5. Partition (データの保存単位)

全てのデータは、Partitionという単位でまとめられて、それがどこかのRegion、Zone、Node、Diskに分散してばらまかれる事になります。この分散先を決めるときに先ほどの「極力遠くに」というポリシーが前提となるわけです。例えば1サーバ1ディスクだけのテストサーバであればその1ディスクの那珂に全部入りますし、たくさんのリージョンに別れた広域分散環境であれば、良い感じに分散してくれるというわけです。

──さて。

AOSでは当初の設計として物理サーバを2つのラックに設置しており、ラック単位でのネットワークスイッチや電源の故障に備えるため、1ラック=1 Zoneとして構築しました。その後、順調に利用量が増えて1ラック分サーバを追加することになりました。サーバ追加するだけで簡単にキャパシティも増える夢のストレージですよさすがですね!ただ、いくら追加すれば良いとはいえ、初の大規模拡張なので、何かあってもすぐ切り戻せるように少しずつ追加していきたいところです。

とりあえず検証してみました。そりゃもうloopback mount生やしまくりで数だけ合わせて1GBのディスクをなんと合計200本以上も作りました。追加しました。







そう、Zoneをまたいで分散しろというプレッシャーが強すぎて、追加した1台のサーバに3つめのレプリカが集中してしまうのです。Swiftには、どのサーバにどれだけのデータを割り振るかを「Weight」として指定することができるのですが、Zoneを跨げという力の前には無力で、たとえweightを他のサーバの1/100にしていても同じ結果でした。

というわけで、最初のキャパシティプランニング段階でZone数はレプリカ数に合わせて設計しておき、Zone内でのサーバ追加で対応できるようにするのが良いです。

サーバ追加後のデータ同期

swift-recon というコマンドを使うと、全てのサーバ・全てのディスクごとに、利用率を比較することができます。

===============================================================================

    • > Starting reconnaissance on 17 hosts

===============================================================================
[2014-12-05 19:59:46] Checking disk usage now
Distribution Graph:
54% 1 *
56% 2 ***
57% 7 ***********
58% 13 *********************
59% 34 *******************************************************
60% 42 *********************************************************************
61% 26 ******************************************
62% 8 *************
63% 11 ******************
68% 2 ***
69% 3 ****
70% 9 **************
71% 10 ****************
72% 17 ***************************
73% 10 ****************
74% 5 ********
75% 3 ****
76% 1 *
Disk usage: space used: 390692674875392 of 611703698153472
Disk usage: space free: 221011023278080 of 611703698153472
Disk usage: lowest: 54.01%, highest: 76.43%, avg: 63.8695950433%
===============================================================================

サーバを追加すると、0%のところに「*」が増えて、データ同期が進むにつれてじわじわ他の利用率に近寄っていきます。そこで、この出力をみんなだいすきGrowthForecastに流し込んであげればさらっと可視化できます。recon_growthforecast.shとして置いておきますので、興味がある方はお試しください。

あと、当然ながら、でっかいストレージだとデータ同期もでっかい時間が掛かります。
100TB/1Gbps=約9.3日、という計算式を置いておきます。

swauthのパスワードを調べる

swauthは、OpenStack標準の認証コンポーネントであるKeystoneを使わないときに用いるSwift独自の認証機構です。swauthはSwift内部のミドルウェアとして組み込まれ、認証情報をSwift自身に保存します。しかも驚きのplaintextで。そのため、swauthのパスワードを後から取得することができます。

swauthが認証に関する情報を保存するため、super_admin_keyというマスターパスワードを使います。このsuper_admin_keyというさも強そうなパスワードは、プロキシサーバの設定ファイルに書かれています。そのsuper_admin_keyを見つけられれば、あとは swauth-list コマンドが使えます。


# grep super_admin_key /etc/swift/proxy-server.conf
super_admin_key = PASSWORD
# swauth-list -K PASSWORD ca.amb.username ca.amb.username
{"groups": [{"name": "ca.amb.username:ca.amb.username"}, {"name": "ca.amb.username"}, {"name": ".admin"}], "auth": "plaintext:USERPASSWD"}

これでパスワードを忘れても大丈夫ですね!

コンテナ内のファイル数

という話題で書こうとしていたら、GREEさんとネタが被ったので省略します。

物理配置を調べる

どのデータをどのノードのどのディスクに保存するかは、リングと呼ばれるファイルで定義されています。swift-get-nodesというコマンドにこのリングファイルを食わせてあげることで、どこに物理的に配置できるかを知ることができます。

手順的には二段階で、まず対象のアカウントを調べます。

# swift -A http://127.0.0.1:8080/auth/v1.0 -U username:username -K USERPASSWD stat | grep Account
Account: AUTH_12345678-1234-1234-1234-1234567890ab

続いて、コンテナ名を指定して、swift-get-nodes を実行します。

# swift-get-nodes /etc/swift/container.ring.gz AUTH_12345678-1234-1234-1234-1234567890ab containername
Account AUTH_12345678-1234-1234-1234-1234567890ab
Container containername
Object None

Partition 219040
Hash deadbeefdeadbeefdeadbeefdeadbeef
Server:Port Device 2001:db8:dead:beef::ffff:feff:1:6001 sde
Server:Port Device 2001:db8:dead:beef::ffff:feff:2:6001 sdj
Server:Port Device 2001:db8:dead:beef::ffff:feff:3:6001 sdi
Server:Port Device 2001:db8:dead:beef::ffff:feff:4:6001 sdb [Handoff]
Server:Port Device 2001:db8:dead:beef::ffff:feff:5:6001 sdl [Handoff]
Server:Port Device 2001:db8:dead:beef::ffff:feff:6:6001 sdm [Handoff]

curl -I -XHEAD "http://2001:db8:dead:beef::ffff:feff:1:6001/sde/219040/AUTH_12345678-1234-1234-1234-1234567890ab/containername"
curl -I -XHEAD "http://2001:db8:dead:beef::ffff:feff:2:6001/sdj/219040/AUTH_12345678-1234-1234-1234-1234567890ab/containername"
curl -I -XHEAD "http://2001:db8:dead:beef::ffff:feff:3:6001/sdi/219040/AUTH_12345678-1234-1234-1234-1234567890ab/containername"
curl -I -XHEAD "http://2001:db8:dead:beef::ffff:feff:4:6001/sdb/219040/AUTH_12345678-1234-1234-1234-1234567890ab/containername" # [Handoff]
curl -I -XHEAD "http://2001:db8:dead:beef::ffff:feff:5:6001/sdl/219040/AUTH_12345678-1234-1234-1234-1234567890ab/containername" # [Handoff]
curl -I -XHEAD "http://2001:db8:dead:beef::ffff:feff:6:6001/sdm/219040/AUTH_12345678-1234-1234-1234-1234567890ab/containername" # [Handoff]

Use your own device location of servers:
such as "export DEVICE=/srv/node"
ssh 2001:db8:dead:beef::ffff:feff:1 "ls -lah ${DEVICE:-/srv/node}/sde/containers/219040/eef/deadbeefdeadbeefdeadbeefdeadbeef/"
ssh 2001:db8:dead:beef::ffff:feff:2 "ls -lah ${DEVICE:-/srv/node}/sdj/containers/219040/eef/deadbeefdeadbeefdeadbeefdeadbeef/"
ssh 2001:db8:dead:beef::ffff:feff:3 "ls -lah ${DEVICE:-/srv/node}/sdi/containers/219040/eef/deadbeefdeadbeefdeadbeefdeadbeef/"
ssh 2001:db8:dead:beef::ffff:feff:4 "ls -lah ${DEVICE:-/srv/node}/sdb/containers/219040/eef/deadbeefdeadbeefdeadbeefdeadbeef/" # [Handoff]
ssh 2001:db8:dead:beef::ffff:feff:5 "ls -lah ${DEVICE:-/srv/node}/sdl/containers/219040/eef/deadbeefdeadbeefdeadbeefdeadbeef/" # [Handoff]
ssh 2001:db8:dead:beef::ffff:feff:6 "ls -lah ${DEVICE:-/srv/node}/sdm/containers/219040/eef/deadbeefdeadbeefdeadbeefdeadbeef/" # [Handoff]

よく分かっているなと思うのが、Swift API(curl)でコンテナの情報を取ったり、対象サーバに接続してディレクトリをlsするワンライナーがどかどか表示されるところです。

例えば、もし仮に万が一1コンテナ内に1億ファイルくらい突っ込んじゃってコンテナのSQLite DBがどれぐらいのサイズに太っちゃったか知りたくなったときも、表示されれたssh行を実行すれば、すぐに該当ディレクトリをlsしてDBサイズを診ることができるわけです。素晴らしいですね。

ソースコード

Swiftの一番良いところは、Pythonで書かれていて、ソースコードにもすぐにアクセスができるところです。また、ソースコードも良い意味でそれほど大きくないため、LL言語に馴染みのある人であれば、ちょっとした動きに違和感があり調査が必要になっても追いかけることがで来ます。

Grizzlyのswift-ring-builderコマンドにはIPv6アドレスを受け取れない不具合があるのですが、ちょっと検索すれば正規表現を直すパッチが転がっていたりしますし、作業用サーバだけ手パッチ当てて動作確認みたいなこともすぐに可能です。ここまでカジュアルに深いところまで触りやすいデータストアはSwiftぐらいでは無いでしょうか。

「Swift」

どこかのアップルとか言うスマホの会社がiOS(IOS)に続いてど派手な名前被りをしてくれたせいで、「Swift」という語句のググラビビリティが大変下がってしまいました。諦めて「OpenStack Swift」で検索しましょう。

まとめ

Swiftは、OpenStackのコンポーネント群のなかでも、Rackspaceが商用サービスで使っていたものをベースとしているだけあって非常に枯れています。また、HTTP(REST)ベースということで内部のトラブルシュートもしやすいです。

うまく他のネットワーク環境との兼ね合いや機器構成を練らないと、パブリッククラウドのオブジェクトストレージとコストだけで闘うのは厳しいですが、うまくユースケースにはまればとても便利な基盤になるので、どうぞご利用ください。

Dockerfile for Tiarra

今日はTiarra

Tiarraのconfはちょっといろいろ分量おおいのでどうしようかと思ったけど、結局VOLUMEから注入する形であきらめた。まあ動的にいじってRELOADすることもあるだろうしこれはこれで良いのかも。

/data/conf 以下にconf置いて、docker run時にファイル名を指定です。


mkdir -p $HOME/tiarra/conf
vi $HOME/tiarra/conf/your.conf
docker run -d --name tiarra -v $HOME/tiarra:/data:rw -p 6667:6667 nekoruri/tiarra:0.1 your.conf

だんだんなれてきた。

Dockerfile for RawGit

RawGit落ちてて自前でも欲しいって話が出たので早速作ってみる。


docker run -d -e FQDN=rawgit.example.jp --name rawgit -p 80:80 -p 443:443 nekoruri/rawgit:0.1

Vagrant用にbootstrap.shがあったのでそのままそれを利用してるので、そのままだとオレオレ証明書が勝手に作られてTLSでもサービス上がります。このあたりの整備は後ほど。

あと、12-factor appに従って、docker run -e FQDN=rawgit.example.jp でFQDNを注入できるようにしてみた。

ミニマムなDockerfile for GrowthForecastつくってみた

自分が使いたくてミニマムなGrowthForecastのDockerfileが欲しかったので作ってみた。

とりあえずDocker hubに投げてみたけど、Buildingから進まないので細かいことはあとで書く。

あと、いくつか考えたポイントをGistにぺらぺら書き残してる。

これだけでいける。


mkdir -p $HOME/vol/gf
docker run -d --name growthforecast -v $HOME/vol/gf:/data:rw -p 5125:5125 nekoruri/growthforecast:0.1

残り課題

  • VOLUME書き忘れた
  • [ok] Trusted buildからpullして動かすテスト
  • timezone