20200817のdockerに関する記事は15件です。

Docker for Windows で webpack dev server のオートリロード(ファイル監視)が動作しない場合の解決策

結論

うまく動かなかったら watchOptions.poll を試してね、とのこと。

If watching does not work for you, try out this option. Watching does not work with NFS and machines in VirtualBox.

webpack 公式ドキュメント より。

設定例

http://localhost:8080 で動作する最小限の記述になります。

本件以外では webpack.config.jshostdocker-compose.ymlworking_dirports あたりがハマりポイントになるかと思います。

webpack.config.js
const path = require('path');

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, 'src', 'index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js',
    },
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        host: '0.0.0.0',
        port: 8080, // default
    },
    watchOptions: {
        poll: 1000
    }
};
docker-compose.yml
version: '3'
services:
  app:
    image: node:12
    working_dir: /app
    volumes:
      - .:/app
    ports:
      - 8080:8080 # port は devServer と揃える必要がある
    command: npm start
package.json
{
  "name": "app",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server"
  },
  "devDependencies": {
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  }
}

以上です。

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

Dockerの主なコマンド一覧

Dockerの主なコマンド、オプション。
詳細は公式ドキュメント

Container

docker container ls [オプション]

稼働中のコンテナ一覧を表示する。

  • -a ― 停止中のコンテナも表示する。
  • -s ― ファイルサイズを表示する。

docker container [オプション] inspect コンテナ

コンテナの詳細情報を表示する。コンテナは複数指定可能(スペース区切り)。

docker container run [オプション] イメージ [コマンド]

イメージからコンテナを作成し、稼働させる(docker image pulldocker container createdocker container startを一度に実行する)。
コマンドの終了と同時に、コンテナも停止する。終了と同時に破棄したい場合は--rmをつける。

  • --name コンテナ名 ― コンテナ名を指定する。
  • -p ホストのポート番号:コンテナのポート番号 ― コンテナのポートをホストに公開する。コンテナ間の通信では不要。
  • --mount type=bind,src=ホストのディレクトリ,dst=コンテナのディレクトリ ― バインドマウント。ホストのディレクトリをコンテナにマウントする。複数指定可能。
  • --mount type=volume,src=ボリューム,dst=コンテナのディレクトリ ― ボリュームマウント。ボリュームをコンテナにマウントする。複数指定可能。
  • --volumes-from コンテナ ― 指定したコンテナと同じボリュームにマウントする
  • -e 環境変数名=値 ― 環境変数の設定
  • -dit ― コンテナをバックグラウンドで実行させる(デタッチモード)。デタッチ中のログはdocker container logsで確認できる。
  • -it ― 標準入出力をコンテナに結びつける(キー入力する場合)。
  • -i ― 標準入出力をコンテナに結びつける(キー入力しない場合)。
  • --rm ― コマンドの実行が完了したとき、コンテナを破棄する。
  • -w ― コンテナ内の作業ディレクトリを指定する。
  • --net ― 接続するDockerネットワークを指定する。
コマンド例
# apacheをバックグラウンドで実行する
$ docker container run -dit --name my-container -p 8080:80 --mount type=bind,src="$PWD",dir=/usr/local/apache2/htdocs/ httpd:latest

docker container create [オプション] イメージ [コマンド]

イメージからコンテナを作成する。作成時に実行したいコマンドを指定する。コマンドを省略すると、イメージ製作者が設定した規定のコマンドが実行される。

  • --name コンテナ名 ― コンテナ名を指定する。
  • -p ホストのポート番号:コンテナのポート番号 ― コンテナのポートをホストに公開する。コンテナ間の通信では不要。
  • --mount type=bind,src=ホストのディレクトリ,dst=コンテナのディレクトリ ― バインドマウント。ホストのディレクトリをコンテナにマウントする。複数指定可能。
  • --mount type=valume,src=ボリューム,dst=コンテナのディレクトリ ― ボリュームマウント。ボリュームをコンテナにマウントする。複数指定可能。
  • -e 環境変数名=値 ― 環境変数の設定

docker container start [オプション] コンテナ

停止中のコンテナを稼働させる。コンテナは複数指定可能(スペース区切り)。

docker container stop [オプション] コンテナ

コンテナを停止する。コンテナは複数指定可能(スペース区切り)。

docker container rm [オプション] コンテナ

コンテナを完全削除する。復活はできない。コンテナは複数指定可能(スペース区切り)。

docker container prune [オプション]

停止中のコンテナをすべて削除する。

docker container logs [オプション] コンテナ

コンテナのログを表示する。

docker container attach [オプション] コンテナ

Dockerホストのの標準入力、出力、およびエラーストリームを実行中のコンテナーにアタッチする。
デタッチする場合は「control + p, control + q」。

docker container exec [オプション] コンテナ コマンド

実行中のコンテナでコマンドを実行する。docker container runと異なり、コマンドの終了後もコンテナは稼働し続ける。

  • -it ― 標準入出力をコンテナに結びつける(キー入力する場合)。
  • -i ― 標準入出力をコンテナに結びつける(キー入力しない場合)。
  • -w ― コンテナ内の作業ディレクトリを指定する。
コマンド例
# 実行中のコンテナでシェルを実行する
$ docker container exec -it my-container /bin/bash

docker container cp [オプション] コピー元のパス コピー先のパス

Dockerホスト、コンテナ間でファイルをコピーする。コンテナが停止中でも可能。
コンテナは「コンテナ:パス」で指定する。

コマンド例
# Dockerホスト → コンテナ
$ docker container cp /tmp/index.html my-container:/usr/local/apache2/htdocs/
# コンテナ → Dockerホスト
$ docker container cp my-container:/usr/local/apache2/htdocs/index.html .

docker container commit [オプション] コンテナ [イメージ名[:タグ]]

コンテナからイメージを作成する

docker container export [オプション] コンテナ

コンテナのファイルシステムをtarアーカイブとしてエクスポートする。
作成されたtarアーカイブはdocker image importでイメージに変換できる。
docker image saveとは異なり、レイヤー情報やメタ情報は保存されない。
そのため、exportされたファイルをimportして作成したイメージは、runコマンドも明示的にコマンドを入力する必要がある。

  • -o パス ― ファイルに書き出す。

Image

docker image ls

Dockerホストに保存されたイメージの一覧を表示する。

docker image history [オプション] イメージ

イメージの変更履歴を表示する。

  • --no-trunc ― 省略せずに表示する。

docker image tag イメージ[:タグ] イメージ名[:タグ]

イメージ名・タグを変更する

docker image rm [オプション] イメージ

イメージを破棄する。イメージは複数指定可能(スペース区切り)。

docker image prune [オプション]

使用していないイメージをすべて削除する。

docker image build [オプション] パス

Dockerfileからイメージを作成する。

  • --no-cache ― イメージ作成時にキャッシュを使用しない。
  • -t イメージ名[:タグ] ― イメージ名を指定する。

docker image push [オプション] イメージ[:タグ]

Dockerレジストリにイメージをプッシュする。
DockerHubにプッシュする場合、イメージ名をdocker image tag等で「dockerId/リポジトリ名:タグ」に設定する必要がある。
まだ作成されていないリポジトリ名でプッシュすると、イメージ名と同名のpublicなリポジトリが作成される。

コマンド例
# DockerHubの自分のレジストリにプッシュする
$ docker login
$ docker image push dockerId/myimage

docker image pull [オプション] イメージ名[:タグ]

イメージをレジストリから取得する。取得したイメージはDockerホストに保存される。

docker image save [オプション] イメージ

イメージをtarアーカイブに保存する。イメージは複数指定可能(スペース区切り)。
デフォルトでSTDOUTにストリーミングされる。
保存したtarアーカイブはdocker image loadでイメージに変換できる。
docker container exportと異なり、レイヤー構造も保存される。

  • -o パス ― ファイルに書き込む。
コマンド例
$ docker image save -o savedimage.tar myimage

docker image load

tarアーカイブまたはSTDINからイメージを読み込む。
tarアーカイブはdocker image saveでコンテナから作成できる。

  • -i パス ― tarアーカイブファイルから読み込む。

docker image import [オプション] パス [イメージ名[:タグ]]

docker container exportによって作成されたtarファイルからイメージを読み込む。

Volume

docker volume ls [オプション]

ボリュームの一覧を表示する。

docker volume inspect [オプション] ボリューム

ボリュームの詳細情報を表示する。ボリュームは複数指定可能(スペース区切り)。

docker volume create [オプション] [ボリューム]

ボリュームを作成する。

  • --name ― ボリューム名を指定する

docker volume rm [オプション] ボリューム

ボリュームを削除する。

docker volume prune [オプション]

使用していないボリュームをすべて削除する。

Network

docker network ls [オプション]

Dockerのネットワークを一覧表示する。

docker network inspect [オプション] ネットワーク

Dockerのネットワークの詳細情報を表示する。

docker network create [オプション] ネットワーク名

ネットワークを作成する。

  • -d ― ドライバーを指定する。指定しなかった場合、bridgeネットワークが作成される。

docker network connect [オプション] ネットワーク コンテナ

コンテナをネットワークに接続する

docker network disconnect [オプション] ネットワーク コンテナ

コンテナをネットワークから切断する

docker network rm ネットワーク

ネットワークを削除する。ネットワークは複数指定可能(スペース区切り)。

その他

docker login [オプション] [サーバー]

Dockerレジストリにログインする

docker logout [サーバー]

Dockerレジストリからログアウトする

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

dockerでelasticsearchクラスターの検証

dockerでelasticsearchクラスターの検証

前提

  • 今回は検証なので色々おかしいとろがあると思います。

検証環境

  • cloud
    • AWS EC2
  • machine type
    • Rhel8
  • instance type
    • t2.xlarge

目的

  • 今回は検証なので

    docker hostで

    curl 0.0.0.0:9200/_cat/health?v

    ↑叩いた時以下のような出力が得られるようにする

cluster  status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
elasctic green           2         1      0   0    0    0        0             0                  -                100.0%

elastic search container 構築

  • とりあえずalpineにjavaとesを入れてみた、imageが大きくなったがとりあえず良しとする
FROM alpine:3.10


ENV ES_HOME=elasticsearch-7.8.1
ENV JAVA_HOME=/usr/lib/jvm/default-jvm/jre

EXPOSE 9200
EXPOSE 9300

RUN apk update \
    && apk upgrade \
    && apk add perl-utils \
    su-exec \
    openjdk11-jre \
    bash \
    && wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.8.1-linux-x86_64.tar.gz \
    && wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.8.1-linux-x86_64.tar.gz.sha512 \
    && shasum -a 512 -c elasticsearch-7.8.1-linux-x86_64.tar.gz.sha512 \
    && tar -xzf elasticsearch-7.8.1-linux-x86_64.tar.gz \

    && rm -rf /elasticsearch-7.8.1/modules/x-pack-ml \
    && rm -rf elasticsearch-7.8.1-linux-x86_64.tar.gz \
    && rm -rf elasticsearch-7.8.1-linux-x86_64.tar.gz.sha512 \

    && adduser -DH -s /sbin/nologin elasticsearch \
    && chown -R elasticsearch:elasticsearch /elasticsearch-7.8.1/

docker network 作成

  • docker network create --driver=bridge --subnet=10.10.0.0/24 es

container 起動

  • node-1(master)
    • docker run --rm --net es -itd --name alpine-esm1 --privileged -p 9200:9200 -p 9300:9300 --ip 10.10.0.10 alpine-es
  • node-2(data)
    • docker run --rm --net es -itd --name alpine-esm2 --privileged --ip 10.10.0.11 alpine-es

config/elasticsearch.yml

master

cluster.name: elasctic
node.name: ${HOSTNAME}
network.host:  _site_
discovery.seed_hosts:
  - "10.10.0.10"
cluster.initial_master_nodes:
  - "10.10.0.10"
node.master: true
node.data: false
node.ingest: false
node.remote_cluster_client: false

data

cluster.name: elasctic
node.name: ${HOSTNAME}
network.host:  _site_
discovery.seed_hosts:
  - "10.10.0.10"
cluster.initial_master_nodes:
  - "10.10.0.10"
node.master: false
node.data: true
node.ingest: false
node.remote_cluster_client: false


elasticsearch 起動

  • su-exec elasticsearch /elasticsearch-7.8.1/bin/elasticsearch

  • ↑を各containerで実行

docker host で

  • curl 0.0.0.0:9200/_cat/health?v

まとめ

  • 今までそれほど考えていなかったdocker networkの勉強になった。
  • ec2上での開発は楽しい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerに詳しくない人間がDocker起動ができなくなった環境を直すまでの長い物語。

まずはじめに。

※物語を別に読みたくない人、解決方法を知りたい方は下記リンクで解決内容にまで飛びます。
解決方法

※この記事には今を生きるAくんと過去を生きているBくんがいます。
※AくんとBくんは同一人物です。
※物語としてAくんとBくんの会話は成り立ってるように調整していますが、実際には会話ができてるわけではないです。
※Aくん = 今の自分、 Bくん = 過去の自分

エピソード1 Dockerが起動しない

:boy:Bくん
Dockerを使って開発をしていました。

久々にそのリポジトリで実装対応があり、今まで通りDockerを使って開発をしようとしたところ、

Dockerが起動できずにエラーが出るように・・・

エラー内容

Bundler::GitError: The git source git://github.com/carrierwaveuploader/carrierwave.git is not yet checked out. Please run `bundle install` before trying to start

なにこれ?

bundle installしてよ!的なことを言ってるけど、bundle installしたらええのか?

Docker起動から抜けて、

$ bundle install

を実行。

その後再度、Dockerを起動するものの同じエラーが出る。

:boy:Bくん
「なんでできないのか謎だわ〜」

:man_tone1:Aくん
「いや、そりゃそうでしょ、ここでのエラーはDockerコンテナ内での話をしてるのになんで、Docker起動から抜けて"bundle install"しとるんや?」
「それをやるなら"Dockerfile"内で"bundle install"してやらんとあかんでしょ?」

:boy:Bくん
「あー、そういうことなのね。でも、"Dockerfile"内で"bundle install"してるよ。」

:man_tone1:Aくん
「じゃあ、エラーの内容はそこではないね。エラー文から他の原因を探すしかないよ」

:boy:Bくん
「そうだな。もう一度見てみるか」

エピソード2 エラー内容ググる

エラー内容

Bundler::GitError: The git source git://github.com/carrierwaveuploader/carrierwave.git is not yet checked out. Please run `bundle install` before trying to start

:boy:Bくん
「上記がエラー内容だけど、"bundle install" だけどそれはさっきやってそこじゃなかったから他のところか〜」
「とりあえずググってみるかな〜」

ググってみるものの、此れと言って同じように該当するものが見当たらない・・・
エラー内容から何かヒントがないか探してみる。

「git://github.com/carrierwaveuploader/carrierwave.git これが結局なんか checked out できないからダメなのか?」

:man_tone1:Aくん
「おっ!そ言うことなのでは?じゃあ、次はなにをして解決にたどり着くかな?」

:boy:Bくん
「とりあえず、grepとかかけたけど、ヒットしないなー。」

:man_tone1:Aくん
「grepの仕方を変えてみればいいんじゃない?」

:boy:Bくん
「お!なんかヒットしたぞ。ファイルは...GemfileとGemlockfile.lock...」

※実際にはここでの調査だったり、試行錯誤がめちゃくちゃ時間を取られてハマってます。

エピソード3 gemファイルを見てみる

特定の場所がヒットしてたけどその部分は

Gemfile

gem 'carrierwave', github: 'carrierwaveuploader/carrierwave', tag: 'v1.2.2'

Gemfilel.lock

GIT
  remote: https://github.com/carrierwaveuploader/carrierwave.git

とあった。

:boy:Bくん
「これでなんで checked out できないんだ?」

:man_tone1:Aくん
「GemfileとGemfilel.lockで書き方が違くない?」

:boy:Bくん
「そうなの?まあ、確かに違うと入れれば違うけど。」

:man_tone1:Aくん
「Gemfileの書き方をhttpsで書いてみたら?」

:boy:Bくん

gem 'carrierwave', :git => 'https://github.com/carrierwaveuploader/carrierwave.git', tag: 'v1.2.2'

こう言うこと?

:man_tone1:Aくん
「そうだね。」

エピソード4 再実行してみる

:boy:Bくん
「修正してみたから、再度Docker起動してみるか。」

$ docker-sync-stack start

これでどうかなー。。。

エラー内容

Bundler::GitError: The git source git://github.com/carrierwaveuploader/carrierwave.git is not yet checked out. Please run `bundle install` before trying to start

:boy:Bくん
「ダメじゃないかー!!!なんでやねん!!!」

:man_tone1:Aくん
「一回、docker再起動とかしてみた?」

:boy:Bくん
「してない!!!」

:man_tone1:Aくん
「してみて!!!!」

:boy:Bくん

$ docker-compose down

$ docker system prune

$ docker ps -a

「よし、起動してるものなくなった!」

「じゃあ、もう一度起動するか」

$ docker-sync-stack start

これを実行して、、、

:man_tone1:Aくん
「ちょっと待ちなさい!!!」

:boy:Bくん
「え?なに?」

:man_tone1:Aくん
「ビルドする前の状態にしてないからして!!」

:boy:Bくん

$ docker-sync-stack clean

「これか...」

:man_tone1:Aくん
「そうそう。そのあとに起動する前にビルドしてね!」

:boy:Bくん
「なるほど・・・」

$ docker-compose build

「これをして、、、」

$ docker-sync-stack start

これをしてと・・・・

... コンテナを立ち上げ中 ...

app_1  | [2020-05-01 09:01:23] INFO  WEBrick::HTTPServer#start: pid=1 port=3001

「お!!エラーがなくなって起動できた!!!!わーい!!!」

:man_tone1:Aくん
「やったね!おめでとう!!」

ここで、Docker起動までの物語は終わりです。

今回の件で学んだこと

  • エラー内容を読む
  • エラー内容を理解する
  • ググる
  • トライアンドエラーを繰り返す

当たり前ではあるけど、こうやって、今ある問題や課題を解決していくしかないと感じました。
もちろんすでに実体験のある人やノウハウがある人に聞けば一発で解決すると思いますが、
その問題が他で起きていない場合や、ググってもなかなか見つからない場合などはトライアンドエラーを繰り返して解決に近づいていくしかないなと感じました。

解決方法

今回の場合
GemfileとGemfile.lockが更新された際にGemfileだけgithubで記載されている状態になっていたので、
それをhttpsにしてあげることで解決しました。

Dockerが起動できていた時の状態

Gemfilel

gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'

Gemfilel.lock

GIT
  remote: git://github.com/carrierwaveuploader/carrierwave.git

Dockerが起動できなくなった時の状態

Gemfilel

gem 'carrierwave', github: 'carrierwaveuploader/carrierwave', tag: 'v1.2.2'

Gemfilel.lock

GIT
  remote: https://github.com/carrierwaveuploader/carrierwave.git

Dockerが起動できるように修正した状態

Gemfilel

gem 'carrierwave', :git => 'https://github.com/carrierwaveuploader/carrierwave.git', tag: 'v1.2.2'

Gemfilel.lock

GIT
  remote: https://github.com/carrierwaveuploader/carrierwave.git

今回の解決方法

Gemfilelの修正

修正前

gem 'carrierwave', github: 'carrierwaveuploader/carrierwave', tag: 'v1.2.2'

修正版

gem 'carrierwave', :git => 'https://github.com/carrierwaveuploader/carrierwave.git', tag: 'v1.2.2'

修正後はdockerを再起動して、ビルドし直して起動してみる

# 完全に元の状況に戻す(ビルドする前の状態)
$ docker-sync-stack clean

# コンテナを停止する
$ docker-compose down

# 停止中のコンテナなど全て綺麗にする
$ docker system prune

# コンテナの確認(空であることを確認)
$ docker ps -a

# ビルドを実行
$ docker-compose build

# ファイル同期してコンテナを立ち上げる
$ docker-sync-stack start
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Kubernetes】入門したので簡潔にまとめてみた

【1】 マニフェストファイル(AP)

◆ Pod

  • Pod作成時ContainerCreatingの場合$ kubectl describe pod [Pod名]で確認
pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: sample-app
  namespace: default
  labels:
    app: test
    type: application
spec:
  containers:
    - name: sample-app
      image: sample-app:v1.0
    command:
      - /bin/bash
    args:
      - -c
      - rails db:migrate && rails server

◆ Service

service.yml
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  ports:
  - port: 3000
    targetPort: 3000

◆ Deployment

Deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  selector:
    matchLabels:   #templateのlabelと一致させる
      app: test
    replicas: 2
  strategy:
    rollingUpdate:   #基本はRollingUpdate一択
      maxSurge: 1
      maxUnavailable: 1
  revesionHistoryLimit: 12   #ReplicaSetの履歴保存数
    template:
      metadata:
        labels:   #5行上のmatchLabelsと一致させる
          app: test
      spec:
        containers:
        - name: sample-app
          image: sample-app:v1.0
          ports:
          - containerPort: 3000

◆ ConfigMap

configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: config   #configMapKeyRefで使用
data:
  sample.cfg: |
    username: test   #configMapKeyRefで使用

---

apiVersion: v1
kind: Pod
metadata:
  name: sample
spec:
  containers:
  - name: sample-app
    image: sample-app:v1.0
    env:
    - name: TYPE
      valueFrom:
        configMapKeyRef:
          name: config     #上記configMapのmetadata参照
          key: username    #上記configMapのdataプロパティ参照

◆ Ingress

ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: sample
spec:
  rules:
  - http:
      paths:
      - path: /   #どのパスにリダイレクトするか設定
        backend:
          serviceName: sample   #Serviceマニフェストのmetadata参照
          servicePort: 80

【2】 マニフェストファイル(DB)

◆ Pod

pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: sample-db
spec:
  containers:
    - name: postgresql
      image: sample-db:v1.0
    volumeMounts:
        - mountPath: "/var/lib/postgresql/data"
          name: db
  volumes:
    - name: db
      persistentVolumeClaim:
        claimName: sample-pvc

◆ PersistentVolume PersistentVolumeClaim

pv-pvc.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: sample-pv
spec:
  capacity:                   #ストレージ容量
    storage: 1Gi
  accessModes:
  - ReadWriteMany              #他はReadWriteOnce, ReadOnlyMany
  storageClassName: standard   #ストレージの種類
  hostpath:
    path: "/tmp"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sample-pvc
spec:
  accessModes:
    - ReadWriteMany            #他はReadWriteOnce, ReadOnlyMany
  resources:
    requests:
      storage: 1Gi             #ストレージ容量
  storageClassName: standard   #ストレージの種類

【3】 pod操作

◆ pod作成
$ kubectl apply -f pod.yml     
◆ pod一覧確認
$ kubectl get pod
NAME    READY     STATUS    RESTARTS   AGE
sample    1/1       Running    0         3s
◆ pod削除
$ kubectl delete pod sample     
$ kubectl delete -f pod.yml     
◆ podログイン
$ kubectl exec -it sample sh   
◆ podとのファイル転送
$ kubectl cp sample:/root/hello.txt ./hello.txt   
◆ pod詳細表示
$ kubectl describe pod/sample 
◆ podログ確認
$ kubectl logs pod/sample     
◆ IPアドレス確認
$ kubectl get pod -o wide

【4】 kubectlインストール

$ brew install kubectl
$ brew install kubernetes-cli
$ kubectl version --client

参考文献

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

GCEでselenium standalone-chromeを動かす

現象

selenium/standalone-chromeのcontainerをGCEでしばらく使っていたらsshに接続できなくなった。
ローカルのMacbookでは発生していなかった。
メモリ関連が原因だと考え調査したところ、Out Of Memoryが発生していた。

https://hub.docker.com/r/selenium/standalone-chrome/

docker run -d -p 4444:4444 --shm-size=2g selenium/standalone-chrome:latest

解決策

VMのメモリを監視しswap領域を追加した。
(お金のある人はメモリがたくさん乗ったインスタンスを使うのが理想的です。)

swapの追加方法

sudo dd if=/dev/zero of=/swapfile bs=1M count=3000
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

swapが追加されていることを確認する

free -m
             total        used        free      shared  buff/cache   available
Mem:          ****        ***        ***         ***         ***         ***
Swap:         2999        ***        ***

次回起動時に自動でmountできるように /etc/fstabに追記する。

# /etc/fstab
/swapfile none swap sw 0 0

現象の究明

メモリ状態を監視する

stackdriver-agentを導入し、Cloud Monitoring にメモリのグラフが出るようにした。
https://cloud.google.com/monitoring/agent/installation?hl=ja

Out Of Memoryが起きたときの状態

image.png

  • Timeoutしてssh接続できない
  • Cloud Monitoring でメモリ状態を監視したところ、徐々にFreeが減少し、最終的にVMは起動しているがグラフが出ない状態になる。

swapの容量

  • メモリ3Gのインスタンスを使っていたので3Gを設定

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/managing_storage_devices/recommended-system-swap-space_getting-started-with-swap

システム内の RAM の容量 推奨されるスワップ領域 ハイバネートを許可する場合に推奨されるスワップ領域
⩽ 2 GB RAM 容量の 2 倍 RAM 容量の 3 倍
2 GB ~ 8 GB RAM 容量と同じ RAM 容量の 2 倍
8 GB ~ 64 GB 最低 4GB RAM 容量の 1.5 倍
64GB 未満 最低 4GB ハイバネートは推奨されない

※ ハイバネートはwindowsのsleepみたいなやつで、メモリの状態を一時的にHDDに保存する機能です。

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

GCE+Ubuntu+Docker環境構築をコマンドで

環境

  • MacOS X 10.15.5 (Catalina)
  • Homebrew 2.4.9
  • Google Cloud SDK 304.0.0

GCP アカウント登録

【画像で説明】Google Cloud Platform (GCP)の無料トライアルでアカウント登録

Google Cloud SDK のインストール

Google Cloud SDK のインストール ~ 初期化

プロジェクト作成

Google Cloud SDK でプロジェクトを作成する

インスタンスの作成

インスタンス名を決める

変数に入れておきます。

$ INSTANCE='anata_no_instance_name'

公開 VM イメージを確認

インスタンスを作成する際にPROJECTFAMILYを参照します。

$ gcloud compute images list

NAME               PROJECT      FAMILY   DEPRECATED STATUS
centos-6-v20200714 centos-cloud centos-6            READY
centos-7-v20200714 centos-cloud centos-7            READY
.
.
ubuntu-1804-bionic-v20200807 ubuntu-os-cloud ubuntu-1804-lts READY

インスタンスの作成

今回は ubuntu-1804-lts を利用

$ gcloud compute instances create $INSTANCE \
--image-family ubuntu-1804-lts \
--image-project ubuntu-os-cloud \
--zone asia-northeast1-a \
--machine-type f1-micro \
--boot-disk-size 30GB

GCPには12か月間、$300分のクレジットがもらえる無料トライアルと、規定範囲内であればクレジットとは関係なく各サービスを無料でつかえるAlwaysFreeという仕組みがあります。
無料トライアル期間中でも Always Free の規定内であればクレジットは消費されないようです。

無料トライアルの期間中に Always Free の対象となるリソースをご利用になる場合、そのリソースが無料トライアルのクレジット分から差し引かれることはありません。

※ 規定が変わる可能性もあるため、こちらをご確認ください。
https://cloud.google.com/free/docs/gcp-free-tier#always-free

インスタンスの詳細確認

作成されたインスタンスを確認してみる。

$ gcloud compute instances describe $INSTANCE

SSH 接続

インスタンスに SSH 接続するための設定をしていきます。

キーペアの作成

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -C 'example@gmail.com'
.
.
Enter passphrase (empty for no passphrase): # 秘密鍵にアクセスするためのパスフレーズを登録
Enter same passphrase again: # 確認のためもう一度
.
.

-t rsa(RSA 方式)
-b 鍵長 4096 ビット方式
-C コメント。GCP に鍵登録する場合は、ここで指定したものを自動でユーザー追加してくれる。

おまけ

gcloud コマンドでも可能

$ gcloud compute ssh $INSTANCE

秘密鍵の権限変更

セキュリティの観点からファイル権限を 400 に変更しておきます。
※ 所有者のみが読み取りのみ可能な権限

$ chmod 400 ~/.ssh/id_rsa

公開鍵をコピー

$ cat ~/.ssh/id_rsa.pub | pbcopy

公開鍵の登録

こちらは GUI で操作する必要があるようです。

GCP コンソールから
https://console.cloud.google.com/

プロジェクト全体で登録する場合

スクリーンショット 2020-08-12 16 11 25

スクリーンショット 2020-08-12 16 12 05

スクリーンショット 2020-08-12 16 12 23

インスタンス毎に登録する場合

スクリーンショット 2020-08-13 14 35 51

接続

ssh コマンドで接続します。

$ ssh ユーザーネーム@外部IP -i ~/.ssh/id_rsa
.
.
Are you sure you want to continue connecting (yes/no/[fingerprint])? # <- yesと入力
Enter passphrase for key '/Users/anata_no_home_dir/.ssh/id_rsa': # <- パスフレーズを入力(キーペア作成時に登録したもの)
・
・

おまけ

Are you sure you want to ~ は初回接続時に聞かれる。(接続先のフィンガープリントが変わったときも)
yes と回答することで~/.ssh/known_hosts ファイルに追加され、次回以降は聞かれなくなります。

-oStrictHostKeyChecking=no オプションをつけることでスキップ可能。
回答をスキップし known_hosts に登録されるがセキュリティ的にはよろしくないので問題ないと判断できる場合のみ。

$ ssh ユーザーネーム@外部IP -i ~/.ssh/id_rsa -oStrictHostKeyChecking=no

config ファイルに登録

~/.ssh/config ファイルを編集します。

/Users/anata_no_home_dir/.ssh/config
Host webserver <- 任意のホスト名
    User anata_no_user_name
    HostName 192.0.2.1
    Port 22
    IdentityFile ~/.ssh/id_rsa

おまけ

config ファイルにStrictHostKeyChecking noを追記することで、-oStrictHostKeyChecking=no と同じことが可能。

/Users/anata_no_home_dir/.ssh/config
Host webserver
    User anata_no_user_name
    HostName 192.0.2.1
    Port 22
    IdentityFile ~/.ssh/id_rsa
    StrictHostKeyChecking no <- これ
    UserKnownHostsFile=/dev/null  <- これ

UserKnownHostsFile=/dev/null はホストを known_hosts ファイルに追記しないようにするもの。

接続

config ファイルに登録したホスト名でログイン確認

$ ssh webserver

ポートの変更

ポート番号は 0 ~ 65535 までありますが、基本的に 49513 ~ 65535 までの番号を使うのが安心なようです。

https://27bit.com/question-number.html

sshd_config ファイルのポート番号を変更

サーバ内操作になります。

/etc/ssh/sshd_config ファイルを編集。
#Port ~ と記載のある行のコメントアウトをはずし、↑ で変更したポート番号に変更

ここを
<変更前>

.
.
#Port 22
.
.


こうする
<変更後>

.
.
Port 55555
.
.

コマンドで

$ sudo sed -i -e "s/#Port 22/Port 55555/g" /etc/ssh/sshd_config

sshd のサービスを再起動

$ sudo systemctl restart sshd

ファイアウォールルールを変更

VPC ネットワークでいくつかのファイアウォールルールというものがデフォルトで設定されています。
ここでは SSH の設定であるdefault-allow-sshのデフォルトのポート番号を22 -> 55555へ変更します。

$ gcloud compute firewall-rules update default-allow-ssh \
--allow tcp:55555

config ファイルのポート番号を変更

/Users/anata_no_home_dir/.ssh/config
Host webserver
    User anata_no_user_name
    HostName 192.0.2.1
    Port 55555 <- ここ
    IdentityFile ~/.ssh/id_rsa

サーバの設定

サーバ内操作になります。

Ubuntu の時刻同期設定

<サーバ内>

どの時刻サーバと同期させるかの設定。

/etc/systemd/timesyncd.confを編集

ここを

/etc/systemd/timesyncd.conf
.
.
[Time]
#NTP=
#FallbackNTP=ntp.ubuntu.com
.
.

こう

/etc/systemd/timesyncd.conf
.
.
[Time]
NTP=ntp.nict.jp
FallbackNTP=ntp1.jst.mfeed.ad.jp ntp2.jst.mfeed.ad.jp ntp3.jst.mfeed.ad.jp
.
.

再起動

$ sudo systemctl restart systemd-timesyncd

タイムゾーンの設定

現在時刻の確認

$ date

Thu Aug 09 00:06:18 UTC 2020

タイムゾーンの確認

$ timedatectl

                      Local time: Thu 2020-08-09 00:08:23 UTC
                  Universal time: Thu 2020-08-09 00:08:23 UTC
                        RTC time: Thu 2020-08-09 00:08:24
                       Time zone: Etc/UTC (UTC, +0000)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no

タイムゾーンの設定

$ sudo timedatectl set-tumezone Asia/Tokyo

タイムゾーンの変更を確認

$ timedatectl

                      Local time: Thu 2020-08-09 09:16:35 JST
                  Universal time: Thu 2020-08-09 00:16:35 UTC
                        RTC time: Thu 2020-08-09 00:16:36
                       Time zone: Asia/Tokyo (JST, +0900)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no

docker のインストール

サーバ内操作になります。

シェルスクリプトでインストール

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh

ユーザーグループの追加

$ sudo usermod -aG docker anata_no_user_name

権限変更

docker が使用するソケットを一般ユーザでも読み込み出来るようにする

$ sudo chmod 666 /var/run/docker.sock

実行確認

$ docker -v

docker-compose のインストール

GitHub リポジトリのバイナリからインストール

# インストール
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

権限変更

$ sudo chmod +x /usr/local/bin/docker-compose

実行確認

$ docker-compose -v

おまけ

  • docker を d
  • docker-compose を dc

で実行できるようにエイリアスを設定します。

$ sudo sh -c "echo \"\nalias d='docker'\" >> ~/.bashrc"
$ sudo sh -c "echo \"\nalias dc='docker-compose'\" >> ~/.bashrc"

$ source ~/.bashrc

※ sudo echo "alias d='docker'" >> ~/.bashrc だとエラー

確認

以下のコマンドがとおれば OK

d -v

Docker version 19.03.12, build 48a66213fe
dc -v

docker-compose version 1.26.2, build eefe0d31

おしまい

最後まで読んでいただきありがとうございました。

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

GCE x Ubuntu x Docker環境構築をコマンドで

環境

MacOS X 10.15.5 (Catalina)
Homebrew 2.4.9
Google Cloud SDK 304.0.0

GCP アカウント登録

【画像で説明】Google Cloud Platform (GCP)の無料トライアルでアカウント登録

Google Cloud SDK のインストール

Google Cloud SDK のインストール ~ 初期化

プロジェクト作成

Google Cloud SDK でプロジェクトを作成する

インスタンスの作成

インスタンス名を決める

変数に入れておきます。

$ INSTANCE='anata_no_instance_name'

公開 VM イメージを確認

インスタンスを作成する際にPROJECTFAMILYを参照します。

$ gcloud compute images list

NAME               PROJECT      FAMILY   DEPRECATED STATUS
centos-6-v20200714 centos-cloud centos-6            READY
centos-7-v20200714 centos-cloud centos-7            READY
.
.
ubuntu-1804-bionic-v20200807 ubuntu-os-cloud ubuntu-1804-lts READY

インスタンスの作成

今回は ubuntu-1804-lts を利用

$ gcloud compute instances create $INSTANCE \
--image-family ubuntu-1804-lts \
--image-project ubuntu-os-cloud \
--zone asia-northeast1-a \
--machine-type f1-micro \
--boot-disk-size 30GB

GCPには12か月間、$300分のクレジットがもらえる無料トライアルと、規定範囲内であればクレジットとは関係なく各サービスを無料でつかえるAlwaysFreeという仕組みがあります。
無料トライアル期間中でも Always Free の規定内であればクレジットは消費されないようです。

無料トライアルの期間中に Always Free の対象となるリソースをご利用になる場合、そのリソースが無料トライアルのクレジット分から差し引かれることはありません。

※ 規定が変わる可能性もあるため、こちらをご確認ください。
https://cloud.google.com/free/docs/gcp-free-tier#always-free

インスタンスの詳細確認

作成されたインスタンスを確認してみる。

$ gcloud compute instances describe $INSTANCE

SSH 接続

インスタンスに SSH 接続するための設定をしていきます。

キーペアの作成

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -C 'example@gmail.com'
.
.
Enter passphrase (empty for no passphrase): # 秘密鍵にアクセスするためのパスフレーズを登録
Enter same passphrase again: # 確認のためもう一度
.
.

-t rsa(RSA 方式)
-b 鍵長 4096 ビット方式
-C コメント。GCP に鍵登録する場合は、ここで指定したものを自動でユーザー追加してくれる。

おまけ

gcloud コマンドでも可能

$ gcloud compute ssh $INSTANCE

秘密鍵の権限変更

セキュリティの観点からファイル権限を 400 に変更しておきます。
※ 所有者のみが読み取りのみ可能な権限

$ chmod 400 ~/.ssh/id_rsa

公開鍵をコピー

$ cat ~/.ssh/id_rsa.pub | pbcopy

公開鍵の登録

こちらは GUI で操作する必要があるようです。

GCP コンソールから
https://console.cloud.google.com/

プロジェクト全体で登録する場合

スクリーンショット 2020-08-12 16 11 25

スクリーンショット 2020-08-12 16 12 05

スクリーンショット 2020-08-12 16 12 23

インスタンス毎に登録する場合

スクリーンショット 2020-08-13 14 35 51

接続

ssh コマンドで接続します。

$ ssh ユーザーネーム@外部IP -i ~/.ssh/id_rsa
.
.
Are you sure you want to continue connecting (yes/no/[fingerprint])? # <- yesと入力
Enter passphrase for key '/Users/anata_no_home_dir/.ssh/id_rsa': # <- パスフレーズを入力(キーペア作成時に登録したもの)
・
・

おまけ

Are you sure you want to ~ は初回接続時に聞かれる。(接続先のフィンガープリントが変わったときも)
yes と回答することで~/.ssh/known_hosts ファイルに追加され、次回以降は聞かれなくなります。

-oStrictHostKeyChecking=no オプションをつけることでスキップ可能。
回答をスキップし known_hosts に登録されるがセキュリティ的にはよろしくないので問題ないと判断できる場合のみ。

$ ssh ユーザーネーム@外部IP -i ~/.ssh/id_rsa -oStrictHostKeyChecking=no

config ファイルに登録

~/.ssh/config ファイルを編集します。

/Users/anata_no_home_dir/.ssh/config
Host webserver <- 任意のホスト名
    User anata_no_user_name
    HostName 192.0.2.1
    Port 22
    IdentityFile ~/.ssh/id_rsa

おまけ

config ファイルにStrictHostKeyChecking noを追記することで、-oStrictHostKeyChecking=no と同じことが可能。

/Users/anata_no_home_dir/.ssh/config
Host webserver
    User anata_no_user_name
    HostName 192.0.2.1
    Port 22
    IdentityFile ~/.ssh/id_rsa
    StrictHostKeyChecking no <- これ
    UserKnownHostsFile=/dev/null  <- これ

UserKnownHostsFile=/dev/null はホストを known_hosts ファイルに追記しないようにするもの。

接続

config ファイルに登録したホスト名でログイン確認

$ ssh webserver

ポートの変更

ポート番号は 0 ~ 65535 までありますが、基本的に 49513 ~ 65535 までの番号を使うのが安心なようです。

https://27bit.com/question-number.html

sshd_config ファイルのポート番号を変更

サーバ内操作になります。

/etc/ssh/sshd_config ファイルを編集。
#Port ~ と記載のある行のコメントアウトをはずし、↑ で変更したポート番号に変更

ここを
<変更前>

.
.
#Port 22
.
.


こうする
<変更後>

.
.
Port 55555
.
.

コマンドで

$ sudo sed -i -e "s/#Port 22/Port 55555/g" /etc/ssh/sshd_config

sshd のサービスを再起動

$ sudo systemctl restart sshd

ファイアウォールルールを変更

VPC ネットワークでいくつかのファイアウォールルールというものがデフォルトで設定されています。
ここでは SSH の設定であるdefault-allow-sshのデフォルトのポート番号を22 -> 55555へ変更します。

$ gcloud compute firewall-rules update default-allow-ssh \
--allow tcp:55555

config ファイルのポート番号を変更

/Users/anata_no_home_dir/.ssh/config
Host webserver
    User anata_no_user_name
    HostName 192.0.2.1
    Port 55555 <- ここ
    IdentityFile ~/.ssh/id_rsa

サーバの設定

サーバ内操作になります。

Ubuntu の時刻同期設定

<サーバ内>

どの時刻サーバと同期させるかの設定。

/etc/systemd/timesyncd.confを編集

ここを

/etc/systemd/timesyncd.conf
.
.
[Time]
#NTP=
#FallbackNTP=ntp.ubuntu.com
.
.

こう

/etc/systemd/timesyncd.conf
.
.
[Time]
NTP=ntp.nict.jp
FallbackNTP=ntp1.jst.mfeed.ad.jp ntp2.jst.mfeed.ad.jp ntp3.jst.mfeed.ad.jp
.
.

再起動

$ sudo systemctl restart systemd-timesyncd

タイムゾーンの設定

現在時刻の確認

$ date

Thu Aug 09 00:06:18 UTC 2020

タイムゾーンの確認

$ timedatectl

                      Local time: Thu 2020-08-09 00:08:23 UTC
                  Universal time: Thu 2020-08-09 00:08:23 UTC
                        RTC time: Thu 2020-08-09 00:08:24
                       Time zone: Etc/UTC (UTC, +0000)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no

タイムゾーンの設定

$ sudo timedatectl set-tumezone Asia/Tokyo

タイムゾーンの変更を確認

$ timedatectl

                      Local time: Thu 2020-08-09 09:16:35 JST
                  Universal time: Thu 2020-08-09 00:16:35 UTC
                        RTC time: Thu 2020-08-09 00:16:36
                       Time zone: Asia/Tokyo (JST, +0900)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no

docker のインストール

サーバ内操作になります。

シェルスクリプトでインストール

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh

ユーザーグループの追加

$ sudo usermod -aG docker anata_no_user_name

権限変更

docker が使用するソケットを一般ユーザでも読み込み出来るようにする

$ sudo chmod 666 /var/run/docker.sock

実行確認

$ docker -v

docker-compose のインストール

GitHub リポジトリのバイナリからインストール

# インストール
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

権限変更

$ sudo chmod +x /usr/local/bin/docker-compose

実行確認

$ docker-compose -v

おまけ

  • docker を d
  • docker-compose を dc

で実行できるようにエイリアスを設定します。

$ sudo sh -c "echo \"\nalias d='docker'\" >> ~/.bashrc"
$ sudo sh -c "echo \"\nalias dc='docker-compose'\" >> ~/.bashrc"

$ source ~/.bashrc

※ sudo echo "alias d='docker'" >> ~/.bashrc だとエラー

確認

以下のコマンドがとおれば OK

d -v

Docker version 19.03.12, build 48a66213fe
dc -v

docker-compose version 1.26.2, build eefe0d31

おしまい

最後まで読んでいただきありがとうございました。

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

Visual StudioのコードとDockerを使用して同じようにASP.NETコアアプリを開発する

このガイドでは、Ubuntu Linuxデスクトップ上でVisual Studio Codeを使用してASP.NETコアアプリを開発し、Alibaba Cloud上でDockerを使用して同じアプリをデプロイします。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

よくある質問

.NET coreとは?

.NET Core は、Microsoft と .NET コミュニティによってメンテナンスされているオープンソースの汎用開発プラットフォームです。クロスプラットフォーム(Windows、MacOS、Linuxをサポート)であり、デバイス、クラウド、IoTアプリケーションの構築に使用できます。

ASP.NET coreとは?

ASP.NET Coreは、クロスプラットフォーム、高性能、オープンソースのフレームワークで、最新のクラウドベース、インターネットに接続されたアプリケーションを構築するためのフレームワークです。

Dockerとは?

Dockerは非常に人気のあるコンテナプラットフォームで、アプリケーションやサービスを簡単にパッケージ化、デプロイ、消費することができます。

Visual Studio Codeとは?

Visual Studio Codeは、デスクトップ上で動作する軽量かつ強力なソースコードエディタで、Windows、MacOS、Linuxに対応しています。JavaScript、TypeScript、Node.jsをビルトインでサポートしており、他の言語(C++、C#、Java、Python、PHP、Goなど)やランタイム(.NET、Unityなど)に対応した拡張機能の豊富なエコシステムを備えています。Visual Studio Codeでは、Dockerを使用したアプリケーションのデプロイを簡単に行うことができ、プロジェクトの種類に応じて適切なDockerファイルの生成と追加をサポートしています。

Alibaba Cloud Simple Application Serverとは?

Simple Application Serverは、アプリケーションの起動と管理、ドメイン名解決の設定、Webサイトの構築、監視、保守を数回クリックするだけで行えるオールインワンのソリューションを提供します。プライベートサーバーの構築が格段に簡単になり、初心者がアリババクラウドを始めるのに最適な方法です。

アプリケーションの開発例

Ubuntu Linuxデスクトップに前提条件をインストール

私はバージョン16.04のUbuntu Linuxデスクトップを持っています。記載されている手順は、どのバージョンでもほとんど同じです。

Node.js

node.jsがインストールされているかどうかを確認します。

node –v

バージョン番号が表示されない場合は、以下の手順でインストールしてください。

sudo apt-get install curl python-software-properties
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash –
sudo apt-get install nodejs

ノードとnpmのバージョンを確認します。

node –v
npm –v

.net core sdk

次のコマンドを実行して、.net core sdkをインストールします。

wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2

注:あなたがUbuntu 16.04 - x64とは異なるlinuxのバージョンを持っている場合は、https://dotnet.microsoft.com/download/linux-package-manager/ubuntu16-04/sdk-current に移動し、linuxのバージョンを変更します。

Docker

DockerにはEnterprise版とCommunity版があります。今回はコミュニティ版のDocker CEをインストールします。

以前のバージョンがインストールされているかどうかを確認し、インストールされている場合はアンインストールしてください。

sudo apt-get remove docker docker-engine docker.io containerd runc

aptパッケージを更新します。

sudo apt-get update

aptがHTTPSでリポジトリを使用できるようにします。

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
           gnupg-agent \
    software-properties-common

GPGキーを追加します。

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –

安定版リポジトリを設定してインストールします。

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

dockerをインストールします。

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

hello-worldイメージを実行して、Dockerが正しくインストールされているか確認します。

sudo docker run hello-world

このコマンドはイメージをダウンロードしてコンテナ内で実行し、そのコンテナ内でHello Worldを印刷します。

しかし、上記のコマンドは sudo または root ユーザーのアクセスで実行されています。

次にインストールする Visual Studio Code とその docker 拡張モジュールを IDE として使用する予定なので、非 root ユーザで実行できるようにする必要があります。VS Code は非 root ユーザーで実行され、拡張機能によりコンテナ化されたアプリケーションの構築、管理、デプロイが容易になります。

dockerグループを作成します。

sudo groupadd docker

dockerグループにユーザーを追加します。

sudo usermod -aG docker $USER

ログアウトして再度ログインするか、グループのメンバーシップが再評価されるように再起動してください。

sudo 再起動
再起動後、sudoなしでdockerコマンドが実行できることを確認します。

docker run hello-world

Visual Studioコード

VS Code をインストールする最も簡単な方法は、Snap パッケージとしてインストールすることです。スナップはすべての主要な Linux ディストリビューションで使用することができ、ほとんどの Ubuntu デスクトップにプリインストールされています。もしあなたのデスクトップにない場合は、https://docs.snapcraft.io/installing-snapd からインストールすることができます。

を実行してVSコードをインストールします。

sudo snap install --classic code

アプリケーション/プログラミングから同じものを選択するか、linuxターミナルでコードを入力してVisual Studioのコードを開きます。

表示」→「拡張機能」に移動します。

C# for Visual Studio Code (powered by OmniSharp)」を検索し、拡張機能をインストールします。拡張機能の詳細については https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp を参照してください。

Docker」を検索して、拡張機能をインストールします。拡張機能の詳細は https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker を参照してください。

.NETコアプロジェクトを作成

フォルダを開くを選択し、documentsディレクトリに移動します。ここでプロジェクトを作成します。

VS Codeにはシェルコマンドを実行するためのターミナルが統合されています。そこから直接.NET Coreのコマンドラインインターフェイス(CLI)コマンドを実行することができます。

Visual Studio Codeのトップメニューから「ターミナル」→「新規ターミナル」を選択してターミナルを開きます。

利用可能なテンプレートの一覧を取得してみましょう。

dotnet new -l

image.png

数あるプロジェクトテンプレートの中から、新しいASP.NET Core MVC Appを作成してみましょう。

dotnet new mvc -n dotnetcore-alibaba-docker-tutorial --no-https

上記のコマンドは、ベースアプリケーションを作成し、dotnetcore-alibaba-docker-tutorialというフォルダ内にASP.NET Core 2.2 MVCアプリケーションをスキャフォールドします。'--no-https' コマンドオプションを使用すると、プロジェクト作成時に https をオプトアウトすることができます。コマンドやその他の利用可能なオプションについての詳細は https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new?tabs=netcore22 を参照してください。

image.png

Visual Studio Codeのトップメニューから「ファイル」→「フォルダを閉じる」を選択して、VS Codeでアプリケーションを閉じます。

コードの編集と変更

ここに独自の開発コードを追加します。ここでは、いくつかの簡単な変更を行います。

Open Folderを選択し、documentsフォルダの下にあるdotnetcore-alibaba-docker-tutorialフォルダに移動し、アプリケーションを開きます。

欠けているアセットを追加するように促されます (Require assets to build and debug are missing)。これは.vscodeフォルダで、同じlaunch.jsonとtask.jsonの中に、F5でアプリケーションを起動してデバッグすることができるようになっているので、Yesボタンをクリックするだけです。

左側のペインから、ビュー→ホーム→index.cshtmlを選択します。

'Welcome'という単語を'Welcome to Docker on Simple Application Server'に更新します。

ビュー→共有→layout.cshtmlを選択します。

dotnetcore_alibaba_docker_tutorial」のすべてのインスタンスを「Alibaba Cloud」に更新します。インスタンスは3つあり、1つはタイトル、1つはナビバー、そして最後の1つはフッターになります。

アプリケーションの実行

F5ボタンを押してアプリケーションを実行します。

アプリケーションが実行され、Webアプリケーションが http://localhost:5000 に表示されます。

注意:最新の.NET Coreでは、開発アプリケーションはhttpsで動作します。そのため、''--no-https' コマンドオプションを付けずにプロジェクトを作成し、アプリケーションを実行した場合、接続がプライベートではないという警告が表示されます。そのような場合は、[詳細設定]ボタンをクリックし、[ローカルホストに進む(安全ではない)]をクリックして、http://localhost:5001 にある Web アプリケーションを表示します。

Visual Studio Codeのトップメニューから「ファイル」→「フォルダを閉じる」を選択して、VS Codeでアプリケーションを閉じます。

アプリケーションをDockerizeする例

パブリックリポジトリは、誰もが利用できるDockerイメージをホスティングするために使用することができます。Docker hubはパブリックリポジトリであり、利用するためのパブリックなDockerイメージのリストを見つけることができます。必要なのはそれらのイメージを引っ張ってきて、それを元にコンテナを起動し始めることだけです。また、Alibaba Cloudは、高速で信頼性が高く、安全なプライベートコンテナレジストリを提供しています。https://www.alibabacloud.com/product/container-registry私たちは、このプライベートリポジトリにイメージを公開することで、イメージを利用可能にしています。

Alibaba Cloudコンテナレジストリアカウントの作成

アリババクラウドコンテナレジストリアカウントとリポジトリの作成

アリババクラウドアカウントをお持ちでない方は、https://account.alibabacloud.com/register/intl_register.htm で無料で取得できます。

コンソールに移動し、[製品]の下の[コンテナレジストリ]を選択します。

パスワードを入力して確認し、Alibaba Cloud Container Registryを有効化します。このパスワードは、クラウドアカウントとは異なるコンテナレジストリ用のパスワードです。

これで、以下のようにコンテナレジストリのコンソールが表示されるはずです。

image.png

ネームスペースはリポジトリの集合体、リポジトリはイメージの集合体です。アプリケーションごとにネームスペースを、イメージごとにリポジトリを用意します。1つのイメージのすべてのバージョンが1つのリポジトリに入ります。

左メニューのDefault InstanceからNamespacesを選択し、Create Namespaceボタンをクリックします。

下の画像のようにネームスペースを入力し、確認ボタンをクリックします。

image.png

ネームスペースが作成されます。自動的にリポジトリを作成するオプションをオフにします。

左メニューからリポジトリに戻り、リポジトリの作成を選択します。

リポジトリ名を入力し、リポジトリタイプをプライベートのままにして、サマリーテキストを入力します。

image.png

次の画面で、コードソースとしてローカルリポジトリを選択し、リポジトリの作成をクリックします。

Container Registryでは、Alibaba Cloud Code、Github、Bitbucketなどのソースコードリポジトリを使用して、イメージの自動ビルドを作成することもできます。

image.png

作成したリポジトリで、リポジトリ名をクリックします。

この画面を通過し、リポジトリへのログイン、画像のプル、プッシュに必要なコマンドを学習します。

image.png

アプリケーションをDockerizeする

フォルダを開くを選択し、documentsフォルダの下にあるdotnetcore-alibaba-docker-tutorialフォルダに移動し、アプリケーションを開きます。

Visual Studio Codeのトップメニューから「ターミナル」→「新規ターミナル」を選択してターミナルを開きます。

Dockerがインストールされて実行されていることを確認します。

docker --version

Visual Studio CodeのトップメニューからView->Command Paletteを選択してCommand Paletteを開きます。

ワークスペースにDockerファイルを追加と入力し、Dockerを選択して実行します。Docker ファイルをワークスペースに追加 コマンドを実行します。

コマンドパレットでアプリケーションプラットフォームの選択を求められますので、ASP.NET Coreを選択します。

次のコマンドパレット画面で、オペレーティングシステムとして linux を選択します。

また、アプリケーションがリッスンするポートを指定してください。

これは、ソースファイルの場所やコンテナ内でアプリを起動するコマンドを含むアプリの環境を記述するDockerfileと共にプロジェクトに特定のファイルを追加します。DockerIgnoreファイルは、ビルドコンテキストを可能な限り小さく保つのに役立ちます。

image.png

dockerfileで何が起こっているのかを理解してみましょう。

まず、アプリケーションのビルドに必要なパッケージと依存関係を復元します。次に、アプリケーションをビルドし、/appディレクトリに公開します。この段階では、Microsoft Container Registry (MCR)で利用可能な.NET Core SDKをベースイメージとして使用します。

次に、ベースイメージとして.NET Core Runtimeを使用し、前の段階で生成したバイナリを/appディレクトリからコピーします。ENTRYPOINT内のアセンブリ名は大文字と小文字を区別し、binDebugフォルダ内のアセンブリ名と一致させる必要があります。

コマンドパレットでDocker: Build Imageを実行してイメージをビルドします。名前を聞かれたらデフォルトの名前を受け入れてください。イメージには[projectname]:latestというタグが付けられます。

ターミナルパネルが開き、Dockerコマンドが実行されます。ビルドが完了すると、DockerのエクスプローラのImagesの下にイメージが表示されます。

image.png

コマンドパレットでdocker runと入力し、Docker:Images runを選択してコンテナをビルドします。

コマンドパレットで、イメージグループ「dotnetcore-alibaba-docker-tutorial」を選択します。

コマンドパレットで、画像の「最新」を選択します。

ターミナルに表示された生成されたコマンドを実行します。

コマンドは'docker run'で、2つのフラグがあります。

-p : これはコンテナ上のポートを公開し、ホスト上のポートにマッピングします。ここでマッピングされたホスト上のポートも同様に5000です。

-d : バックグラウンドでコンテナを実行します。

詳細は https://docs.docker.com/engine/reference/commandline/run/ を参照してください。

お使いのブラウザで http://your_server_ip:5000 または http://localhost:5000 に移動して、アプリケーションを表示します。

残念ながらウェブサイトは表示されません。

実行中のコンテナを検査します。

Docker ps

コンテナログを検査します。

Docker logs [CONTAINER ID] 

CONTAINER ID]をDocker psコマンドで取得した自分のCONTAINER IDに置き換えます。

image.png

ログを見ると、デフォルトでは80番ポートでリッスンされています。

mcr.microsoft.com/dotnet/core/aspnet:2.2 イメージは ASPNETCORE_URLS をポート 80 に設定しています。

実行中のコンテナを右クリックして、DOCKER explorer の Containers の下にある stop を選択して、実行中のアプリケーションコンテナを停止してください。

または、ターミナルで以下のコマンドを実行することもできます。

docker stop [CONTAINER ID]

以下のようにDockerfileを更新して、kestrelのWebサーバがリッスンするURLを明示的に指定します。

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
ENV ASPNETCORE_URLS http://+:5000
EXPOSE 5000

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src
COPY ["dotnetcore-alibaba-docker-tutorial.csproj", "./"]
RUN dotnet restore "./dotnetcore-alibaba-docker-tutorial.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "dotnetcore-alibaba-docker-tutorial.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "dotnetcore-alibaba-docker-tutorial.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "dotnetcore-alibaba-docker-tutorial.dll"]

コンテナをビルドして先ほどと同じように実行し、今回はブラウザから http://your_server_ip:5000 または http://localhost:5000 に移動してアプリケーションを表示できるようになります。

Alibaba Cloud Container Registryに画像をアップロード

Visual Studio Code のトップメニューから Terminal -> New Terminal を選択して Terminal を開きます。

Alibaba Cloud Container Registry Repository Guideで利用可能だったコマンドに従ってください。

コンテナレジストリにログインします。

sudo docker login --username=arnab@xyz.abc registry-intl.ap-southeast-1.aliyuncs.com

利用可能な画像を見ます。

sudo docker images

image.png

画像にタグを付けます。

sudo docker tag 183d85283e0b registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1

画像をコンテナレジストリにプッシュします。

sudo docker push registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1

image.png

Alibaba Cloud Container Registry Consoleで、指定したリポジトリとタグのセクションで、イメージが存在することを確認します。

image.png

シンプルなアプリケーションサーバにアプリケーションをデプロイする

並行記事Developing ASP.NET core App in Visual Studio and Deploying on Simple Application Serverをご覧いただき、Alibaba Cloud上にCentOS7でSimple Application Serverインスタンスを作成し、インスタンスへのパスワードを作成し、デスクトップ端末を使ってログインする方法をご紹介します(記事のようにputtyではなく)。

サーバーに前提条件をインストールする

yum
yumは、CentOSでソフトウェアパッケージを取得、インストール、削除、クエリ、管理するための主要なツールです。まず、ソフトウェアリポジトリを最新のバージョンにアップデートするために使います。

yum -y update

Docker

古いバージョンがある場合は、アンインストールしてください。

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

必要なパッケージをインストールします。

sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

インストールするリポジトリの設定

sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

Dockerのインストール

sudo yum install docker-ce docker-ce-cli containerd.io

Dockerの起動

sudo systemctl start docker

Dockerを非rootユーザーで動作させます。

sudo groupadd docker
sudo usermod -aG docker $USER
sudo reboot

Dockerの再起動

sudo systemctl start docker

コマンドが sudo なしで実行されているかどうかを確認します。

docker run hello-world

アプリケーションのデプロイ

コンテナを構築してアプリケーションを実行します。

コンテナレジストリへのログイン

docker login --username=arnab@xyz.abc registry-intl.ap-southeast-1.aliyuncs.com

レジストリからイメージを取り出します。

docker pull registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1

アプリケーションの実行します。

docker run -d -p 80:5000 registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1

ここでは、ホスト側で80番ポートを使用しました。そのため、簡易アプリケーションサーバの公開IP(サーバ管理画面で利用可能)を利用してサイトを閲覧する際には、ポート番号を使用する必要はありません。

http://public_ip にアクセスしてサイトをテストします。アプリケーションが動作しているのが確認できるはずです。

結論

これらは、Ubuntu linux上でビジュアルコードを使用してASP.NET Coreアプリケーションを開発し、アプリケーション用のDockerイメージを作成し、Alibaba Cloudのコンテナレジストリを作成してコンテナレジストリにイメージをプッシュし、最後にCentOSを使用してAlibaba CloudのSimple Application Server上にコンテナレジストリイメージをデプロイするための基本的なステップです。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

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

Visual Studioのコードと同じDockerを使ってNode.jsアプリを開発する

このガイドでは、Ubuntu Linuxデスクトップ上でVisual Studio Codeを使ってNode.jsアプリを開発し、Alibaba Cloud上でDockerを使って同じアプリをデプロイしていきます。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

よくある質問

Node.jsとは?

Node.jsはオープンソースでクロスプラットフォームなJavaScriptのランタイム環境で、サーバー上でJavaScriptを実行することができます。

Express とは?

Expressは、最小限で柔軟性の高いNode.jsのWebアプリケーションフレームワークで、Webとモバイルアプリケーションのための堅牢な機能セットを提供しています。

Dockerとは?

Dockerは非常に人気のあるコンテナプラットフォームで、アプリケーションやサービスを簡単にパッケージ化、デプロイ、消費することができます。

Docker Hubとは?

Docker Hubは、Dockerユーザーやパートナーがコンテナイメージを作成、テスト、保存、配布するクラウドベースのリポジトリです。

Visual Studio Codeとは?

Visual Studio Codeは、デスクトップ上で動作し、Windows、MacOS、Linuxに対応した軽量かつ強力なソースコードエディタです。JavaScript、TypeScript、Node.jsをビルトインでサポートしており、他の言語(C++、C#、Java、Python、PHP、Goなど)やランタイム(.NET、Unityなど)に対応した拡張機能の豊富なエコシステムを備えています。Visual Studio Codeでは、Dockerを使ったアプリケーションのデプロイを簡単に行うことができ、プロジェクトの種類に応じて適切なDockerファイルの生成と追加をサポートしています。

Alibaba Cloud Simple Application Serverとは?

Simple Application Serverは、アプリケーションの起動と管理、ドメイン名解決の設定、ウェブサイトの構築、監視、保守を数回クリックするだけで行えるオールインワンのソリューションを提供します。プライベートサーバーの構築が格段に簡単になり、初心者がアリババクラウドを始めるのに最適な方法です。

アプリケーションの開発例

Ubuntu Linuxデスクトップに前提条件をインストール

私はバージョン16.04のUbuntu Linuxデスクトップを持っています。記載されている手順は、すべてのバージョンでほとんど同じです。

Node.js

node.jsが既にインストールされているかどうかを確認します。

node –v

バージョン番号が表示されない場合は、以下の手順でインストールしてください。

sudo apt-get install curl python-software-properties
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash –
sudo apt-get install nodejs

ノードとnpmのバージョンを確認します。

node –v
npm –v

Docker

DockerにはEnterprise版とCommunity版があります。今回はコミュニティ版のDocker CEをインストールします。

以前のバージョンがインストールされているかどうかを確認し、インストールされている場合はアンインストールしてください。

sudo apt-get remove docker docker-engine docker.io containerd runc

aptパッケージを更新します。

sudo apt-get update

aptがHTTPSでリポジトリを使用できるようにします。

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
           gnupg-agent \
    software-properties-common

GPGキーを追加

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –

安定版リポジトリを設定してインストールします。

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

dockerをインストールします。

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

hello-worldイメージを実行して、Dockerが正しくインストールされているかどうかを確認します。

sudo docker run hello-world

このコマンドはイメージをダウンロードしてコンテナ内で実行し、そのコンテナ内でHello Worldを印刷します。

しかし、上記のコマンドはsudoまたはrootユーザのアクセスで実行されています。

次にインストールするVisual Studio CodeとそのDockerエクステンションをIDEとして使用する予定なので、非rootユーザで実行できるようにする必要があります。VS Codeは非rootユーザで動作し、拡張機能を使うことでコンテナ化されたアプリケーションの構築、管理、デプロイが容易になります。

Dockerグループを作成します。

sudo groupadd docker

ユーザーをdockerグループに追加します。

sudo usermod -aG docker $USER

ログアウトして再度ログインするか、グループのメンバーシップが再評価されるように再起動してください。

sudo reboot

再起動後、sudoなしでdockerコマンドが実行できることを確認します。

docker run hello-world

Visual Studioコード

VS Code をインストールする最も簡単な方法は、Snap パッケージとしてインストールすることです。スナップはすべての主要な Linux ディストリビューションで使用することができ、ほとんどの Ubuntu デスクトップにプリインストールされています。もしあなたのデスクトップにない場合は、https://docs.snapcraft.io/installing-snapd からインストールすることができます。

VSコードをインストールします。

sudo snap install --classic code

アプリケーション/プログラミングから同じものを選択するか、linuxターミナルでコードを入力してVisual Studioのコードを開きます。

「表示」→「拡張機能」に移動します。

Docker」を検索して、拡張機能をインストールします。拡張機能の詳細は https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker を参照してください。

Node.jsプロジェクトの作成

アプリケーション/プログラミングから同じものを選択するか、linuxターミナルでコードを入力してVisual Studioのコードを開きます。

フォルダを開くを選択し、documentsディレクトリに移動します。ここでプロジェクトを作成します。

VS Codeにはシェルコマンドを実行するためのターミナルが統合されています。そこから直接Node.jsを実行することができます

Visual Studio Code のトップメニューから Terminal -> New Terminal を選択して Terminal を開きます。

Express用のテンプレエンジンをインストールするためにExpress Generatorをインストールします。

sudo npm install -g express-generator

新しいエクスプレスアプリケーションを足場にします。

express nodeexpress-alibaba-docker-tutorial --view=pug

これにより、nodeexpress-alibaba-docker-tutorialという名前の新しいフォルダが作成され、左のdocumentsの下にあるアプリケーションの内容を見ることができます。

コードの編集と変更

ここに独自の開発コードを追加します。ここでは、いくつかの簡単な変更を行います。

routes フォルダの下にある index.js を選択します。

index.jsの中のres.renderを含むコードの行に移動します。

以下のように変更してください。

res.render('index', { title: 'Docker on Simple Application Server', data:'Alibaba Cloud' });

フォルダビューの下にあるindex.pugを選択します。

Welcome toを含む行のデータタイトルを変更します。

アプリケーションの実行

VSCodeターミナルで、ディレクトリをアプリケーションフォルダに変更します。

cd nodeexpress-alibaba-docker-tutorial

package.jsonファイルに存在するアプリケーションの依存関係をインストールします。

npm install

image.png

Package.jsonファイルには、Node.jsアプリケーションを実行するためのスタートスクリプトも含まれています。

npm start

ブラウザを開き、localhost:3000にアクセスしてアプリケーションを表示します。ポート番号はスタートスクリプトから呼び出されるbinフォルダ内のファイルwwwの中に設定されています。

Visual Studio Codeのトップメニューから「ファイル」→「フォルダを閉じる」を選択し、VS Codeでアプリケーションを閉じます。

アプリケーションのDockerize例

パブリックリポジトリは、誰もが利用できるDockerイメージをホスティングするために使用することができます。Docker hubはパブリックリポジトリであり、利用するためのパブリックなDockerイメージのリストを見つけることができます。あとはそれらのイメージを引っ張ってきて、それを元にコンテナを起動し始めるだけです。Docker Hub上の公開リポジトリに公開することで、イメージを利用可能にしています。

Docker Hubアカウントとリポジトリの作成

https://hub.docker.com/ にサインアップし、アカウントを作成したらログインします。

トップメニューからリポジトリを選択します。

アカウントを作成したばかりなので、リポジトリはありません。リポジトリの作成ボタンを選択してリポジトリを作成します。これがあなたの画像が保存されるリポジトリです。

image.png

次の画面では、リポジトリの名前と説明を指定します。ここでは下の画像のようにnodeexpress-alibaba-docker-tutorialという名前を指定します。

リポジトリを公開し、dockerhub上で検索できるようにしています。また、リポジトリを非公開にすることもできます。1つのプライベートリポジトリは無料で、課金プランを利用すればそれ以上の数のリポジトリを作成することができます。プライベートリポジトリは公開リポジトリと同じように動作しますが、閲覧や検索ができません。

image.png

Click on the Create button and your repository is ready.

image.png

画面の右端にあるコマンドに注目してください。このコマンドを実行して画像をこのリポジトリにプッシュする必要があります。

画像は [registry or username]/[image name]:[tag] の形式である必要があります。

注:Alibaba Cloudは、https://www.alibabacloud.com/product/container-registry で利用できる安全なコンテナレジストリも提供しています。

アプリケーションをDockerizeする

フォルダを開くを選択し、documentsフォルダの下にあるnodeexpress-alibaba-docker-tutorialフォルダに移動し、アプリケーションを開きます。

Visual Studio Codeのトップメニューから「ターミナル」→「新規ターミナル」を選択してターミナルを開きます。

Dockerがインストールされて実行されていることを確認します。

docker –version

Visual Studio CodeのトップメニューからView->Command Paletteを選択してCommand Paletteを開きます。

ワークスペースにDockerファイルを追加と入力し、Dockerを選択して実行します。Dockerファイルをワークスペースに追加するコマンドを実行します。

image.png

コマンドパレットでアプリケーションプラットフォームの選択を求められますので、Node.jsを選択します。

image.png

また、アプリケーションがリスンするポートを指定します。

image.png

これにより、ソースファイルの場所やコンテナ内でアプリを起動するコマンドなど、アプリの環境を記述するDockerfileと共にプロジェクトに特定のファイルが追加されます。

コマンドパレットでDocker: Build Imageを実行してイメージをビルドします。先ほど作成したDockerfileを選択し、Docker hubリポジトリの作成時に指定したフォーマットでイメージに名前を付けます。名前は......... arnab74/nodeexpress-alibaba-docker-tutorial:firsttry

image.png

ターミナルパネルが開き、Dockerコマンドが実行されます。ビルドが完了すると、DockerエクスプローラーのImagesの下にイメージが表示されます。

コマンドパレットでdocker runと入力し、Docker:Images runを選択してコンテナをビルドします。

image.png

コマンドパレットで、イメージグループ arnab74/nodeexpress-alibaba-docker-tutorial を選択します。

image.png

コマンドパレットで、Image firsttryを選択します。

ターミナルに表示された生成されたコマンドを実行します。

コマンドは'docker run'で、2つのフラグがあります。

-p : これはコンテナ上のポートを公開し、ホスト上のポートにマッピングします。ここでマッピングされたホスト上のポートも同様に3000です。

-d : バックグラウンドでコンテナを実行します。

詳細は https://docs.docker.com/engine/reference/commandline/run/ を参照してください。

実行中のコンテナを検査します。

Docker ps

ブラウザを http://your_server_ip:3000 または http://localhost:3000 に移動してアプリケーションを表示します。

実行中のアプリケーションコンテナを停止するには、実行中のコンテナを右クリックして、DOCKER explorer の Containers の下にある stop を選択します。

image.png

または、ターミナルで以下のコマンドを実行することができます。

docker stop [CONTAINER ID]

CONTAINER ID]をDocker psコマンドで取得した自分のCONTAINER IDに置き換えてください。

お試し追加ステップ

VSCode の docker 拡張機能によって自動的に生成される dockerfile を改良しました。

https://hub.docker.com/_/node/ から現在の nodejs LTS バージョンに基づいてアプリケーションのベースイメージを更新します。

コンテナをrootで実行することは避けなければなりません。Docker Nodeイメージには、rootではないノードのユーザが含まれています。ユーザーと同じにして、そのホームディレクトリを作業ディレクトリに設定します。

新しいDockerfileは以下のようになります。

FROM node:10.16-alpine
ENV NODE_ENV production
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
USER node
RUN npm install --production --silent && mv node_modules ../
COPY --chown=node:node . .
EXPOSE 3000
CMD npm start

前述のプロセスに従って、新しいイメージをビルドし、arnab74/nodeexpress-alibaba-docker-tutorial:latestという名前で実行してテストします。

Docker Hubに画像をアップロードする

Docker Explorerで、レジストリセクションのConnect Registryを選択します。

image.png

利用可能なオプションで、レジストリプロバイダとしてDocker Hubを選択します。

image.png

ユーザー名とパスワードを入力してログインします。

コマンドパレットでdockerタグを書き、Docker Images:Tagを選択します。

次のコマンドパレット画面で画像グループを選択します。

arnab74/nodeexpress-alibaba-docker-tutorial

次の画面でタグ付けする画像を選択

latest

新しいタグを提供

arnab74/nodeexpress-alibaba-docker-tutorial:0.1

コマンドパレットでdocker pushを書き、Docker Images:Pushを選択します。

次のコマンドパレット画面で画像グループを選択します。

arnab74/nodeexpress-alibaba-docker-tutorial

次の画面でDocker hubにプッシュするImageを選択します。

0.1

ターミナル上にDocker Pushコマンドが生成されるので、それに従ってください。

以下のようにターミナル上で上記の手順を行うこともできます。

docker login --username=arnab74
docker images

docker tag [IMAGE ID] arnab74/nodeexpress-alibaba-docker-tutorial:0.2

IMAGE ID を最新のタグ付けされた画像の画像 ID に置き換えてください。

docker push arnab74/nodeexpress-alibaba-docker-tutorial:0.2

アップロードされた画像は、Docker hubのサイトのリポジトリやDocker Explorerのレジストリで確認できるはずです。

シンプルなアプリケーションサーバにアプリケーションをデプロイする

並行記事Developing Node.js App in Visual Studio and Deploying on Simple Application Serverをご覧いただき、Alibaba Cloud上にCentOS7でSimple Application Serverインスタンスを作成し、インスタンスへのパスワードを作成し、デスクトップ端末を使ってログインする方法をご紹介します(記事のようにputtyではなく)。

サーバーに前提条件をインストールする

yum

yumは、CentOSでソフトウェアパッケージを取得、インストール、削除、クエリ、管理するための主要なツールです。まず、ソフトウェアリポジトリを最新のバージョンにアップデートするために使います。

yum -y update

Docker

古いバージョンがある場合は、アンインストールしてください。

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

必要なパッケージをインストールします。

sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

インストールするリポジトリの設定

sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

Dockerのインストール

sudo yum install docker-ce docker-ce-cli containerd.io

Dockerの起動

sudo systemctl start docker

Dockerを非rootユーザーで動作させます。

sudo groupadd docker
sudo usermod -aG docker $USER
sudo reboot
Start Docker again
sudo systemctl start docker

コマンドが sudo なしで実行されているかどうかを確認します。

docker run hello-world

アプリケーションのデプロイ

コンテナをビルドしてアプリケーションを実行します。マシンのローカルにイメージがない場合は、Dockerがリポジトリからイメージを引っ張ってきます。

docker run -d -p 80:3000 arnab74/nodeexpress-alibaba-docker-tutorial:0.1

ここでは、ホストに80番ポートを使用しました。そのため、簡易アプリケーションサーバの公開IP(サーバ管理画面で利用可能)を利用してサイトを閲覧する際には、ポート番号を使用する必要はありません。

http://public_ip にアクセスしてサイトをテストします。アプリケーションが起動しているのが確認できるはずです。

結論

これらは、Ubuntu Linux上でビジュアルコードを使用してNode.jsアプリケーションを開発し、アプリケーション用のDockerイメージを作成し、Dockerハブリポジトリを作成してDockerハブにイメージをプッシュし、最後にCentOSを使用してAlibaba CloudのSimple Application Server上にDockerハブイメージをデプロイするための基本的なステップです。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

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

開発環境でのDocker内のPostgresコンテナへの接続について

いろいろ調べて見つけたのでメモ。もっといいやり方があればご指摘を。

1 「docker ps」で現在の稼働しているコンテナを一覧で表示させ、postgresコンテナのidをチェックする。

$ docker ps

2 上で見たようにチェックしたidをもとに、postgresコンテナへログイン

$ docker exec -it コンテナid bash

3 postgresユーザーとしてpostgres内へログイン

bash-5.0# psql -U postgres

完了!

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

実務未経験者が顧客管理アプリを作ってみた 〜環境構築編その2〜

実務未経験者が顧客管理アプリを作ってみた 〜環境構築編その1〜

前回は仮想マシンにDockerをインストールするところまで進めた。(一ヶ月前)
今回はDockerComposeをインストールして実際にコンテナを立ち上げていく。
ちなみにDockerComposeとはymlファイルへの記述を基に、複数のコンテナの定義、実行ができる非常に便利なツールである。

手順

1.DockerComposeをインストールする
2.docker-compose.ymlを作成する
3.Dockerfileを作成する
4.コンテナを起動する

1.DockerComposeをインストールする

仮想マシン内で以下コマンドを実行する。
DockerCompose公式を参考にする。
https://docs.docker.jp/compose/install.html#linux

#インストール
$sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
#実行権限の付与
$sudo chmod +x /usr/local/bin/docker-compose
#確認
docker-compose --version

2.docker-compose.ymlを作成する

一度仮想マシンから出て、docker-compose.ymlを作成する。
qiita-dockerディレクトリ内に作ろう。

%cd qiita-docker
%touch docker-compose.yml

Dockerfileを基にWebコンテナを構築すること、
qiita-dockerディレクトリ内に後ほど作成するLaravelアプリとWebコンテナの/var/www/htmlのデータを共有すること等を記述する。

docker-compose.yml
version: '3'

services:
  web:
    build: ./
    volumes:
      - ./qiita-docker/app:/var/www/html
    ports:
      - "8080:80"
    depends_on:
      - db 
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: qiita
      MYSQL_USER: root
      MYSQL_PASSWORD: root

3.Dockerfileを作成する

続いてqiita-dockerディレクトリ内にDockerfileを作成していく。
ベースとなるDockerイメージを指定、拡張機能の追加など記述する。
今回はphp:7.2-apacheにエディタであるVim、MySQLとの連携に必要なpdo_mysql、Laravelアプリを作成するのに必要なComposer、zip、unzip等をインストール。

FROM php:7.2-apache

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update
RUN apt-get install -y vim
RUN docker-php-ext-install pdo_mysql
RUN apt-get install -y git zip unzip

4.コンテナを起動する

さっそく仮想マシン内のqiita-docker直下でコンテナを立ち上げる。

$docker-compose up -d

ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?

エラーが出ます。
Docker daemonにコネクトできない、と。
Dockerの使用権限はデフォルトではrootのみに与えられているようです。
sudoコマンドを使うもしくは、dockerグループにユーザーを追加しなければいけない。
今回はdockerグループにユーザーを追加する。

#dockerグループが存在しているか確認
$cat /etc/group | grep docker
#存在していなければ作成
$sudo groupadd docker
#現在ログイン中のユーザーをdockerグループに追加する
$sudo gpasswd -a $USER docker

反映させるために一度exitして仮想マシンに入り直す。
もう一度コンテナを立ち上げる。

$docker-compose up -d

指定したIPアドレスのポート番号にアクセスしてみよう。
スクリーンショット 2020-08-17 7.28.08.png
こちらの画面が表示されれば成功です!

次回はLaravelをインストールして表示させるところまで進めます。

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

WindowsのVSCodeでDocker / Remote - Containersプラグインを使う(公式DDW・DTB・WSL2無しで)

概要

公式で配布されているDDW(Docker Desktop for Windows)DTB(Docker ToolBox on windows)、そしてDocker対応のWSL2も使わず、
WindowsのVSCodeからDockerプラグイン、Remote - Containersプラグインを使ってコンテナ操作をするためのメモです。

Linux側の設定

まず、Linux側で外部のDockerクライアントの要求に対応できるようにしないと使えませんので設定しておく必要があります。

/etc/docker/daemon.jsonで以下のように設定します。ファイルが存在しなければ新規に作成します。2375の部分は任意のポート番号に設定できます

/etc/docker/daemon.json
{"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]}

Docker本体にはユーザー制御的なものは存在しないようなので、ファイアウォールや接続ipの限定でアクセス制限をしないと外部からやりたい放題されるリスクがあります。

同一マシンの仮想PCの場合、通常はWindowsファイアウォールで許可しない限りは外部から接続できませんが、不安なら仮想化ソフトのポートフォワーディング設定でホスト側の対象のアドレスをlocalhostに制限すれば外部からの接続を遮断できます。

Docker CLI / Docker-Composeのダウンロード

Windows側にDocker CLIDocker-Composeをダウンロードします。

Docker CLIは公式では自身でビルドする必要があるようなので、面倒ならビルド済みバイナリを公開している人がいるのでそこからdocker.exeをダウンロードします

Docker-Composeは公式でバイナリ配布されているので、そこからdocker-compose-Windows-x86_64.exeをダウンロードしてdocker-compose.exeにリネームしておきます。

コマンドラインから使ってみる

ダウンロード(ビルド)したdocker.exe、docker-compose.exeがあるフォルダにパスを通します。

DOCKER_HOST環境変数で接続先のDockerのアドレスとポートを設定します。同一マシン内の仮想PCのDockerに接続する場合は次のようにします。

set DOCKER_HOST=localhost:2375

設定に問題なければこれで使えるようになっているはずです。docker psしてみたりdocker run hello-worldしてみたりしてください。

VSCodeのDockerプラグインを使う

Linux側のDockerが起動しており、PATHとDOCKER_HOST環境変数が適切に設定されていればプラグインをインストールするだけで使えるようになるはずです。

バッチファイルやWindowsの設定で環境変数を設定せず、VSCode内で完結させたい場合は前項のDOCKER_HOSTと同じ内容(localhost:2375)をVSCode設定のdocker.hostに、Docker.exeがあるフォルダをterminal.integrated.env.windowsに設定しておきます。

VSCodeのRemote - Containersプラグインを使う

Remote - Containersプラグインはどうもdocker.exeにパスが通っていても実行しないようなので、remote.containers.dockerPathにdocker.exeのフルパスを設定する必要があります。

Dockerプラグインが正常に動作している場合は設定されているはずですが、使わない場合はDOCKER_HOST環境変数またはVSCode設定のdocker.hostに接続先のアドレスとポートを指定しておく必要があります。

感想

今のところ個人的にはWindowsからDocker環境を整えるメリットはVSCodeのRemote - ContainersプラグインでWindowsからリモートコンテナ開発ができることくらいだと思います。

コマンドラインはSSH接続で直接Linuxから実行すればいいわけですし、GUIツールも特別必要な機能がなければ導入がdockerコマンド2行で済みWebブラウザで操作できるportainerなんかで十分だと思います。

コンテナにSSHサーバーを入れてSSH接続できるようにすればRemote - SSHプラグインで同じことができるのですが、リモート開発したいコンテナが複数に渡ると対象のコンテナ全てにSSHサーバーを入れてポートを割り当てないといけないのでSSHサーバーを都度コンテナに導入する手間とWindowsにDocker環境を整える手間のどっちが少ないかの問題になるんじゃないかと思います。

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

汎用的なLEMP環境を1コマンドで起動するDockerキットを作りました!

作成背景

複数のサービスを取り扱う職場で横断的に開発に参加しており、「〇〇システムの改修が終わったら△△システムの開発を進めてね〜〜」という感じでのオーダーが多い職場でした。サービスによっては複数のシステムが同一言語で複数のメジャーバージョンを使用しており、XAMPP をその度にインストールするなど、ローカルPCの開発環境が重くなったり、環境がPC上で散らかっちゃったりしている状況でした。
さらには複数のシステムを跨いだ動きを考えて開発をするものについては、AWSなどに頼ってインフラを構築しなければならないなと思う状況でした。

AWSを個々の開発環境として使っていたらお金もかかりすぎてしまうため、自分のクライアントPC内で環境が作れないかなといろいろ探していたところ、1年前にDockerと出会い、DockerでWebサービス環境をいい感じに作れるようでしたので、汎用的で職場でも使用しはじめている環境構成を公開したいと思います。

LEMP環境とは
LEMP環境とは、Webアプリケーションを開発するために使用するOS、Webサーバ、データベースサーバ、プログラミング言語を著した言語です。よく使われるWebサーバとして「Apache」が有名で、その頭文字をとって「LAMP」環境と呼ぶことが多く、聞いたことがある方もいるのではないでしょうか?
今回のLEMP環境も同じような考え方で、「E」は「Nginx(読み方:エンジンエックス)」の読みの頭文字の「E」をとっています。
- Linux(OS)
- Nginx(Webサーバ)
- MySQL / MariaDB(データベースサーバ)
- PHP(アプリケーションサーバ(プログラミング言語))

ディレクトリ構成

Dockerを存在を布教するまで知らないエンジニアが多かったこともあり、新米エンジニアなどには「プログラムの改修だけなら、このディレクトリの中身だけをいじれば良い」といえるような、シンプルなディレクトリ構成にするように心がけました。
昨今トレンドになってきている「マイクロサービスアーキテクチャー」の考えを参考にしてNginx、MySQL/MariaDB、PHPをコンテナごとに分割しました。1
全体的なディレクトリ構成は下記のようになります。

ディレクトリ構成
project_root/
 ┣ data/
 ┃  ┣ html
 ┃  ┃  ┗ web-app/
 ┃  ┗ logs
 ┃     ┗ nginx/
 ┣ php-fpm/
 ┃  ┣ conf/
 ┃  ┃  ┗ php.ini
 ┃  ┗ Dockerfile
 ┣ nginx/
 ┃  ┣ conf.d/
 ┃  ┃  ┗ default.conf
 ┃  ┗ Dockerfile
 ┣ mariadb/
 ┃  ┗ docker-entrypoint-initdb.d/
 ┃     ┗ initial.sql
 ┣ phpmyadmin/
 ┃  ┗ config/
 ┃     ┗ config.inc.php
 ┣ env/
 ┃  ┣ .env
 ┃  ┗ その他環境変数のテンプレートファイル
 ┣ docker-compose.yml
 ┗ .gitignore

基本的に、インフラを整える必要のない方には原則「data」ディレクトリ直下のソースコードをいじっていただければ良いようにしています。
ディレクトリごとの

ディレクトリパス 説明
data/html 各コンテナに設置するプログラムソースを格納(執筆時に「data/src」にすればよかったと反省中
data/logs 各コンテナのログファイルを出力
nginx Nginxコンテナで使用する設定ファイルなどを格納しています
mariadb データベースコンテナで使用する設定ファイルなどを格納しています
phpmyadmin Webベースでデータベースを操作するためのツールで、独自の設定をする際に設定ファイルを格納します
env    すべてのコンテナに共通する環境変数と各コンテナごとに挿入する環境変数のファイルを格納します。あくまでもこれは「テンプレート」のため、実際に環境変数を使用する場合は「.env」というディレクトリ名で複製して使うようにします(DockerキットをGitHubに登録するためにわざとしてます)

Docker Compose

docker-compose.yml
version: '3'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    privileged: true
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./data/logs/nginx/nginx-proxy:/var/log/nginx
      - /etc/nginx/vhost.d
      - ./ssl/web:/etc/nginx/certs
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro

  web:
    image: nginx:alpine
    env_file:
      - ./.env/.env
    environment:
      - VIRTUAL_HOST=www.app.local
    depends_on:
      - app
    volumes:
      - ./data/html/app:/var/www/html
      - ./nginx/web.conf:/etc/nginx/conf.d/default.conf
      - ./data/logs/nginx/api:/var/log/nginx

  app:
    build:
      context: .
      dockerfile: ./php-fpm/Dockerfile
    ports:
      - 9000:9000
    env_file:
      - ./.env/.env
    volumes:
      - ./data/html/app:/var/www/html
      - .env/codeigniter4.env:/var/www/html/.env

  db:
    image: mariadb:latest
    ports:
      - 3306:3306
    env_file:
      - ./.env/.env
    volumes:
      - db-data:/var/lib/mysql
      - ./mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    ports:
      - 8080:80
    env_file: ./.env/.env
    environment:
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=password
      - PMA_BLOWFISH_SECRET=
    depends_on:
      - db
    volumes:
      - ./phpmyadmin/config/config.inc.php:/var/www/html/config.inc.php

volumes:
  db-data:

Dockerfileについて

データベースコンテナ(MariaDB/MySQL)

基本的にチューニングを考えた作りにしていなかったので、データベースコンテナのDockerfileは存在しません。
コマンドベースでチューニングを行う場合は、Dockerfileを作成してやりましょう。

Webサーバコンテナ

基本的にチューニングを考えた作りにしていなかったので、データベースコンテナのDockerfileは存在しません。
コマンドベースでチューニングを行う場合は、Dockerfileを作成してやりましょう。
また、nginx/conf.dディレクトリ内には、コンテナ名ごとにnginxのconfファイルを格納しておくと、修正時にわかりやすくなります。
複数のWebサーバを動かす必要が出てきたときは、そのコンテナごとにconfファイルを/docker-compose.ymlvolumes:内に設定すれば、コンテナを切り分けて入れることも可能です。

/php-fpm/Dockerfile
FROM php:fpm-alpine
RUN apk upgrade && \
    apk update && \
    apk add --update --no-cache \
      oniguruma-dev \
      icu-dev && \
    apk add \
      vim \
      git \
      composer && \
    docker-php-ext-install -j$(nproc) \
      intl \
      pdo_mysql \
      mysqli \
      mbstring

WORKDIR /var/www/html

アプリケーションコンテナ

PHP7.4以降では「oniguruma」という正規表現のモジュールがPHPに標準ライブラリとして搭載していないようです。(※ ドツボにはまる重要ポイントです!)
composerは、開発時は基本的に「ホスト側のcomposer」を利用してライブラリをインストールしていたので、コンテナ内では気持ち程度に入れております。

/php-fpm/Dockerfile
FROM php:fpm-alpine
RUN apk upgrade && \
    apk update && \
    apk add --update --no-cache \
      oniguruma-dev \ # PHPバージョンが`<7.4`であれば、この行は不要です!
      icu-dev && \
    apk add \
      vim \
      git \
      composer && \
    docker-php-ext-install -j$(nproc) \
      intl \
      pdo_mysql \
      mysqli \
      mbstring

WORKDIR /var/www/html

最後に

今回は、Dockerを使った簡単で汎用的な開発環境構築キットの作り方を公開させていただきました。
実際のソースコードも公開させていただきますので、よかったら使用してみてください。

yusuke-shina/apache-httpd-docker-kit
*詳しいセットアップの仕方などをREADME.mdに記載できていませんが、記載できる隙が作れたら、更新していきます!

今回は、簡単で汎用的な開発環境構築キットという名目だったので(Dockerでのネットワーク構築については勉強中の身)ネットワーク周りの設定をDocker Composeを使って反映できていませんので、その辺とかも出来次第更新できたらと考えております。

具体的な説明があまりできていない雑な記事ではありますが、Dockerにこれから挑戦される方、開発環境をDocker化したいという方々のさわりとして、参考にしていただければ幸いです。
また、お詳しい方はコメント欄に認識が異なる部分がありましたらご指摘いただけると幸いです。


  1. 本当にこのやり方がマイクロサービスアーキテクチャの考え方に則しているかが怖いですが…… 

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

汎用的なLEMP環境をdocker-compose up -dコマンド一発で起動するDockerキットを作りました!

作成背景

複数のサービスを取り扱う職場で横断的に開発に参加しており、「〇〇システムの改修が終わったら△△システムの開発を進めてね〜〜」という感じでのオーダーが多い職場でした。サービスによっては複数のシステムが同一言語で複数のメジャーバージョンを使用しており、XAMPP をその度にインストールするなど、ローカルPCの開発環境が重くなったり、環境がPC上で散らかっちゃったりしている状況でした。
さらには複数のシステムを跨いだ動きを考えて開発をするものについては、AWSなどに頼ってインフラを構築しなければならないなと思う状況でした。

AWSを個々の開発環境として使っていたらお金もかかりすぎてしまうため、自分のクライアントPC内で環境が作れないかなといろいろ探していたところ、1年前にDockerと出会い、DockerでWebサービス環境をいい感じに作れるようでしたので、汎用的で職場でも使用しはじめている環境構成を公開したいと思います。

LEMP環境とは
LEMP環境とは、Webアプリケーションを開発するために使用するOS、Webサーバ、データベースサーバ、プログラミング言語を著した言語です。よく使われるWebサーバとして「Apache」が有名で、その頭文字をとって「LAMP」環境と呼ぶことが多く、聞いたことがある方もいるのではないでしょうか?
今回のLEMP環境も同じような考え方で、「E」は「Nginx(読み方:エンジンエックス)」の読みの頭文字の「E」をとっています。
- Linux(OS)
- Nginx(Webサーバ)
- MySQL / MariaDB(データベースサーバ)
- PHP(アプリケーションサーバ(プログラミング言語))

コンテナイメージの選定で必要なイメージなど

jwilder/nginx-proxy

複数のコンテナで同一のポートで通信したいときに入れておくと良いリバースプロキシサーバのコンテナイメージです。
1つのサービスで複数のドメインを同時に利用する場合があることから、上記のコンテナを立てておきます。

Alpine Linux

軽量なLinux OSで、よく使用しているUbuntuの1/7、CentOSでは1/40の容量で構成されているようです。

参考:@ryuichi1208さん「超軽量なAlpine Linuxについて調べた」

CentOS 約4GB
Ubuntu 約700MB
Alpine 約100MB

この汎用LEMP開発キットでは、コンテナ生成の際に時間のロスを減らすために、シンプルで軽量なOSであるAlpine Linuxのイメージをふんだんに採用しています。

ディレクトリ構成

Dockerを存在を布教するまで知らないエンジニアが多かったこともあり、新米エンジニアなどには「プログラムの改修だけなら、このディレクトリの中身だけをいじれば良い」といえるような、シンプルなディレクトリ構成にするように心がけました。
昨今トレンドになってきている「マイクロサービスアーキテクチャー」の考えを参考にしてNginx、MySQL/MariaDB、PHPをコンテナごとに分割しました。1
全体的なディレクトリ構成は下記のようになります。

ディレクトリ構成
project_root/
 ┣ data/
 ┃  ┣ html
 ┃  ┃  ┗ web-app/
 ┃  ┗ logs
 ┃     ┗ nginx/
 ┣ php-fpm/
 ┃  ┣ conf/
 ┃  ┃  ┗ php.ini
 ┃  ┗ Dockerfile
 ┣ nginx/
 ┃  ┣ conf.d/
 ┃  ┃  ┗ default.conf
 ┃  ┗ Dockerfile
 ┣ mariadb/
 ┃  ┗ docker-entrypoint-initdb.d/
 ┃     ┗ initial.sql
 ┣ phpmyadmin/
 ┃  ┗ config/
 ┃     ┗ config.inc.php
 ┣ env/
 ┃  ┣ .env
 ┃  ┗ その他環境変数のテンプレートファイル
 ┣ docker-compose.yml
 ┗ .gitignore

基本的に、インフラを整える必要のない方には原則「data」ディレクトリ直下のソースコードをいじっていただければ良いようにしています。

ディレクトリパス 説明
data/html 各コンテナに設置するプログラムソースを格納(執筆時に「data/src」にすればよかったと反省中
data/logs 各コンテナのログファイルを出力
nginx Nginxコンテナで使用する設定ファイルなどを格納しています
mariadb データベースコンテナで使用する設定ファイルなどを格納しています
phpmyadmin Webベースでデータベースを操作するためのツールで、独自の設定をする際に設定ファイルを格納します
env    すべてのコンテナに共通する環境変数と各コンテナごとに挿入する環境変数のファイルを格納します。あくまでもこれは「テンプレート」のため、実際に環境変数を使用する場合は「.env」というディレクトリ名で複製して使うようにします(DockerキットをGitHubに登録するためにわざとしてます)

Docker Compose

LEMP環境のコンテナを同時に生成できるように設定情報をdocker-compose.ymlに記載をしていきます。

docker-compose.yml
version: '3'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    privileged: true
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./data/logs/nginx/nginx-proxy:/var/log/nginx
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro

  web:
    image: nginx:alpine
    env_file:
      - ./.env/.env
    environment:
      - VIRTUAL_HOST=www.app.local
    depends_on:
      - app
    volumes:
      - ./data/html/app:/var/www/html
      - ./nginx/web.conf:/etc/nginx/conf.d/default.conf
      - ./data/logs/nginx/api:/var/log/nginx

  app:
    build:
      context: .
      dockerfile: ./php-fpm/Dockerfile
    ports:
      - 9000:9000
    env_file:
      - ./.env/.env
    volumes:
      - ./data/html/app:/var/www/html
      - .env/app.env:/var/www/html/.env # 例えば、app.envという名前でアプリケーションの.envファイルとして、アプリケーション内のライブラリphpdotenvを用いて環境変数を読み取らせるようにする

  db:
    image: mariadb:latest
    ports:
      - 3306:3306
    env_file:
      - ./.env/.env
    volumes:
      - db-data:/var/lib/mysql
      - ./mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    ports:
      - 8080:80
    env_file: ./.env/.env
    environment:
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=password
      - PMA_BLOWFISH_SECRET=
    depends_on:
      - db
    volumes:
      - ./phpmyadmin/config/config.inc.php:/var/www/html/config.inc.php

volumes:
  db-data:

Dockerfileについて

データベースコンテナ(MariaDB/MySQL)

基本的にチューニングを考えた作りにしていなかったので、データベースコンテナのDockerfileは存在しません。
コマンドベースでチューニングを行う場合は、Dockerfileを作成してやりましょう。

Webサーバコンテナ

基本的にチューニングを考えた作りにしていなかったので、データベースコンテナのDockerfileは存在しません。
コマンドベースでチューニングを行う場合は、Dockerfileを作成してやりましょう。
また、nginx/conf.dディレクトリ内には、コンテナ名ごとにnginxのconfファイルを格納しておくと、修正時にわかりやすくなります。
複数のWebサーバを動かす必要が出てきたときは、そのコンテナごとにconfファイルを/docker-compose.ymlvolumes:内に設定すれば、コンテナを切り分けて入れることも可能です。

アプリケーションコンテナ

PHP7.4以降では「oniguruma」という正規表現のモジュールがPHPに標準ライブラリとして搭載していないようです。(※ ドツボにはまる重要ポイントです!)
composerは、開発時は基本的に「ホスト側のcomposer」を利用してライブラリをインストールしていたので、コンテナ内では気持ち程度に入れております。

/php-fpm/Dockerfile
FROM php:fpm-alpine
RUN apk upgrade && \
    apk update && \
    apk add --update --no-cache \
      oniguruma-dev \ # PHPバージョンが`<7.4`であれば、この行は不要です!
      icu-dev && \
    apk add \
      vim \
      git \
      composer && \
    docker-php-ext-install -j$(nproc) \
      intl \
      pdo_mysql \
      mysqli \
      mbstring

WORKDIR /var/www/html

使用コマンド

使用コマンドは下記の2つだけです。

バックグラウンドでdocker-compose.ymmlファイルに記載のあるdockerコンテナを一括起動
docker-compose up -d
バックグラウンドでdocker-compose.ymmlファイルに記載のあるdockerコンテナを一括シャットダウン
docker-compose down

また、コンテナがうまく立ち上がっているかの確認をするときのために、下記の2つのコマンドも覚えておくと便利です。

コンテナがうまく立ち上がっているかを確認する
docker-compose ps
コンテナを特定してコンテナを立ち上げる際のログを確認する
docker-compose logs | grep <CONTAINER_NAME>

最後に

今回は、Dockerを使った簡単で汎用的な開発環境構築キットの作り方を公開させていただきました。
実際のソースコードも公開させていただきますので、よかったら使用してみてください。

yusuke-shina/apache-httpd-docker-kit
*詳しいセットアップの仕方などをREADME.mdに記載できていませんが、記載できる隙が作れたら、更新していきます!

今回は、簡単で汎用的な開発環境構築キットという名目だったので(Dockerでのネットワーク構築については勉強中の身)ネットワーク周りの設定をDocker Composeを使って反映できていませんので、その辺とかも出来次第更新できたらと考えております。

具体的な説明があまりできていない雑な記事ではありますが、Dockerにこれから挑戦される方、開発環境をDocker化したいという方々のさわりとして、参考にしていただければ幸いです。
また、お詳しい方はコメント欄に認識が異なる部分がありましたらご指摘いただけると幸いです。


  1. 本当にこのやり方がマイクロサービスアーキテクチャの考え方に則しているかが怖いですが…… 

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