ためすう

Goに入門するため、Dockerで環境を構築する

2020-12-20

やったこと

Go の開発環境を Docker で構築してみます。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d
$ docker-compose --version
docker-compose version 1.27.4, build 40524192

調査

Quick start

こちらを使います。

$ git clone git@github.com:tamesuu/docker-sample.git
$ cd docker-sample/golang/
$ mkdir work

ホストOS

$ vim work/main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

ホストOS

$ docker-compose up -d
Recreating golang_app_1 ... done
$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
832161a8fe30        golang_app          "bash"              58 seconds ago      Up 57 seconds       0.0.0.0:9000->8080/tcp   golang_app_1
$ docker-compose exec app go run main.go
Hello, World!

docker-compose --help より

exec Execute a command in a running container

コンテナに対して、コマンドを実行します。

ディレクトリ指定版

$ mkdir work/hoge
$ vim work/hoge/server.go
$ docker-compose exec app go install hoge

docker-compose exec app go help より

install compile and install packages and dependencies

$ docker-compose exec app ../bin/hoge
server dayo
$ docker-compose exec app go env | grep GOPATH
GOPATH="/go"

ここはハマったのですが、go install した時、go/bin にビルドされた結果が出力されるようでした。

go/src
go/bin

gRPCのQuick start (Ruby)をやった

2020-12-19

やったこと

gRPC に入門します。

公式のチュートリアルとは少しだけ手順を変えてやっていきます。言語はRubyです。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d

調査

gRPC とは

Googleが開発を開始したオープンソースのリモートプロシージャコール (RPC) システムである。

さらにデフォルトで、Protocol Buffersを使うことが出来ます。

Protocol Buffers とは

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler

シリアライズしてあるデータで、速い(とのこと)。

Quick start を進める

tab1 (server)

-- local
$ docker run -it --rm grpc/ruby bash

-- コンテナ
$ gem install grpc

$ gem install grpc-tools

$ git clone -b v1.34.0 https://github.com/grpc/grpc
$ cd /grpc/examples/ruby
$ ruby greeter_server.rb

tab2 (client)

※ コンテナIDを $ docker ps を実行するなどして取得してください

-- local
$ docker exec -it de1f4f419893 bash

-- コンテナ
$ cd /grpc/examples/ruby

-- 編集用
$ apt-get update
$ apt-get install vim

今回は、tab2 (client) の中で色々作業していきます。

examples/protos/helloworld.proto

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // 今回追加する
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

gRPCのコードを生成

$ grpc_tools_ruby_protoc -I ../protos --ruby_out=lib --grpc_out=lib ../protos/helloworld.proto

このファイルが更新されました。

	modified:   lib/helloworld_pb.rb
	modified:   lib/helloworld_services_pb.rb

greeter_server.rb

class GreeterServer < Helloworld::Greeter::Service
  ...(省略)

  def say_hello_again(hello_req, _unused_call)
    Helloworld::HelloReply.new(message: "Hello again, #{hello_req.name}")
  end
end

greeter_client.rb

def main
  stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
  user = ARGV.size > 0 ?  ARGV[0] : 'world'
  message = stub.say_hello(Helloworld::HelloRequest.new(name: user)).message
  p "Greeting: #{message}"

  # ここが追加するコード
  message = stub.say_hello_again(Helloworld::HelloRequest.new(name: user)).message
  p "Greeting: #{message}"
end

実行します

$ ruby greeter_client.rb

最後に

新しい言葉が多く出てきましたが、手を動かすことで開発の流れを少しだけイメージすることができました。

gRPC は数種類の通信方法があるみたいなので、やっていきたいと思います。

参考

docker-compose config を使ってみる

2020-12-18

やったこと

docker-compose config を使ってみます。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d
$ docker-compose --version
docker-compose version 1.27.4, build 40524192

調査

docker-compose config --help より

Validate and view the Compose file.

ファイルのバージョンをバリデーションをしてくるようです。

それでは使ってみましょう。

バリデーションが通る場合

docker-compose.yml

version: '3'
services:
  app1:
    build: .
    ports:
      - '9000:8080'
  app2:
    build: .
    ports:
      - '9090:8080'

このオプションをつけて実行してみます。

–services Print the service names, one per line.

$ docker-compose config --service
app1
app2

バリデーションが通らない場合

docker-compose.yml

version: '3'
serves:
  app1:
    build: .
    ports:
      - '9000:8080'

service と書くべきところを serves とします。

エラーが発生しました。

$ docker-compose config --service
ERROR: The Compose file './docker-compose.yml' is invalid because:
Invalid top-level property "serves". Valid top-level sections for this Compose file are: version, services, networks, volumes, secrets, configs, and extensions starting with "x-".

You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/

docker-compose build して、Dockerコンテナの起動までしてみる

2020-12-13

やったこと

これらのコマンドを使っていきます。

  • docker-compose build
  • docker-compose up -d

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d
$ docker-compose --version
docker-compose version 1.27.4, build 40524192

調査

docker-compose build を実行する

docker-compose --help より

build Build or rebuild services

docker-compose build --help より

Build or rebuild services.

Services are built once and then tagged as project_service, e.g. composetest_db. If you change a service’s Dockerfile or the contents of its build directory, you can run docker-compose build to rebuild it.

Usage: build [options] [–build-arg key=val…] [–] [SERVICE…]

Dockerfile

FROM golang:latest

WORKDIR /go/src

ADD . /go/src

docker-compose.yml

version: '3' # composeファイルのバーション指定
services:
  app:
    build: .
    tty: true # コンテナの起動永続化
    volumes:
      - .:/go/src
    ports:
      - '9000:8080'

build 実行前

$ docker images | grep "app"
$ docker-compose images
Container   Repository   Tag   Image Id   Size
----------------------------------------------

ビルド実行

$ docker-compose build
Building app
Step 1/3 : FROM golang:latest
 ---> 8e2ffcb73e11
Step 2/3 : WORKDIR /go/src
 ---> Using cache
 ---> 7dbb384cb1ad
Step 3/3 : ADD . /go/src
 ---> b59a010ffd5b

Successfully built b59a010ffd5b
Successfully tagged golang_app:latest

ビルド実行後

$ docker-compose images
Container   Repository   Tag   Image Id   Size
----------------------------------------------
$ docker images | grep "app"
golang_app                           latest

Dockerイメージが作成されたことが分かります。(ちなみに、この挙動について公式ドキュメントが見つからなかった)

docker-compose up -d を実行する

$ docker-compose up -d
Creating network "golang_default" with the default driver
Creating golang_app_1 ... done

起動確認

$ docker ps | grep golang
45e0a8b4a6d2        golang_app            "bash"                   51 seconds ago      Up 48 seconds       0.0.0.0:9000->8080/tcp     golang_app_1
$ docker container ls | grep golang
45e0a8b4a6d2        golang_app            "bash"                   59 seconds ago      Up 56 seconds       0.0.0.0:9000->8080/tcp     golang_app_1
$ docker-compose ps
    Name       Command   State           Ports
-------------------------------------------------------
golang_app_1   bash      Up      0.0.0.0:9000->8080/tcp

起動していることが確認できました。

おまけ

コンテナに接続する

$ docker-compose exec app /bin/bash

参考

Dockerコンテナにポート指定してみる

2020-12-12

やったこと

Dockerコンテナにポート指定してみます。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d

調査

$ docker container run \
> -d \
> --name nginx_test \
> -h host1 \
> -p 9090:80 \
> nginx:1.17
378b845265d4deb9ff6213ec37f82d3eaab57943b359b8db252c759d2f4535b9

$ docker container ls -a | grep nginx_test
378b845265d4        nginx:1.17            "nginx -g 'daemon of…"   33 seconds ago      Up 32 seconds               0.0.0.0:9090->80/tcp       nginx_test

docker container run --help より

-p, –publish list Publish a container’s port(s) to the host

http://localhost:9090/ にアクセスすると、nginx の Welcome ページが見えるかと思います。

ポート: 9090 でアクセスすると、80 に飛ばされるようになりました。

Dockerで起動コンテナにホストOSのVolumeを提供する

2020-12-11

やったこと

Dockerで起動しているコンテナに、ホストOSのVolumeを提供して共有で使います。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d

調査

今回 docker container run で、このオプションを使ってみます。

-v, –volume list Bind mount a volume

タブ1: ホストOS (手元のPC) で起動するコンテナに提供するVolume

$ pwd
/tmp/test_volume
$ tree
.
└── sample.txt
$ cat sample.txt
123

タブ2: コンテナ起動

$ docker container run \
> --name abc_container \
> -h host1 \
> -it \
> -v /tmp/test_volume:/tmp \
> ruby:2.5 \
> /bin/bash
root@host1:/# ls /tmp/
sample.txt
root@host1:/# cat /tmp/sample.txt
123

タブ1: ファイル追加

$ pwd
/tmp/test_volume
$ echo 456 > sample2.md
$ cat sample2.md
456

タブ2: コンテナ上でファイルが存在していることを確認

root@host1:/# ls /tmp/
sample.txt  sample2.md
root@host1:/# cat /tmp/sample2.md
456

ホストOSで追加したファイルが、コンテナ上でも確認することができました。

最後に

ホストOSのデータをコンテナに見せるには、下記のような方法もあります。

  • bind mount
  • tmpfs mount

Dockerで、ホストOSからゲストOSへファイルを渡す

2020-12-10

やったこと

Dockerで、ホストOSからゲストOSへファイルを渡します。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d

調査

ホストOS

$ docker ps
CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS                    NAMES
257d4f38cf99        kalilinux/kali-rolling   "/bin/bash"         17 minutes ago      Up 17 minutes                                stoic_archimedes

ホストOS

$ docker cp flag.zip stoic_archimedes:/tmp/flag.zip

ゲストOS (コンテナ)

# ls /tmp/
flag.zip

ファイル転送することができました。

help はこちらになります。

$ docker cp help
"docker cp" requires exactly 2 arguments.
See 'docker cp --help'.

Usage:  docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
	docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

起動中のDockerコンテナに接続する

2020-12-09

やったこと

起動中のDockerコンテナに、別タブから接続します。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d

調査

使うイメージ

$ docker image ls | grep ruby | grep 2.5
ruby                                 2.5                                                                875fc97a76ff        2 weeks ago         843MB

コンテナ起動

タブ1

$ docker container run \
> -d \
> --name abc_container \
> -h host1 \
> -it \
> ruby:2.5 \
> /bin/bash
c5fd47fd970256a98c9fb9ed1c95f68e5129a3571e0a874b04a5ebbcb6d03b04

$ docker container ls -a | grep abc
c5fd47fd9702        ruby:2.5              "/bin/bash"              9 seconds ago       Up 8 seconds                                   abc_container

docker container exec で接続

タブ2

$ docker container exec -it abc_container bash
root@host1:/#

docker container --help より

exec Run a command in a running container

docker container attach で接続

タブ3

$ docker container attach abc_container
root@host1:/#

docker container --help より

attach Attach local standard input, output, and error streams to a running container

おまけ

status が Exitのコンテナを削除する

$ docker container ls -a | grep container | grep ruby
28b447b3bbdc        ruby:2.5              "/bin/bash"              4 minutes ago       Exited (0) About a minute ago                              abc_container
eb715bbaf632        ruby:2.5              "/bin/bash"              10 minutes ago      Exited (130) 10 minutes ago                                tmp01_container
$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
28b447b3bbdc414b288d2766bf87f2f41349d694b817ec6a5f650428b92426ac
eb715bbaf6322a08b6f591090bc9d70498b4832a6b0301a4297bff3425575627

Total reclaimed space: 10B

最後に

docker container execdocker container attach は何が違うのでしょうか。

docker container attach から exit すると別タブも exit されることだけ確認できました。

exec はコマンドを渡せるので、bashで入ったり、zshで入ったり出来るようになるの良いのかもしれませんね。

Dockerコンテナの起動と削除

2020-12-08

やったこと

Dockerコンテナの起動と削除を実行してみます。

確認環境

$ docker --version
Docker version 19.03.13, build 4484c46d9d

調査

使うイメージ

$ docker image ls | grep ruby | grep 2.5
ruby                                 2.5                                                                875fc97a76ff        2 weeks ago         843MB

Dockerコンテナの起動と削除

タブ1

$ docker container run \
> --name tmp01_container \
> -h host1 \
> -it \
> ruby:2.5 \
> /bin/bash

root@host1:/#

docker container run --help より

Usage: docker container run [OPTIONS] IMAGE [COMMAND] [ARG…]

-i, –interactive Keep STDIN open even if not attached -t, –tty Allocate a pseudo-TTY –name string Assign a name to the container -h, –hostname string Container host name

タブ2

$ docker container ls | grep tmp
ed9b4c865708        ruby:2.5              "/bin/bash"              43 seconds ago      Up 41 seconds                                  tmp01_container

タブ1: exitします

root@host1:/# exit
exit

タブ2: コンテナの確認

$ docker container ls -a | grep tmp
ed9b4c865708        ruby:2.5              "/bin/bash"              2 minutes ago       Exited (0) 35 seconds ago                              tmp01_container

タブ2: コンテナの削除

$ docker container rm tmp01_container
tmp01_container

docker container --help より

rm Remove one or more containers

コンテナがなくなっていることが確認できます。

$ docker container ls -a | grep tmp

Dockerコンテナの終了時に即座に削除する

タブ1: コンテナの起動

$ docker container run \
--rm \
--name tmp01_container \
-h host1 \
-it \
ruby:2.5 \
/bin/bash

–rm Automatically remove the container when it exits

タブ2: コンテナが起動していることの確認

$ docker container ls -a | grep tmp
20b0403d390d        ruby:2.5              "/bin/bash"              15 seconds ago      Up 13 seconds                                  tmp01_container

タブ1: exit

root@host1:/# exit
exit

タブ2: コンテナが削除されていることの確認

$ docker container ls -a | grep tmp

最後に

チートシートみたいなものを作成したいですね。

GitHubのユーザー名を変えたら、GitHubと接続する時にパスワードが求められるようになったのでパスワード入力をスキップする

2020-12-06

やったこと

ふとGitHubのユーザー名を変えたくなったので、変更しました。

その時、GitHubからpull、GitHubにpushというGitHubと接続する時にパスワード入力が必要になってしまったので、パスワード入力をスキップさせます。

状況はこんな感じです。

  • GitHubのユーザー名を変えた
  • git の remote urlを git@github.com に設定し直した
  • pull、pullする時にパスワードの入力をスキップさせるようにした

調査

  • ユーザー名を before_user から after_user へ変更
  • 対象のリポジトリは my-repo

git の remote urlを git@github.com に設定し直す

変更前

$ git remote -v
origin	https://github.com/before_user/my-repo.git (fetch)
origin	https://github.com/before_user/my-repo.git (push)

変更後

$ git remote set-url origin git@github.com:after_user/my-repo.git

$ git remote -v
origin	git@github.com:after_user/my-repo.git (fetch)
origin	git@github.com:after_user/my-repo.git (push)

公開鍵をGitHubに登録する

GitHub のここら辺 (2020/12/05時点はここ)

Settings -> SSH and GPG keys の SSH key の方に公開鍵を設定します。

私は鍵ペアをすでに持っていたので、ここは実施しません。

ちなみに鍵の生成はこちらを参考に。

ssh-add に登録する

こちらを参考にします。

最後に

GitHubのユーザー名を変える前、httpsで接続する時パスワード入力を求められないのは何でなのか分かりませんでしたが、これはまたの機会に。