コーヒー飲みながら仕事したい

仕事で使う技術的なことの備忘録とか


Wordpress に引っ越しました!

Dockerfile を使って、自分用の Ubuntu の Docker イメージを作成する

前回の続き。

tassi-yuzukko.hatenablog.com

今回の目的

docker pull ubuntuで最新版のubuntuイメージを取得することはできる。
しかし、その場合、 sudoすら入っていない状態なので、一つずつ apt-get で環境整備する必要が出てくる。 そこで、Dcokerfile を使用して楽をする。

Dockerfile とは

イメージのカスタマイズをスクリプトで実現することができる。
Dockerfile を使用することで、物理的に異なるデバイスでも、同一の環境をすぐ用意できるようになる。たぶん。

Ubuntu 用の Dockerfile 導入手順

参考

前提

そもそも Docker を導入した最終目的は protobuf-cで遊ぶためのコンパイル環境を用意することである。
そのため、 Ubuntu 用の Dockerfile も protobuf-c のコンパイルのためにカスタマイズする。

  • protobuf-c をコンパイルするために必要なもの一覧
    • sudo
    • autoconf
    • automake
    • libtool
    • curl
    • make
    • g++
    • unzip
    • pkg-config
    • protobuf(後述の注意の通り、apt-getで取得するのはNG)
  • あと、あれば便利なもの一覧

注意:protobuf-c と protobuf の互換性問題

現状、protobuf-c の最終リリース版(protobuf-c Ver1.30)自体に、本家 protobuf との互換問題があるらしい。
(protobuf Ver3.00 以上を用意しないと protobuf-c がコンパイルできない。しかし、Ubuntu 用の apt-get では protobuf のバージョンがVer2.6X らしいので、普通に本家 protobuf を用意するのではなく、自前で用意する必要がある)

上記を踏まえて Dockerfile を作る

そもそも、Dockerfileの置き場所はどこが適切なのか調べたが、ぱっと出てこない。
たぶん、どこでもいいような気がするので、今回はDocker ToolBox のルートパスである C:\Program Files\Docker Toolbox 直下に置いてみる。
Windows 10 では Program Files 内に直接ファイルを作ることはできないので、℃っか違うところで作って move する)

ファイル名は、まんまDockerfile (拡張子なし)でたぶんOK。

ファイルの中身は以下のようにしてみた。

#利用するUbuntuのイメージ
FROM ubuntu:14.04

#プロキシ設定が必要な場合のみ
#ENV https_proxy=XXX
#ENV http_proxy=XXX

#各種インストール
RUN apt-get update
#protobuf はあえてインストールしない
RUN apt-get install -y sudo autoconf automake libtool curl make g++ unzip pkg-config wget git

Dockerfile をビルド

docker build -t ubuntu1404 . でビルドする。(-t はタグ名なので必須だが任意の文字列)

イメージの取得も行うため、結構時間かかる。

追記

しかも、私の環境では powershell の描画更新がバグって

debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype

とか出たりしたけど、気にしないでおこう・・・

さらに追記

さらに私の環境ではビルドが終了すると、上記の描画問題に加え、以下の警告が表示された。

SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

うーん、大丈夫なのかなぁ。
内容としては「 '-rwxr-xr-x' になってるよ!」ってだけだから問題なさそうだけど。

イメージの確認

docker images でイメージが作成されたことを確認する。

PS C:\Program Files\Docker Toolbox> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu1404          latest              1d8f1efde705        10 minutes ago      382MB

たぶん入ってるっぽい。

コンテナの起動

docker run -it -v /work:/work ubuntu1404 で起動する。(前回行った共有フォルダのマウントも有効にしている)

Dockerfile によるカスタマイズの確認

とりあえず make あたりを実行すしてみる。

root@8c8f74f92f1a:/# make
make: *** No targets specified and no makefile found.  Stop.

と出て、 make というコマンドを認識してるっぽいので、成功していることがわかる。


とりあえず今回は Dockerfile を使用して、 Ubuntu による protobuf-c のコンパイルの準備までやった。
次回は、protobuf および protobuf-c のコンパイルに焦点を当てて記事を書く。

Docker でホストマシンのストレージ移動と共有フォルダのマウント

Docker ホストマシンのストレージを移動する

イメージを入れる前に、Docker ToolBox を使用している場合は、C:\Users\<ユーザー名>\.docker\machine\machines\<マシン名>に仮想ディスクファイル (.vmdk) が作られるらしい。
私の環境ではCドライブが切迫しているので、取り急ぎDドライブに移動する。

基本的に↓参照でおk。
(注意:VirtualBox立ち上げっぱなしで.vboxファイル編集してもダメ。.vboxファイルは仮想マシン起動時ではなく、VirtualBox本体を立ち上げるときに読み込まれるらしい。

takaya030.hatenablog.com

データを永続化するために、ストレージを共有フォルダ化する

dockerコンテナは、そのままではデータを永続的に保持できないらしい。そのため、共有フォルダを使用して、データ永続化を実現する必要がある。

ぱっと調べた感じ、参考になるのはあったが、Windows野郎の私にとってはsshの手順とかも慣れていないのですんなりいかなかった。ので、備忘録として手順等を残しておく。

1. VirtualBoxに共有フォルダ設定する

とりあえずここではD:\docker\workを共有フォルダにしてみた。 f:id:tassi-yuzukko:20180303232030j:plain f:id:tassi-yuzukko:20180303232036j:plain f:id:tassi-yuzukko:20180303232040j:plain

2. 起動時設定ファイルを作る

Docker Machineの起動時に、共有フォルダが自動でマウントされるように設定ファイルと作る。

  1. docker-machine ssh実行
    • power shell で実行すると文字化けするので、git bash でやった方が良いかも
  2. /var/lib/boot2docker/bootlocal.shに以下のように書いて保存する
    • bash で操作するから、たぶん vi 使わないといけないんだけど、sudo vi /var/lib/boot2docker/bootlocal.shてな感じで sudo が必要
mkdir -p /d/docker/work
mount -t vboxsf -o defaults,iocharset=utf8,uid=1000,gid=50 work /d/docker/work

3. 設定を有効にする

最後にいったんdocker-machine stop defaultした後に再度 docker-machine start default で docker を再起動する。

参考

共有フォルダをマウントしてコンテナを起動する

docker run -it -v /work:/XXX <コンテナ名>:<タグ> で、上述した work のシンボリックリンクの共有フォルダが、 コンテナ上に XXX フォルダとしてマウントされる。

うーん、ややこしいなぁ。

Docker を Windows 10 Home 環境で動作させてみる

あらすじ

前回

tassi-yuzukko.hatenablog.com

Windowsでのmakeとかがうまくいかなかったので、開き直って「もうLinux環境でやってやる!」となったので、Dockerをインストールすることにする。

Docker ToolBox

どうやらWindows 10 ProじゃないとDocker for Windowsを動かしてくれないそう。(Hyper-Vの関係らしいけど、詳しいことはわからん)
Windows 10 Home民専用に、VirtualBox必須という条件付きでDockerできるDocker ToolBoxというものがあるらしい。民の私はこれをインストールする。

インストール

ググってたら、

qiita.com

こちらがわかりやすそうだったんで、これを参考にする。

起動

とりあえず上記記事を参考に起動するところまでやってみた。

とりあえず現状把握している状況としては、予想だけどこんな感じ。

  • Oracle VM Virtual Box マネージャー なるもので、VirtualBox上でどれくらいリソース食っているか確認できる
  • Dcoker CLIを起動すると、Power Shell が起動する

Dockerで遊ぶ

一通りのチュートリアルが以下にあったのでそちらを参考にいろいろやってみる。

www.ogis-ri.co.jp

よく使うと思われるDockerコマンド

  • docker pull <イメージ名>
    • イメージ名を取得する
  • docker images
    • 取得済みイメージ一覧を表示
  • docker run <イメージ名> <コンテナで起動するコマンド>
    • 取得済みのイメージをについて、コンテナを作成(create)し、そのコンテナを起動(start)する
    • これだけだと、コマンド実行後にすぐにコンテナは終了するが、docker run -it <イメージ名> <コンテナで起動するコマンド>のように-itオプションを付けると、コンテナ接続を終了しない
  • docker stop <プロセス番号>
    • 指定したプロセス番号のコンテナを終了する
    • プロセス番号は、docker psで確認できる

コンテナの再操作

docker run -itでコンテナ起動後、power shell を閉じても、docker stop しない限り、コンテナは終了しないみたい。
そうなると、power sherll 閉じた後に再びコンテナの操作する必要があると思うが、その場合はdocker attach <プロセス番号>を使用してコンテナの再操作ができる。

コンテナの終了方法

上記docker stopでもよいが、操作中ならCtrl + dでも終了できる。

コンテナやイメージの削除方法

下を参照。

qiita.com

基本的に、イメージを削除するためにはまずはコンテナを削除する必要があるっぽい。
で、コンテナは終了していてもID自体は残っているらしい。


とりあえずここまで。
次はubuntuのイメージでも入れてみたいと思います。

Protocol Buffers のC言語版で遊んでみる

ことの成り行き

Windows PC から、C言語しか動作しない低性能ハードウェアとEthernet通信するという案件がある。
もともと、Windows PC からIoT機器に対するEthernet通信(というかMQTT)では伝文のシリアライズフォーマットにJSONの使用を考えていた。しかし、対低性能ハードウェア視線で考えると、C言語JSONのパースはちょっときついかも・・・
そこで、C言語でも実装できるようなシリアライズフォーマットで何か良いのないかなぁと探していたら、protobuf-cなるものを見つけた。

protobuf-cとは、google謹製Protocol BuffersC言語版らしい。

もともと、MQTTに適したシリアライズフォーマットを調査してたときにProtocol Buffersは候補に挙がっていたので、「こんなのもあるのかー」と一応存在自体は把握していた。が、対象がC++Pythonであると思っていたので、「それならお手軽JSONでいいやー」とスルーしていた。

ここにきて、C言語対応のシリアライズフォーマットとして筆頭候補に挙がってきたので、ちょっとどんなものなのか遊んでみる。

実行環境

とりあえず本番環境がWindows10 IoTなので、それに近い環境で手元にあるWindows10 64bitでいろいろやってみる。

環境の構築

Readme.mdに書かれているが、
protobuf-c requires a C compiler, a C++ compiler, protobuf, and pkg-config to be installed.
と書いてあるので、それらを入手する必要がある。
the autotools (autoconf, automake, libtool) must also be installedと言われているのでそららもいるかもしれないが、とりあえず今は様子見しとく。なお、Qiitaの記事autoconfの説明で参考になるものがあった。)

タチが悪いことに、環境がWindowsなので、色々遠回りに環境構築する必要がある。
備忘録を兼ねて、それらを残しておく。

protobuf-cのクローン

とりあえず環境作成のためには、protobuf-cを自前ビルドすることが前提のようなので、このソースコードgithubからクローンする。

CコンパイラおよびC++コンパイラの入手

手持ちにgit bashがあったのでそれで代用するという手抜きをする。
git bashにはもともとgccコンパイラが入っているっぽい)

ちなみに、git bashGit for Windowsをインストールする過程で入手できる。

注意

普通にgit bashを使って、後述するmakeすると、

/usr/bin/sh: line 1: C:/Program: No such file or directory

とかいって怒られる。

これに結構ハマったんだけど、どうやらgit bashのデフォルトインストール先がC:\Program Files\GitなのでC:\Program Files\Git\usr\bin\sh.exeにアクセスしようとする過程で、半角スペースが含まれるのでアクセス不可になってたっぽい。
いろいろ対処法探したんだけど、これといって良いのが見つからなかったので、最終解決手段として私はC:\Program Files\GitフォルダをC:\Git(C直下)にコピーして、そのフォルダ内のgit bashを使用することでmakeを解決できた。

protobufの入手(windows

githubのreleasesページから~win32.zipをダウンロードする。
binフォルダ内にprotoc.exeがあるので、それを取得。

pkg-configの入手(windows

Readme.md#buildingに書いてある通り、./configを使用できるようにする必要がある。そのため、pkg-configが必要。

こちらからtar.gzをダウンロードし、そいつを、クローンしたprotobuf-cフォルダの中に展開する

注意

そのまま./configureやると

configure: error: Either a previously installed pkg-config or "glib-2.0 >= 2.16" could 
not be found. Please set GLIB_CFLAGS and GLIB_LIBS to the correct values or pass 
--with-internal-glib to configure to use the bundled copy.

とか言われてエラーになったので、こちらを拝見して、./configure --with-internal-glibと実行する。うまくいった。

makeの入手(windows

素のWindows環境では、makeコマンドが効かないので、それを用意する必要がある。
とりあえずgnuwin32からインストーラをダウンロードする。(Complete package, except sources の SetUp )

git bashを使用する場合、前述したmake実行できないトラップがあるので注意。

protoc-cの生成

./pkg-config/configure --with-internal-glib && make && make installで行けるやろ!
って思って実行したけど、

/usr/bin/sh: -c: line 0: syntax error near unexpected token `('
/usr/bin/sh: -c: line 0: `test -f config.h || C:/Program Files (x86)/GnuWin32/bin/make  stamp-h1'
make: *** [config.h] エラー 1

って怒られる。こりゃWindowsは無理かなーってことで今諦めモードです。

こうなったら意地でもどうなるかやってみたいので、Linux環境でやるしかないね。
てことで、秘蔵っ子のDocker for Windowsに手を出してみるか・・・!

備考

なお、autoconfを使用したautogen.shを試してみたいのだが、Windows用autoconfのGnuWin32鯖落ち?してるので手に入れることができない・・・

C#でTCP通信のプログラムを作ってみる

主題の通り、作ってみるのだが、とりあえず今は調査中なので「これは押さえておきたい」というところのメモ

目的

基本的にはサーバープログラムを作る。
同時に複数のコネクションが接続されることを想定する。

基本的には↓が参考になる。

ichiroku11.hatenablog.jp

ただし、ReadObjectWriteObjectの拡張メソッドは自前実装しなければならないとのこと。

やらないといけないこと

定期的な死活監視が必要

クライアントは一度コネクションを張ると、切断せず接続しっぱなしにする予定。
そのため、クライアントとの接続が生きているかを監視する必要がある。

解決策

blog.sky-net.pw

常時コネクション

kou-yeung.hatenablog.com

Windows10が勝手に自動更新してウザイとき

Windows10で自動更新がかかるのを制御する方法。作業中にいきなりCPU100%とかなって邪魔されるので、自動更新を切ります。

Windows10 Pro であることが前提です。あと、更新が一切かからなくなるので、手動更新は自己責任です。

Windows Update を無効にする方法

↓に答えがあります。

itblogdsi.blog.fc2.com

一点、Windows Update が再び勝手に開始されることを防ぐためにローカルグループポリシーをいじる必要があるのですが、gpedit.msc を実行すると、ローカルグループポリシーエディターが起動します。

dotnet ef migrations add したら Unable to create an object of type 'ApplicationDbContext' と怒られるとき

ことの成り行き

もともと dotnet core 1.1 のプロジェクトを dotnet core 2.0 にターゲットフレームワークを差し替えた時のお話。
コードファーストでDBを作るために、主題の通り dotnet ef migrations add XXX を実行したら Unable to create an object of type 'ApplicationDbContext' と怒られた。
ググったら既知の問題らしかったので、備忘録として残す。

解決方法

↓に書かれている通り、Program.cs を修正する。

www.ryadel.com

一応念のため、ソースコードを記載しておく。

public static void Main(string[] args)
{
    // REPLACE THIS:
    // BuildWebHost(args).Run();
 
    // WITH THIS:
    var host = BuildWebHost(args);
    using (var scope = host.Services.CreateScope())
    {
        // Retrieve your DbContext isntance here
        var dbContext = scope.ServiceProvider.GetService<ApplicationDbContext>();
 
        // place your DB seeding code here
        DbSeeder.Seed(dbContext);
    }
    host.Run();
 
    // ref.: https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/
}
 
public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();

WebHost.CreateDefaultBuilder なんてねーよって怒られるとき

で、これだけじゃうまくいかないのが嫌なところ。
dotnet core 1.1 のプロジェクトがベースの場合、上記の通り、 WebHost.CreateDefaultBuilder が存在しないって怒られる。
これは、Nuget しているパッケージのバージョンも dotnet core 2.0 用に更新する必要があるから。

ここまでやって、やっと先に進めた。

けど・・・

結局マイグレーションがうまくいかない。
dotnet ef migrations add XXX を実行すと、成功したようになるんだけど、DB側にはテーブルが作られていない。
コードファースト諦めるかなぁ。要調査