20191012のdockerに関する記事は12件です。

Dockerでよく使うコマンド集

はじめに

この記事はコンテナ勉強用として試したことまとめたものです。
(ほぼ自分が使用するもの...随時追加予定)

Dockerコマンド

  • イメージのダウンロードコマンド
docker image pull [オプション] イメージ名 [:タグ名]
# docker image pull centos:7
7: Pulling from library/centos
8ba884070f61: Pull complete
Digest: sha256:a799dd8a2ded4a83484bbae769d97655392b3f86533ceb7dd96bbac929809f3c
Status: Downloaded newer image for centos:7
docker.io/library/centos:7
#
  • イメージの一覧表示コマンド
docker image ls [オプション] [リポジトリ名]
# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              5a3221f0137b        41 hours ago        126MB
centos              7                   9f38484d220f        5 months ago        202MB
hello-world         latest              fce289e99eb9        7 months ago        1.84kB
#
  • イメージの詳細情報
docker image inspect [イメージ名]
# docker image inspect centos:7
[
    {
        "Id": "sha256:9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1",
        "RepoTags": [
            "centos:7"
        ],
        "RepoDigests": [
            "centos@sha256:a799dd8a2ded4a83484bbae769d97655392b3f86533ceb7dd96bbac929809f3c"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2019-03-14T21:19:53.361167852Z",
        "Container": "958baf5225f586da9c70a21e911a0a875402dd22d83133d78b3b3aa6130e7892",
        "ContainerConfig": {
            "Hostname": "958baf5225f5",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/bin/bash\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:294e8d8145287e70f07328cc09d840fad8980b801223321b983442f097aff0d8",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20190305",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "DockerVersion": "18.06.1-ce",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:294e8d8145287e70f07328cc09d840fad8980b801223321b983442f097aff0d8",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20190305",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 201775492,
        "VirtualSize": 201775492,
        "GraphDriver": {
            "Data": {
                "DeviceId": "10",
                "DeviceName": "docker-253:0-50575843-a8cd5245187bae41a0457a7100bac56e3468e9a74d4eeab24091a5b772a899ae",
                "DeviceSize": "10737418240"
            },
            "Name": "devicemapper"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:d69483a6face4499acb974449d1303591fcbb5cdce5420f36f8a6607bda11854"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]
#
  • Dockerfileからイメージを作成
docker build -t [作成するイメージ名]:[タグ名] [Dockerfileの場所]
# docker build -t test-docker:latest ./
Sending build context to Docker daemon  3.584kB
Step 1/4 : FROM centos:centos7
 ---> 67fa590cfc1c
Step 2/4 : RUN ["yum",  "-y", "install", "httpd"]
 ---> Using cache
 ---> 37f12e15f83e
Step 3/4 : COPY index.html /var/www/html
 ---> Using cache
 ---> fbafd7674218
Step 4/4 : CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
 ---> Using cache
 ---> d59edf5b5938
Successfully built d59edf5b5938
Successfully tagged test-docker:latest
#
  • Dockerコンテナ起動
docker run [オプション] [イメージ名:タグ名] [引数]
# docker run -it test-ubuntu-docker
root@0e0479ff474v:/#
  • イメージの削除
docker rmi [オプション] [イメージID]
# docker rmi -f golang
Untagged: golang:latest
Untagged: golang@sha256:1b1246987ecb4939d9bd20f74eab25e8e2ad819aceea2d6b59869c82f85ef1de
Deleted: sha256:52b59e9ead8e18fafb497532ed44ee8ee4833082b9874abbf0bca61a713a4e01
Deleted: sha256:037466601c73650bce9e801284525d2cb01076d83152e3f52b58a4f1db93cd92
Deleted: sha256:bfe10948239b9bb3c686f973f558bf3b13e5a4e5836a6e2ca10160ce3cec52f0
Deleted: sha256:1daff011bfed534d3a97f224a10f0345bb856f3ee68c885515f0840875ff1502
Deleted: sha256:aeed80cc2bd89729d4743c112894e46bf3e454e23035fca42d8c2317d76e6b59
Deleted: sha256:4d46c2665dc95257b2142eff58b4ca0e01c39238ce5722c573b351a86f6db59d
Deleted: sha256:5bfb8954c951a40ba691ad40d8c6403564ab3ec406bb33693c15a145a4e6cede
Deleted: sha256:78c1b9419976227e05be9d243b7fa583bea44a5258e52018b2af4cdfe23d148d
#
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker 環境構築(php+nginx+mysql+memcached)

ディレクトリ構成

---docker
|--docker-compose.yml
|--docker
|  |--nginx
|  |    |--Dockerfile
|  |    |--nginx.conf
|  |    |--conf.d
|  |         |--default.conf
|  |
|  |--phpfpm
|  |    |--Dockerfile
|  |    |--php.ini
|  |
|  |--mysql
|  |    |--Dockerfile
|  |    |--my.cnf
|  |
|  |--memcached
|       |--Dockerfile
|
|--volumes
   |--db
   |  |--data
   |
   |--logs
   |--nginx
   |--www
      |--html
      |--webcore

docker-compose.ym

FROM php:7.3-fpm-alpine

RUN apk update \
&& apk add \
    autoconf \
    vim \
    git \
    zip \
    gcc \
    g++ \
    make \
    libmemcached-dev \
    zlib-dev \
    freetype-dev \
    libjpeg-turbo-dev \
    libpng-dev \
    libmcrypt-dev \
    postgresql-dev \
&& pecl install memcached \
&& docker-php-ext-install \
    mbstring \
    json \
    exif \
    mysqli \
    pdo_mysql \
    gd \
    pgsql \
    pdo_pgsql \
    hash

nginx

:latestと:alpineの違い
:latest → bash/shが使用可能
:alpine → shのみ使用可能

Dockerfile

FROM nginx:alpine

conf.d/default.conf

mysql

Dockerfile

#イメージ指定
FROM mysql:5.7

my.cnf

[mysql]
default-character-set=utf8mb4

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
explicit_defaults_for_timestamp=1
default-time-zone=Asia/Tokyo
max_allowed_packet=32M
skip-symbolic-links=1

[client]
default-character-set=utf8mb4

phpfpm

Dockerfile

FROM php:7.3-fpm-alpine

RUN apk update \
&& apk add \
    autoconf \
    vim \
    git \
    zip \
    gcc \
    g++ \
    make \
    libmemcached-dev \
    zlib-dev \
    freetype-dev \
    libjpeg-turbo-dev \
    libpng-dev \
    libmcrypt-dev \
    postgresql-dev \
&& pecl install memcached \
&& docker-php-ext-install \
    mbstring \
    json \
    exif \
    mysqli \
    pdo_mysql \
    gd \
    pgsql \
    pdo_pgsql \
    hash

php.ini

[Date]
date.timezone = "Asia/Tokyo"

[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

[extension]
enabled_dl = On

[memcached]
extension=memcached.so

php-fpm.conf

memcached

Dockerfile

FROM memcached:latest
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker 環境構築(php+nginx+mysql)

ディレクトリ構成

---docker
|--docker-compose.yml
|--docker
|  |--nginx
|  |    |--nginx.conf
|  |
|  |--phpfpm
|  |    |--Dockerfile
|  |    |--php.ini
|  |
|  |--mysql
|       |--Dockerfile
|       |--my.cnf
|
|--volumes
   |--db
   |  |--data
   |
   |--logs
   |--nginx
   |--www
      |--html
      |--webcore

mysql

Dockerfile

#イメージ指定
FROM mysql:5.7

my.cnf

[mysql]
default-character-set=utf8mb4

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
explicit_defaults_for_timestamp=1
default-time-zone=Asia/Tokyo
max_allowed_packet=32M
skip-symbolic-links=1

[client]
default-character-set=utf8mb4

phpfpm

nginx

:latestと:alpineの違い
:latest → bash/shが使用可能
:alpine → shのみ使用可能

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker 削除まとめ

コンテナとイメージの削除

それぞれを削除する必要あり
コマンド実行時は前方一致で削除されるため要注意

コンテナ削除

docker rm CONTAINER_ID

コンテナ削除(停止中のみ)

for /f "usebackq" %x in (`docker ps -aq`) do docker rm %x

コンテナ削除(すべて)

for /f "usebackq" %x in (`docker ps -aq`) do docker rm -f %x

イメージ削除

docker rmi IMAGE_ID

イメージ削除(すべて)

for /f %T IN ('docker images --format "{{.ID}}"') DO docker rmi %T
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker コマンドまとめ

バージョン確認

docker version

実行環境確認

docker info

イメージ操作

ダウンロード

オプションは
-a すべてのタグ

docker pull IMAGE_NAME:[TAG_NAME] [OPTION]

一覧表示

docker images []

検索

-stars=%d スターの数

docker search [KEYWORD]

コンテナとイメージの削除

それぞれを削除する必要あり コンテナ→イメージ
コマンド実行時は前方一致で削除されるため要注意

docker system prune
docker container prune
docker image prune
docker volume prune
docker network prune

コンテナ削除

docker rm CONTAINER_ID

コンテナ削除(停止中のみ)

for /f "usebackq" %x in (`docker ps -aq`) do docker rm %x

コンテナ削除(すべて)

for /f "usebackq" %x in (`docker ps -aq`) do docker rm -f %x
docker rm `docker ps -a -q`

イメージ削除

-f 強制オプション

docker rmi IMAGE_ID

イメージ削除(すべて)

for /f %T IN ('docker images --format "{{.ID}}"') DO docker rmi %T

コンテナ生成

起動

-d バックグラウンド
-e 環境変数設定
--env-file 環境変数一括設定

docker run [OPTION] IMAGE_NAME[:TAG_NAME] 
docker run -e ENV=dev IMAGE_NAME
docker run --env-file=ENV_FILE.txt

コンテナ 一覧表示

-a すべて
-f フィルタリング

docker ps [OPTION]
docker ps -a
docker ps -f 'NAME=VAL'

コンテナ ステータス確認

docker status CONTAINER_ID
docker status KEY1[ KEY2 KEY3]

コンテナ詳細確認

docker inspect CONTAINER_ID

コンテナ ビルド

--no-cache

docker build

コンテナ 起動

docker start CONTAINER_ID [OPTION]
docker restart CONTAINER_ID [OPTION]

コンテナ 停止

-t NUM NUM秒後に停止

docker stop CONTAINER_ID [OPTION]

コンテナ ファイルコピー

docker cp CONTAINER_ID:CONTAINER_FROM_PATH COPY_TO_PATH

Dockerfileからイメージ作成

docker build -t NEW_IMAGE_NAME[:TAG_NAME] [OUTPUT_PATH]

コマンド挙動差分

イメージ コンテナ コンテナ起動
build × ×
up
start × ×
run
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GAE(FE)にDocker環境上のRuby on Railsをデプロイする

はじめに: Dockerで開発したら手軽にデプロイまでしたい。

Ruby on Railsの開発で今や主流のDocker環境。
ネット上に環境構築の情報は豊富に転がっているし、local開発は出来たし、Herokuにもデプロイできた。

でもやっぱりHerokuだとイマイチ速度が出ないし、
何よりAWSとかGCP使ってるほうがカッコイイ気がする!(小並感)

圧倒的に情報不足なDockerに乗っけたままAWSやGCPにデプロイをする方法。
今回は既にHerokuで運用中のwebサービスをGAE環境に移し替えたのでその際に行った手順と、躓いた点を書いていこうと思います。

自分自身も右往左往しながら、なんとかデプロイできたー!!動いたー!!
という感じなので、間違っている点や、改善点などが有りましたら是非色々とご教示いただけると助かります。

前提

  • 既にDocker+ docker-composeで環境構築済み、動作確認済みのRuby on Railsアプリケーションがある
  • GCPアカウント及びプロジェクトが作成済
  • Cloud SDKが導入済み

【参考】
Dockerを使ってRuby on Rails環境の構築をしてみる
https://qiita.com/me-654393/items/d11b871ce8d76e153b21

Cloud SDK のインストール
https://cloud.google.com/sdk/downloads?hl=ja

App Engineにアプリを作成する

まず最初に、ターミナルからGAEアプリを作成します。

$ gcloud app create
You are creating an app for project [project-name].
WARNING: Creating an App Engine application for a project is irreversible and the region
cannot be changed. More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.

Please choose the region where you want your App Engine application
located:

 [1] asia-east2    (supports standard and flexible)
 [2] asia-northeast1 (supports standard and flexible)
 [3] asia-northeast2 (supports standard and flexible)
 [4] asia-south1   (supports standard and flexible)
 [5] australia-southeast1 (supports standard and flexible)
 [6] europe-west   (supports standard and flexible)
 [7] europe-west2  (supports standard and flexible)
 [8] europe-west3  (supports standard and flexible)
 [9] europe-west6  (supports standard and flexible)
 [10] northamerica-northeast1 (supports standard and flexible)
 [11] southamerica-east1 (supports standard and flexible)
 [12] us-central    (supports standard and flexible)
 [13] us-east1      (supports standard and flexible)
 [14] us-east4      (supports standard and flexible)
 [15] us-west2      (supports standard and flexible)
 [16] cancel
Please enter your numeric choice:  2

Creating App Engine application in project [project-name] and region [asia-northeast1]....done.
Success! The app is now created. Please use `gcloud app deploy` to deploy your first app.

asia-northeast1が東京リージョンですので、選択します。
※[project-name]となっている部分は各々作成したGCPプロジェクト名が入ります。

app.yamlを作成する

続いて、Dockerfileと同階層にapp.yamlを作成します。
app.yamlの説明に関してはここでは省略します。
【参考】https://cloud.google.com/appengine/docs/standard/go/config/appref?hl=ja

app.yaml
entrypoint: bundle exec rackup --port $PORT
env: flex
runtime: custom

env_variables:
  SECRET_KEY_BASE: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX(各々のsecret key baseを入れる)

SECRET_KEY_BASEの取得方法は、
コンソール上で、

$ docker-compose exec web bundle exec rails secret

表示される文字列をコピペすればOKです。

Railsサーバの起動ポートを8080に合わせる

GAEでは、8080番に対してアクセスするので、3000番などに設定している方は8080番に変更しましょう。

Dockerfile(例)
FROM ruby:2.6.3

RUN apt-get update -qq && \
  apt-get install -y build-essential \
  libpq-dev \
  nodejs

RUN mkdir /app_name
ENV APP_ROOT /app_name
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install
ADD . $APP_ROOT

# 8080番でポートを起動する
CMD /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 8080 -b '0.0.0.0'"

docker-compose.yml(例)
version: "3"
services:
  web:
    environment:
      TZ: Asia/Tokyo
    build: .
    volumes:
      - .:/app
    ports:
      - 8080:8080
    tty: true
    stdin_open: true

volumes:
  db-volume:

基本的な準備はここまで。

いざデプロイ!

さて、待ちに待ったデプロイ。この瞬間が一番ドキドキします。
ターミナルを開いて、

$ gcloud app deploy

descriptor:      [/project-name/app.yaml]
source:          [/projects/project-name]
target project:  [project-name]
target service:  [default]
target version:  [20190000t123456]
target url:      [https://project-name.appspot.com]
Do you want to continue (Y/n)?  Y(←上記の内容で問題なければ、Yを入力します。)

ビルドが始まり、しばらく待ち、

Updating service [default] (this may take several minutes)...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://project-name.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse

と、表示されれば成功。

$ gcloud app browse

で確認しましょう。

トラブルシューティング

「Switch to inspect mode.」と怒られる件について

Updating service [default] (this may take several minutes)...failed.
ERROR: (gcloud.app.deploy) Error Response: [9]
Application startup error:
Switch to inspect mode.

色々ググったけど今ひとつ情報源に当たれずにめちゃくちゃ困ってた。
8080番でRailsが起動しておらず、GAEがアクセスできていないってことだと思う。

原因はdocker-compose側でサーバーを起動していたこと。

docker-compose.yml(例)
version: "3"
services:
  web:
    build: .

    # ここがアウト
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 8080 -b '0.0.0.0'"

    volumes:
      - .:/app_name
    ports:
      - "8080:8080"
    links:
      - db

これだとこのエラーが出るみたい。
原因はいまいちよくわかっていないが、もしかしたらdocker-compose読んでいないのかも?

8080番ポートの下りで記載したDockerfileのように、

Dockerfile
CMD /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 8080 -b '0.0.0.0'"

で、8080を開いてあげるのがいいのかも。

【参考】
A weekend, a Rails app, a Kubernetes and an Azure.
https://medium.com/@michiels/a-weekend-a-rails-app-a-kubernetes-and-an-azure-d330b003d7c2

最後に:Herokuの方がわかりやすいけど、やっぱりGAE早い

今回は実行速度が気になったので、HerokuからGAEに乗り換えることを決意したわけですが、
予想通りGAEの方が速度が出ました。

左: Heroku
右: GAE
sp-heroku.jpg sp-gae.jpg

特にRailsの中身をいじること無く、20程度速度が速度が上昇しました。
改善案の部分でサーバー応答時間の短縮(TTFB)が表示されなくなったのがでかい気がします。

おまけ:宣伝

今回HerokuからGAEに移行したのはスポチューバーTVという、野球の技術指導メディアです。
スポーツ教育×Techの、主に野球の分野を伸ばしていけたらなと思っているので、興味のある方は是非御覧ください。
https://spotuber-tv.com/

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerやECR, ECS, Fargateなど、コンテナ周りのAWS知識を効率的にキャッチアップしたい人のために

概要

私自身がコンテナや、コンテナ関連のAWSサービスについてはほぼ分からない状態だったのですが、そこからできる限り効率的に知識をキャッチアップしたくて学習したときの道のりです。

同じように困っていらっしゃる方のお役に立てばと思い、記事にしてみました。この道のりの通りに進んでいただければ、時間を無駄にすることなく、多少なりともスムーズに知識をキャッチアップできると思います。

主要な概念や全体像を理解するまでの道のり

いきなり詳細に踏み込んでも、つまりいきなりFargateなどのAWSサービスを使っても、すぐに迷子になることは目に見えていましたので、まずは全体感や重要な概念、用語を理解しようと思いました。

そこで色々と調べていると、次の記事を見つけました。ものすごく分かりやすかったです。

これを読んでよく分かったのは、以下の点です。

  • レジストリとは、Docker Hubのようなもので、Dockerイメージを管理するところ。AWSだとECRがこれにあたる。
  • それとは別次元で、以下がある。
    • コントロールプレーン
      • コンテナ数の管理など、コンテナの管理をするもの。データプレーンを起動する役割したりする。ECSがこれにあたる。
    • データプレーン
      • 実際にコンテナが動く場所で、EC2やFargateがこれにあたる。

ただ、上記の記事を読んでも、ECSのクラスター、サービス、タスク、コンテナの概念はよく分かりませんでした。うーむ、難しい・・。

また、それらとデータプレーン(EC2, Fargate)との違いについても、ほぼ理解できませんでした。

こういったトピックについては、以下の記事がとても分かりやすいです。

DockerコンテナをFargateで動かすことの素晴らしさ

こうやって調査をしていきますと、Fargateというサービスの何が素晴らしいのか、という点が見えてきました。

DockerコンテナをFargateで動かすということは

  • PaaS(Elastic Beanstalkなど)よりも自由度が高くなり
  • IaaS(EC2など)よりも生産性が高くなる(DockerのインストールやOSセキュリティパッチの適用などから解放される)

ということです。一言でいうと「良い塩梅でめっちゃいい」ということですね。

EC2(つまりIaaS)でコンテナを動かすことはできます。しかし、それにはEC2インスタンスを構築し、Dockerという基盤をインストールする必要があります。そしてOSセキュリティパッチなどの面倒を見続けなければなりません。それは、ものすごく大変なことです。

そのあたりの大変さをAWSが引き受けてくれる、というのがFargateの素晴らしいところです。私たちは、Dockerイメージさえつくれば良いのです。

こういった点から、色々な制約はもちろんあるものの、マネージドの恩恵を最大限に受けるようにした方が得策だと感じてきました。

Dockerfileとdocker-composeの関係

Dockerについてまだ慣れていない私は、この二つの関係がよく分からず混乱していました。

この点については、以下の記事で分かりやすく解説されています。

実際に動かしてみるまでの道のり

主要な概念や全体像を理解できましたので、今度は実際にECR, ECS, Fargateを使って、Dockerイメージを動かしてみることにしました。

私の場合、自作したアプリを動かしてみたかった関係で、Spring Bootが動くコンテナをつくってみようと思いました。

その際、以下の記事を参考にさせていただきました。

こちらの記事を参考に、以下のDockerfileを、Mavenプロジェクト直下に作成しました。

Dockerfile
FROM openjdk:8-jdk-alpine

COPY target/my-app-0.0.1-SNAPSHOT.jar my-app.jar

ENTRYPOINT ["java","-jar","/my-app.jar"]

そして、Dockerイメージをつくります。

docker build ./ -t my-app

tオプションは作成したイメージにどんな名前をつけるか、を指定するものです。

ところが、このイメージの名前というものが意外に分かりづらいのです。ここに指定したものは、何を意味するのか、何に影響してくるのかが、分かりません。

tオプションについては、以下の公式リファレンスで解説されています。

しかし、これらを読んでもイマイチよく分かりません。他の記事を調べても「なるほど!そういうことか!」という思いに至ることができませんでした。

公式リファレンスや先人の解説記事の内容をつなぎ合わせると、イメージ名は以下のものだと分かってきました。

「イメージ名」とは?

イメージ名というのは、全世界のなかでイメージを一意に特定するためのIDみたいなものです。
では、どうやって一意に特定するのかというと

  • どのレジストリで管理されているか?
    • レジストリ、というのはDockerHubのようにDockerのイメージを管理するところです。
    • 平たく言うと、DockerHubなのか?ECRなのか?全く別のホストなのか?、ということです。
    • ですから、ここにはホスト名やIPアドレス、およびポート名が記載されることになります。
  • そのレジストリの中の、なんというリポジトリなのか?
    • リポジトリというのは、レジストリの中にあるもので、Githubのリポジトリのようなものです。
    • DockerHubではユーザー名によって名前空間が区切られていますから、ここが[ユーザー名]/[リポジトリ名]という構造になります。一方、そのようにユーザー名で区切られていない場合は、シンプルに[リポジトリ名](スラッシュで区切られない)という感じです。
  • そのリポジトリの中の、どのタグか。
    • これもGithubのタグと同じようなものです。1.0とかバージョン番号にするのが典型ですね。
    • docker build -tのtオプションでタグ名を省略すると、latestがデフォルトで付きます。

イメージ名は以上の3要素から構成され、具体的には以下の構造です。

レジストリ名(多くの場合ホスト名) / リポジトリ名(DockerHubの場合は、「ユーザー名/リポジトリ名」) : タグ名

では、先ほどように

docker build ./ -t my-app

と指定した場合はどうなるのでしょうか?

ホスト名が省略されていますので、公式リファレンスの

ホストの指定が無ければ、デフォルトで Docker の公開レジストリのある registry-1.docker.io を使います。

の記述に基づいて、registry-1.docker.ioであると見なされます(つまりDockerHubだと見なされます)。

タグ名が省略されていますので、latestがデフォルトで指定されます。

つまり、以下で指定したのと同じ意味になる、ということだと私は解釈しています。

registry-1.docker.io/my-app:latest

作成したDockerイメージを、ECRに登録します

ローカルPCで先ほどつくったDockerイメージを、ECRに登録していきます。

この手順については公式ガイドで解説されています。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html#use-ecr

以下、この公式ガイドの手順どおりに実行したことについて、解説してきます。

ECRでは、レジストリはユーザー単位に作成されます。ここはDockerHubとは異なりますね。DockerHubは全体で一つのレジストリで、その中の名前空間をユーザー名で分割してる感じです。

ですので、どのレジストリにアクセスするかは、aws cliでログインしているユーザに紐づくレジストリとなります。このため、コマンドにはレジストリを指定する内容が出てきません。

まずは、レジストリという自分専用の部屋に、今回のDockerイメージを格納するための空間(リポジトリ)を作成します。

aws ecr create-repository --repository-name my-app --region ap-northeast-1

すると、以下の結果がかえってきます。

{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:{アカウントID}:repository/my-app",
        "registryId": "{アカウントID}",
        "repositoryName": "my-app",
        "repositoryUri": "{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/my-app",
        "createdAt": 1570824304.0
    }
}

次に、リポジトリーに登録したDockerイメージに、ECR用のイメージ名(tag)をつけます。

docker tag my-app {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/my-app

ここでついに、イメージ名にホスト名を明示的に追加したわけです。

  • {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.comというECR上の私専用の部屋(レジストリにある、
  • my-appというリポジトリに配置するイメージだよ

ということを、イメージ名が表しています。なお、タグについては省略しましたので、自動的に「latest」が付与されます。

次に、レジストリ(ECR)にログインする必要があるのですが、「ログインするためのコマンド」を取得するためのコマンドを叩かねばなりません。

aws ecr get-login --no-include-email --region ap-northeast-1

すると、以下のコマンドを実行するよう、指示されます。

docker login -u AWS -p {ものすごく長い文字列。12 時間有効な認証トークン、つまりパスワード。} https://{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com

このコマンドを実行してECRにログインします。

そして、さきほどつけたタグ名を指定して、ECRにイメージを登録します。

docker push {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/my-app
The push refers to repository [{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/my-app]
ffb5690b4e55: Preparing 
ceaf9e1ebef5: Preparing 
9b9b7f3d56a0: Preparing 
f1b5933fe4b5: Preparing 
no basic auth credentials

このようにno basic auth credentialsが出てしまった場合は、以下を参考に対応しましょう。
https://qiita.com/NaokiIshimura/items/1886dbd04631c3f7d0e1

うまくいくと・・・

The push refers to repository [{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/my-app]
ffb5690b4e55: Pushed 
ceaf9e1ebef5: Pushed 
9b9b7f3d56a0: Pushed 
f1b5933fe4b5: Pushed 
latest: digest: sha256:{ハッシュ値}
size: 1160

のようになります。

管理コンソールから見ると・・・

スクリーンショット 2019-10-12 5.30.51.png
スクリーンショット 2019-10-12 5.31.03.png

しっかり登録されています!よかった!

ECRに登録したDockerイメージを、ECSを使ってFargateの上で動かします。

次は、このECRに登録したdockerイメージを、Fargateの上で動かしてみましょう。Fargateで動くDockerコンテナの管理は、ECSで行います。

この手順については、公式ガイドで解説されています。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS_GetStarted_Fargate.html

ガイドに記載のとおり、以下ウィザードを使ってECSおよびFargateをセットアップできます。
https://console.aws.amazon.com/ecs/home#/firstRun

私が分かりづらかった点を、以下に記載します。

ポートマッピング

ポートマッピングをSpring Boot(のtomcat)が待ち受けているポート番号に指定します。たとえば、Tomcatが5000番ポートをリッスンする設定にしているならば、5000を指定する必要があります。Fargateをつかう場合、前面で待ち受けるポートと、コンテナ側のポート番号は同じじゃないとダメみたいです。それはもはや「マッピング」ではないと思いますが・・。

セキュリティグループのインバウンドルール

ポートマッピングでFargateが待ち受けるポート番号を、Tomcatが待ち受けるポート番号と同じにしないといけないので、そのポート番号でFargateへ流入してくるトラフィックを許可しないといけません。

Fargateから他のAWSサービスを呼び出す場合は、権限設定が必要

権限がない状態でAWSサービスを呼び出すと、エラーが起こります。今回のアプリの場合、Fargateで動くSpring Bootアプリから、DynamoDBを呼び出していました。

ECSの管理コンソールからログが見れるのですが、そこでログを見て見ると・・・

Caused by: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), SystemPropertiesCredentialsProvider: Unable to load AWS credentials from Java system properties (aws.accessKeyId and aws.secretKey), com.amazonaws.auth.profile.ProfileCredentialsProvider@46393853: profile file cannot be null, com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@53f52e4e: Unable to load credentials from service endpoint]

というエラーが出ていました。

↓整形すると・・・

Caused by: com.amazonaws.SdkClientException: 
Unable to load AWS credentials from any provider in the chain: 

[
EnvironmentVariableCredentialsProvider: 
 Unable to load AWS credentials from environment variables
 (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and
  AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), 

SystemPropertiesCredentialsProvider: 
 Unable to load AWS credentials from Java system properties
 (aws.accessKeyId and aws.secretKey),

com.amazonaws.auth.profile.ProfileCredentialsProvider@46393853:
 profile file cannot be null, 

com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@53f52e4e: 
 Unable to load credentials from service endpoint
]

これを素直に読めば「どこかにcredentialを置け」、と指示されていることになります。

しかし、その前にそもそも、EC2やFargateからAWSのAPIを呼び出すときは、どのユーザーのAWS_ACCESS_KEY_IDとAWS_SECRET_KEYを指定すべきなのでしょうか?

普通に考えたら、サーバーや設定画面に、アクセスキーやシークレットキーを配置するなど、セキュリティ的に考えられませんから、実行しているFargate, EC2のロールに権限をつけることで対象のサービスを呼び出したいところです。

先ほどのエラーも、タスクを実行するロールに、対象のAWSサービス(今回はDynamoDB)にアクセスする権限が付与されていないため、しょうがなくどこかにアクセスキーなどを探しにいったところ、見つからなかった、という顛末でしょう。

ということで、そもそもタスクを実行するロールに適切な権限さえついていれば、問題がないということです。

これを実現するには、ECSのタスク定義でタスクロールを適切に設定すれば良いです。

スクリーンショット 2019-10-12 9.52.08.png

私の場合は、この「タスクロール」に何のロールも設定されていませんでした。ecsTaskExecutionRoleはデフォルトで用意されているもののようで、ひとまずこのロールを設定します。

あとは、対象のAWSサービスを呼び出す権限を、このロールに付与すればOKです。

ecsTaskExecutionRoleのリンクから、ロールの設定画面に飛べます。

スクリーンショット 2019-10-12 9.54.18.png

私の場合は、Fargateで動かすコンテナからDynamoDBを使いたいので、ここにAmazonDynamoDBFullAccessを付与してみました。(権限が強すぎるとは思いますが・・)

すると、先ほどのエラーも出ず、通常どおりに動作しました!

終わりに

以上、私のキャッチアップの道のりをご紹介しました。

aws cliの導入手順などは端折ってしまいましたが、誰かのお役に立てたらと思います。
ご覧いただき、ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

IntelliJ + Docker + Pythonの環境構築

はじめに

Macbookを買い換えたのでPythonの開発環境を作り直すことになるのですが、ローカルに直接Pythonをインストールすると、ついうっかりglobalにパッケージをインストールしてしまったり、venvを使っていても環境を作り直したいときに一手間が面倒だったり、ということが嫌だったのでDockerを使って構築することにしました。

IntelliJにPluginインストール

IntelliJにDocker Pluginが入っていない場合は Preferences > Pluginsからインストールします。

image.png

Pythonプロジェクトの作成

次にIntelliJを立ち上げてPythonプロジェクトを作成します。
Dockerの必要なイメージはこの後作るので、ここではとりあえず適当なProject SDKを選んでおきます。(ここではPython2.7(venv)になっています)
それ以外はデフォルトのままで良くて、プロジェクトを作成します。

image.png

IntelliJ上でDockerfileを作成してイメージをビルドする

今回はPythonQiitaというプロジェクト名にしました。最初にPython環境をDockerイメージにしておく必要があるので、プロジェクトフォルダの直下にDockerfileを作成します。(場所はどこでも良い)

image.png

Dockerfileにはベースとなるイメージファイル、初期設定コマンドなどを書いておきます。
今回はpython:3イメージを使います。パッケージにpandas numpyを入れておきます。

image.png

作成したDockerfileを右クリックして、メニューからCreate Dockerfileを選択します。

image.png

Configurationウィンドウが表示されるのでImage tagを入力します。このタグ名は後で使います。ここではpython_qiitaとしました。
Run built imageのチェックは外しておきます。これをオンにしておくと、イメージをビルドした後、コンテナとして起動してくれます。Container nameを入力すると、そのコンテナ名で起動するようになっています。

image.png

下記のimage.pngから作成したDockerfile設定を起動すればイメージがビルドされます。Deploy Logに'python_qiita Dockerfile: Dockerfile' has been deployed successfully.と出て完了したことが分かります。

image.png

イメージが作成されるとServicesビューにイメージ名が表示され、ビルドが成功したことが分かります。

image.png

ビルドしたイメージをProject SDKとして設定する

Dockerイメージがビルドできると、プロジェクトで利用するSDKとして利用できるようになります。コンテナはSDKにはならないので注意が必要です。

FIle > Project Structureを開き、Project項目にあるNewボタンを押し、ポップアップにあるPython SDKを選択します。
image.png

Python Interpreterを選択するウィンドウが表示されるので、左メニューにあるDockerを選びます。すると、Image nameに先ほどビルドしたDockerイメージのタグ名が選択できるようになっていることを確認してOKボタンを押します。

image.png

Project StructureのSDKs項目にRemote Python 3.7.4 Docker...が表示されており、packagesにDockerfileに書いたパッケージがインストールされていることが分かります。venvなどの環境では、ここでパッケージの追加・削除ができますが、DockerイメージのPythonだと追加・削除はできません。パッケージの構成が変わるたびにイメージをビルドしなおす必要があります。

image.png

Pythonの実行とデバッグ

ここまでくれば後は通常通りPythonファイルを作成して実行するだけですが、、、
設定を完了した直後だと、IntelliJがPythonの構成を適切に読み込めていないらしく、一度プロジェクトを閉じて開きなおす必要があります。さらに、画面下に下記のような更新中のインジケータが完了するまで待たないといけません。ここだけが難点です。仕組みはわかりませんが、改善されることに期待したいですね。

image.png

ここまで出来ればPythonのコード補完や実行、デバッグがIntelliJ上でできるようになっています。下記はpandasをインポートして実行した状態。
image.png

不便なこと

環境はDockerで構築できるのでポータブルになるし、気軽に作り直せることは実行環境面で非常に便利に感じます。一方で、いくつか不便に思うことがあるので書いておきます。

Dockerイメージをビルドしなおすと構成読み込みに時間がかかる

上述のSDKを設定した直後と同様に、イメージをビルドし直してPythonパッケージの構成を変えたとしても、すぐに反映されません。プロジェクトを再起動するなどして、IntelliJが再認識するのを待つ必要があります(数分)。
構成見直しが不要になってくると気になりませんが、プロジェクトの初期フェーズでは煩わしいです。

matplotlibなどのshow()的なことができない

当たり前ですが、Docker上で実行するのでshow()のようなウィンドウを立ち上げることができません。諦めてファイルに保存して確認するしかないです。

まとめ

紹介したような不便なところもありますが、環境も汚れないしポータブルであることは便利だと感じています。今までだと、パッケージの再構築が面倒だったり、requirements.txtのようなものに書きださなければならなかった環境が、Dockerfileにまとまるし、必要ならイメージをレポジトリで保存しておく事もできるのは良い感じだなと。
venvとどちらが楽か、と聞かれるとvenvだと思いますが、新しい環境で色々とやってみる方が今の自分の好みに合っているので、暫くはDockerで進めてみようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker環境でAtCoder〜Ruby編

AtCoderのRuby環境って特殊だよね?

AtCoderのRubyのバージョンは2.3.3です。ちょっと古いですね。AtCoderの時だけrbenvを使って2.3.3に戻してもいいですけど、Dockerを使ってもいいなぁとぼんやり思っているここの私!
というわけで、DockerでRubyのAtCoder環境を整えてみました。

Dockerfileを書いてみた

Dockerfile
FROM ruby:2.3.3
ENV LANG="C.UTF-8"

ENV USER yourname
ENV HOME /home/${USER}

RUN useradd -m ${USER}
RUN gpasswd -a ${USER} sudo
RUN echo "${USER}:password" | chpasswd

RUN gem install at_coder_friends

USER ${USER}
WORKDIR ${HOME}

CMD ["/bin/bash"]

途中でインストールしているgemの at_coder_friends というのは、 AtCoderツールを自作した話@nejiko96 さんが作ってくださったAtCoderのテストツールです。テストだけではなく、回答のスケルトンも作ってくれたり、このツールから回答フォームにsubmitできたりとものすごく便利です。現在はRubyとC++に対応している模様です。
Usageなどが書かれたGitHubのリポジトリはこちら> AtCoderFriends

で、ビルドして実行してAtCoderを楽しみましょう!

docker build --tag at-coder .
docker run --rm -it -v path/to/atcoder_problems:/home/yourname at-coder

参考URL

https://qiita.com/Riliumph/items/3b09e0804d7a04dff85b
https://qiita.com/nejiko96/items/0cd23ac2c033864ef341

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dnmonsterで生成した画像データをiterm2上で表示してみる

dnmonsterとは

githubの初期アイコンなどのランダムな画像はindenticonと呼ばれるみたい。
dnmonsterはindenticonを生成して返却してくれるNode.jsで作られたwebサーバ。
amouat/dnmonster: Dockerised Node server for KevinGuadin's monsterids
モンスターがかわいい。

実行環境

  • macOS Mojave
  • iterm2
  • docker

試してみる

$ docker run -d -p 8000:8080 amouat/dnmonster
$ curl http::/localhost:8000/monster/sk8metal
�PNG

bKGD�������oIDAT8�c`C�\����*��Ĩe"d1bD�
�lb耑�!��X�b�2�a���D{�[葁.��P
                             g���^�zb�
                                       řa��E
.��t!�+a��Q@]��R�\]��IEND�B`�%

PNGの画像データとして返ってきた。

imgcatを用意する

iterm2で画像を表示するためにimgcatを用意する。

$ cd /usr/local/bin;wget "https://www.iterm2.com/utilities/imgcat";sudo chmod +x imgcat

dnmonsterから返却された画像データを表示してみる

imgcatを利用してdnmonsterから返却された画像データをiterm2上で表示してみる。

$ curl http:/localhost:8000/monster/sk8metal | imgcat

スクリーンショット 2019-10-12 14.40.15.png

別のリクエストに変えると画像データも変わる。
スクリーンショット 2019-10-12 14.43.49.png

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【図解付き】Docker Data Volumeのバックアップ・リストア方法

バックアップ方法

$ docker run --rm --volumes-from [データボリュームのマウント先コンテナ名] -v `pwd`:/backup busybox tar cvf /backup/backup.tar [データボリュームのマウント先ディレクトリ]

もしくは

$ docker run --rm -v [データボリューム名]:[データボリュームのマウント先ディレクトリ] -v `pwd`:/backup busybox tar cvf /backup/backup.tar [データボリュームのマウント先ディレクトリ]

具体例

MySQLのデータベース情報が保存されているデータボリュームをバックアップしたい場合は以下のようになります。
データボリュームがマウントされているDBコンテナをwp_db_conとします。

$ docker run --rm --volumes-from wp_db_con -v `pwd`:/backup busybox tar cvf /backup/backup.tar /var/lib/mysql

図で表現すると以下のようになります。

volume-backup-from-con-880-1.png

もしくは以下のようになります。
データボリューム名をmy_wordpress_mysql_dataとします。

$ docker run --rm -v my_wordpress_mysql_data:/var/lib/mysql -v `pwd`:/backup busybox tar cvf /backup/backup.tar /var/lib/mysql

図で表現すると以下のようになります。

volume-backup-from-volume-880-1.png

リストア方法

$ docker run --rm --volumes-from [データボリュームのマウント先コンテナ名] -v `pwd`:/backup busybox tar xvf /backup/backup.tar

もしくは

$ docker run --rm -v [データボリューム名]:[データボリュームのマウント先ディレクトリ] -v `pwd`:/backup busybox tar xvf /backup/backup.tar

具体例

MySQLのデータベース情報が保存されているデータボリュームをリストアしたい場合は以下のようになります。

$ docker run --rm --volumes-from wp_db_con -v `pwd`:/backup busybox tar xvf /backup/backup.tar

もしくは以下のようになります。

$ docker run --rm -v my_wordpress_mysql_data:/var/lib/mysql -v `pwd`:/backup busybox tar xvf /backup/backup.tar

さいごに

データボリュームのバックアップ・リストア方法の詳細については【Docker】具体例で理解するデータボリュームのバックアップ・リストア方法でも紹介していますのでもし興味のある方はご覧になっていただければと思います。

ツイッター(@nishina555)やってます。フォローしてもらえるとうれしいです!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker上で自前OpenSSH(sshd)をビルドして動そうとしてコケた話

何がしたかったか?

  • 研究関連でOpenSSH(のsshd)を自前でビルドして色々試したい事がある
  • Mac上でうまくビルドできないし,どこでもビルドできるようにDockerで動かしたい
    • つまりDocker上でビルド,サービス化,接続テストができるように
    • MacのVSCodeで編集,即座にDocker上でビルド,すぐ接続テスト.したい.
  • DockerといえばAlpine Linux!!

環境とか

  • Docker Engine: 19.03.2
  • Docker Compose: 1.24.1

  • ディレクトリ構造

tree.txt
.
├── docker-compose.yml
├── src
│   └── OpenSSHのソースコード
└── vm
    ├── Dockerfile
    └── login.sh

最初に試したこと

1. 以下のdocker-composeとDockerfileを書いてみた.

docker-compose.yml
version: '3'
services:
  sshd-build: 
    build: ./vm # vm/Dockerfileがあるのでそいつをビルド
    image: sshd-build:latest
    container_name: sshd-container
    restart: always
    volumes:
      - ./:/root/openssh-portable # ローカルで開発してDockerでビルド,検証したいので共有
    tty: true # 立てたコンテナの中で動きたいときに書くやつ
Dockerfile
FROM alpine as sshd-linux

WORKDIR /root # rootとして動くのでここを作っとく

RUN apk update && \ # ビルドに必要なパッケージの追加
    apk add --no-cache openrc openssh \ # この2つはAlpineのデーモン登録のため必要
    gcc g++ make openssl-dev zlib-dev bash # これらはビルドのため

ENTRYPOINT ["/bin/bash"]

2. コンテナへのログイン

login.sh
#!/bin/bash
docker exec -it sshd-container /bin/bash

3. ビルドとインストール

# cd openssh-portable/src
# ./configure && make && make install

問題とその解決

1. インストール後, デーモン起動を試みるも...

tty
# rc-service sshd start
/lib/rc/sh/openrc-run.sh: line 100: can't create /sys/fs/cgroup/blkio/tasks: Read-only file system
/lib/rc/sh/openrc-run.sh: line 100: can't create /sys/fs/cgroup/cpu/tasks: Read-
... 同様の表示
 * You are attempting to run an openrc service on a
 * system which openrc did not boot.
 * You may be inside a chroot or you may have used
 * another initialization system to boot this system.
 * In this situation, you will get unpredictable results!
 * If you really want to do this, issue the following command:
 * touch /run/openrc/softlevel
 * ERROR: sshd failed to start

起動できていない...ここは海外ニキを参考にして修正をした.海外ニキ,全体的にエスパーで解決しに来るのでつよい.
今回環境の場合はdocker-composeを使っているのでそこに追加.

2. その後も追加でエラー...

  • 後半のエラーコード(You are attempting...)は消えず.

エラーコードに従ってtouch /run/openrc/softlevelを叩いたら通った.

結論

docker-compose.yml
version: '3'
services:
  sshd-build: 
    build: ./vm
    image: sshd-build:latest
    container_name: sshd-container
    restart: always
    volumes:
      - ./:/root/openssh-portable
      - /sys/fs/cgroup
    tty: true
Dockerfile
FROM alpine as sshd-linux

WORKDIR /root

RUN apk update && \
    apk add --no-cache openssh openrc gcc g++ make openssl-dev zlib-dev bash

ENTRYPOINT ["/bin/bash"]

コンテナ起動後

# cd openssh-portable/src
# ./configure && make && make install
# touch /run/openrc/softlevel
# rc-service sshd start
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519 
 * Starting sshd ... [ok]
# rc-status
Runlevel: sysinit
Dynamic Runlevel: hotplugged
Dynamic Runlevel: needed/wanted
Dynamic Runlevel: manual
 sshd 

あとはソースコード書き換えて, make && make install && rc-service sshd restartを繰り返す.

ちなみに

イメージサイズは197MBであった.もう少し小さくしたいな...
その話はまた今度.

あとビルドが遅い.数秒で終わってほしい(願望)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む