Go
Linux
golang
docker

dockerでgolangの実行ファイル1個だけを含むイメージを作って動かす

はじめに

前回の記事 でdockerではネットワークのアクセスとUTCの現在時刻の設定に関しては自動でやってもらえるということがわかった。
ということなので、今回はbusyboxの代わりにgolangで書いた簡単なhttp file serverを1個だけを含むイメージを作って動かしてみる。

http file server のビルド

httpfileserver.go
package main

import (
    "log"
    "net/http"
)

func main() {
    log.Fatal(http.ListenAndServe(":80", http.FileServer(http.Dir("/"))))
}

static linkになるように、CGO_ENABLED=0 をつけてビルドする。

CGO_ENABLED=0 go build

static link になっていることを確認。

$ file httpfileserver
httpfileserver: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

docker のイメージを作成して実行

テンポラリなディレクトリに httpfileserver を一個だけ入れて、それで dockerのイメージを作成する。

mkdir /tmp/a
cp httpfileserver /tmp/a
cd /tmp/a
tar cf - . | docker import - httpfileserver0:latest

コンテナ内のport:80が外から見えるようにbindして実行する。

docker run -p 0.0.0.0:80:80/tcp httpfileserver0 /httpfileserver

実行結果

http://localhost/

.dockerenv
dev/
etc/
httpfileserver
proc/
sys/

http://localhost/etc/

hostname
hosts
mtab
resolv.conf

http://localhost/proc/

1/
acpi/
buddyinfo
bus/
cgroups
cmdline
consoles
cpuinfo
crypto
devices
diskstats
dma
driver/
execdomains
fb
filesystems
fs/
interrupts
iomem
ioports
irq/
kallsyms
kcore
key-users
keys
kmsg
kpagecgroup
kpagecount
kpageflags
loadavg
locks
mdstat
meminfo
misc
modules
mounts
mtrr
net
pagetypeinfo
partitions
sched_debug
schedstat
scsi/
self
slabinfo
softirqs
stat
swaps
sys/
sysrq-trigger
sysvipc/
thread-self
timer_list
tty/
uptime
version
version_signature
vmallocinfo
vmstat
zoneinfo

当然だが、このコンテナの中で動いているプロセスは1個だけ。

$ curl -I http://localhost/
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Last-Modified: Sat, 14 Apr 2018 01:09:59 GMT
Date: Sat, 14 Apr 2018 01:18:31 GMT
Content-Length: 191

HTTPのレスポンスヘッダの中の時刻も特に問題無し。

追加ファイル

golangの実行ファイル1個だけで動かす場合には制限があります。
時刻はUTCでしか扱えませんし、TLS(暗号化通信)は使用できません。
これらのためには/etc にファイルを追加する必要があります。
以下の記事の「追加ファイル」の章を参考にしてください。
minimumgo: Linuxでgolangの実行ファイルをひとつだけ動かすときに必要最小限の初期化処理をしてくれるgolangのパッケージ