20200818のdockerに関する記事は13件です。

Dockerのイメージを全部消す(クリーンアップ)

Dockerのイメージを全部消す(クリーンアップ)

稼働中のコンテナを全て止める。

$ docker kill `docker ps -q`
d949279b7e8b
90f0009df4dc
fc6cf5b5a26b

全てのコンテナを削除する。

$ docker rm `docker ps -aq`
60f91cccb7dd
d949279b7e8b
90f0009df4dc
fc6cf5b5a26b

全てのイメージを削除する。

$ docker rmi `docker images -q`
Untagged: nginx:latest
Untagged: nginx@sha256:b0ad43f0ad430ad43ee5edbc0eff...
Deleted: sha256:4bb46517cac397bdb0bab6eba09b0e1f8e9...
Deleted: sha256:80b21afd8140706d5fe3b7106ae6147e192...
Deleted: sha256:0f04ae71e99f5ef9021b92f76bac3979e25...
Deleted: sha256:9a14852344d88a1fdf8297914729834521e...
Deleted: sha256:74299126f8099031c5bbd4774147f4ab6b0...
Untagged: wordpress:latest
Untagged: wordpress@sha256:6da8f886b20632dd05eeb246...
Deleted: sha256:f1da35a7ddca022240b522847aa00229a53...
Deleted: sha256:2575d97839d38f8e5d03bff9faa60e2b6b9...
Deleted: sha256:02b438dc689e82d43a5020697c9fcf69ab1...
Deleted: sha256:6ba52464be861d5820d3993f1679fb19598...
Deleted: sha256:c009eaa948f2fdeac83c727e23ecf54e3ce...
Deleted: sha256:c1dcd220a514e0a20c296ac98504ae1a060...
Deleted: sha256:4ea2c0ce663f0f818e515817b07f4c9a874...
Deleted: sha256:87c45811775aae1757da1a94f55ecbbbdeb...
Deleted: sha256:f6e183c191d75a55ea7b0695c32ba9bd4a6...
Deleted: sha256:ff09d507a3ca7496a332579227770965c61...
Deleted: sha256:ffa2c187679ddbeeda9b9d41725fa4916f2...
Deleted: sha256:eaae8b52ab6afc664a6584033bd8942c7a9...
Deleted: sha256:56a340d84f17f5b4e83bd02ffd40a3b1273...
Deleted: sha256:f8899bfcfa880bd6caa5078c27b488a37f6...
Deleted: sha256:08b50110935f318104dd652795f0b0a2c6d...
Deleted: sha256:3bcc29238c6f1ce1602b88b2317fd742922...
Deleted: sha256:e7854f919e1ba15b6ac0b0e70cd2cb1eac7...
Deleted: sha256:45c01c7d544fd67d36753507065e5458be1...
Deleted: sha256:8e311722d5028e3cb61f5dea8786ed5fbc5...
Deleted: sha256:2f245d38723aa315787ea341d92c1abbccc...
Untagged: mysql:5.7
Untagged: mysql@sha256:da58f943b4721d46e87d5de208dc...
Deleted: sha256:718a6da099d82183c064a964523c0deca80...
Deleted: sha256:058d93ef2bfb943ba6a19d8b679c702be96...
Deleted: sha256:7bca77783fcf15499a0386127dd7d5c6793...
Deleted: sha256:183d05512fa88dfa8c17abb9b6f09a79922...
Deleted: sha256:1658012fa88dfa5124c17a136fdeec1782b...
Deleted: sha256:904bdc2d0b81c112fa88dfa7ac17a71d215...
Deleted: sha256:d26f7649f78cf789267fbbca8aeb234932e...
Deleted: sha256:7fcf7796e23ea5b42eb3bbd5bec160ba5f5...
Deleted: sha256:826130797a5760bcd2bb19a6c6d92b5f486...
Deleted: sha256:53e0181c63e41fb85bce681ec8aadfa323c...
Deleted: sha256:d6854b83e83d7eb48fb0ef778c58a8b839a...
Deleted: sha256:d0f104dc0a1f9c744b65b23b3fd4d4d3236...
Untagged: hello-world:latest
Untagged: hello-world@sha256:7f0a9f93b4aa3022c3449b...
Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb...
Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc97...

確認

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

すっきり

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

docker-composeでのプロキシ設定を.envファイルにまとめる

docker-composeでのプロキシ設定を.envファイルにまとめたリポジトリを作りました。

SolKul/docker-compose-proxy

dockerで必要になるプロキシ設定は主に3つに分かれていて、

  • ホストのプロキシ設定
  • イメージのビルド中のプロキシ設定
  • 立ち上がったコンテナのプロキシ設定

の3つあるとおもいます。

このリポジトリを使い、.envファイルの中のプロキシ設定を自分に合わせて変えて、docker-compose upをすれば、

  • イメージのビルド中のプロキシ設定
  • 立ち上がったコンテナのプロキシ設定

が自動でなされているはずです。

解説

前提知識

前提知識としてそもそもプロキシサーバの概要や役割、
Linuxの環境変数、プロキシの設定方法、
Dockerfileの仕組みについて知っておいたほうがいいでしょう。

Docker入門(第四回)~Dockerfileについて~ | さくらのナレッジ

最悪、リポジトリをコピペしても動くとは思いますが、こうした知識がないとトラブルやエラーが起きた場合に対処できなく積んでしまうと思います。

Linuxの各種コマンドでプロキシを使うには

検索するといろんな設定ファイルをいじらなければいけないように感じますが、
基本的に以下の環境変数を設定していればプロキシを使えます。

HTTP_PROXY
http_proxy
HTTPS_PROXY
https_proxy
FTP_PROXY
ftp_proxy
NO_PROXY
no_proxy

NO_PROXYno_proxy以外の環境変数にプロキシの
http://<user>:<password>@<your-proxy>:<proxy-port>/
(認証付きでない場合は<user>:<password>@を外す。)
を設定すれば大丈夫です。

Dockerfile、docker-composeでのプロキシ設定

Dockerfile、docker-composeでのプロキシ設定についてはこの記事が詳しいです。

防火壁の中の Docker

またこの記事を理解するにはDockerfileのARGやENVの知識、docker-compose.ymlenvironment:についての知識を知っておいたほうがいいでしょう。
ARG | Dockerfile reference
Dockerドキュメント | compose中の環境変数

まとめると、Dockerfileのビルド変数(build-arg)にプロキシの設定を渡すことで、イメージのビルド中のプロキシ設定が設定され、docker-compose.ymlenvironment:を設定することで、立ち上がったコンテナのプロキシ設定が設定できます。

プロキシに関するビルド変数は予め宣言されている(predefined)なので、
Dockerfile内でARG HTTP_PROXYとする必要はありません。

(Predefined ARGs参照)

.envファイルについて

そして更に、このリポジトリではdocker-compose中のデフォルトの環境変数を設定するために、.envファイルを使っています。

docker-compose中で環境変数の使い方や.envファイルについてはこの記事や公式リファレンスを参考にしてください

docker-composeのenv_fileと.envファイルの違い
Dockerドキュメント | compose中の環境変数

.envファイルを使うことで、docker-compose upした際に、以下のdocker-compose.ymlの$から始まる環境変数に.envファイルに記したプロキシ設定が代入されます。
また、そのホストに別のプロキシが設定されていれば、そのホストのプロキシ設定が代入され、.envファイルの値は使われません。

docker-compose.yml
version: '3'

services:
  test:
    build:
      context: .
      # ビルド中にプロキシを使うための設定
      args:
        - HTTP_PROXY=$HTTP_PROXY
        - http_proxy=$http_proxy
        - HTTPS_PROXY=$HTTPS_PROXY
        - https_proxy=$https_proxy
        - FTP_PROXY=$FTP_PROXY
        - ftp_proxy=$ftp_proxy
        - NO_PROXY=$NO_PROXY
        - no_proxy=$no_proxy
    # 立ち上がったコンテナでプロキシを使うための設定
    environment:
      - HTTP_PROXY=$HTTP_PROXY
      - http_proxy=$http_proxy
      - HTTPS_PROXY=$HTTPS_PROXY
      - https_proxy=$https_proxy
      - FTP_PROXY=$FTP_PROXY
      - ftp_proxy=$ftp_proxy
      - NO_PROXY=$NO_PROXY
      - no_proxy=$no_proxy
    # 検証のため、標準入出力をオン
    tty: true
    stdin_open: true
.env
HTTP_PROXY=proxy_url:port
http_proxy=proxy_url:port
HTTPS_PROXY=proxy_url:port
https_proxy=proxy_url:port
FTP_PROXY=proxy_url:port
ftp_proxy=proxy_url:port
NO_PROXY=no_proxy_url
no_proxy=no_proxy_url

メリット

このようにするメリットとしては、

  • プロキシ設定がimageに焼き付かない
  • 別の人に使って貰おうとdocker-compose.ymlを配布したいと思ったが、プロキシ設定に認証情報が入っているため配布したくない場合でも、この方法を使えば、docker-compose.ymlにはプロキシ設定が記されておらず、.envファイルの中身だけ変えればいいので、配布しやすい

などがあります。

注意

.envファイルはdocker-composeコマンドを実行したときのディレクトリにある必要があります(ワーキングディレクトリ)
他の場所では認識しません。

例えばVSCodeのRemote Containerではdocker-composeをVSCodeのルートディレクトリで実行しているので
.envファイルは今VSCodeが開いているルートディレクトリに置かないと、正常に動作しません。

参考:Qiitaのdockerプロキシ記事まとめ

Linux環境の場合:

この記事でほぼ網羅されていますが、
Windowsの場合、Docker Desktop for Windowsで追加の設定をしないとdocker pullができません
次の記事を見て設定してください。

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

docker-composeでのプロキシ設定を一つのファイルにまとめる

docker-composeでのプロキシ設定を一つのファイル(.envというファイル)にまとめたリポジトリを作りました。

SolKul/docker-compose-proxy

メリット

このようにするメリットとしては、

  • プロキシ設定がimageに焼き付かない
  • 別の人に使って貰おうとdocker-compose.ymlを配布したいと思ったが、プロキシ設定に認証情報が入っているため配布したくない場合でも、この方法を使えば、docker-compose.ymlにはプロキシ設定が記されておらず、.envファイルの中身だけ変えればいいので、配布しやすい

などがあります。

解説

前提知識

前提知識としてそもそもプロキシサーバの概要や役割、
Linuxの環境変数、プロキシの設定方法、
Dockerfileの仕組みについて知っておいたほうがいいでしょう。

Docker入門(第四回)~Dockerfileについて~ | さくらのナレッジ

最悪、リポジトリをコピペしても動くとは思いますが、こうした知識がないとトラブルやエラーが起きた場合に対処できなく積んでしまうと思います。

Linuxの各種コマンドでプロキシを使うには

プロキシについて調べていくといろんな設定ファイルをいじらなければいけないように感じますが、
基本的に以下の環境変数を設定していればプロキシを使えます。

HTTP_PROXY
http_proxy
HTTPS_PROXY
https_proxy
FTP_PROXY
ftp_proxy
NO_PROXY
no_proxy

NO_PROXYno_proxy以外の環境変数にプロキシの
http://<user>:<password>@<your-proxy>:<proxy-port>/
(認証付きでない場合は<user>:<password>@を外す。)
を設定すれば大丈夫です。

Dockerfile、docker-composeでのプロキシ設定

Dockerfile、docker-composeでのプロキシ設定についてはこの記事が詳しいです。

防火壁の中の Docker

またこの記事を理解するにはDockerfileのARGやENVの知識、docker-compose.ymlenvironment:についての知識を知っておいたほうがいいでしょう。
ARG | Dockerfile reference
Dockerドキュメント | compose中の環境変数

まとめると、Dockerfileのビルド変数(build-arg)にプロキシの設定を渡すことで、イメージのビルド中のプロキシ設定が設定され、docker-compose.ymlenvironment:を設定することで、立ち上がったコンテナのプロキシ設定が設定できます。

プロキシに関するビルド変数は予め宣言されている(predefined)なので、
Dockerfile内でARG HTTP_PROXYとする必要はありません。

(Predefined ARGs参照)

.envファイルについて

そして更に、このリポジトリではdocker-compose中のデフォルトの環境変数を設定するために、.envファイルを使っています。

docker-compose中で環境変数の使い方や.envファイルについてはこの記事や公式リファレンスを参考にしてください

docker-composeのenv_fileと.envファイルの違い
Dockerドキュメント | compose中の環境変数

.envファイルを使うことで、docker-compose upした際に、以下のdocker-compose.ymlの$から始まる環境変数に.envファイルに記したプロキシ設定が代入されます。
また、そのホストに別のプロキシが設定されていれば、そのホストのプロキシ設定が代入され、.envファイルの値は使われません。

docker-compose.yml
version: '3'

services:
  test:
    build:
      context: .
      # ビルド中にプロキシを使うための設定
      args:
        - HTTP_PROXY=$HTTP_PROXY
        - http_proxy=$http_proxy
        - HTTPS_PROXY=$HTTPS_PROXY
        - https_proxy=$https_proxy
        - FTP_PROXY=$FTP_PROXY
        - ftp_proxy=$ftp_proxy
        - NO_PROXY=$NO_PROXY
        - no_proxy=$no_proxy
    # 立ち上がったコンテナでプロキシを使うための設定
    environment:
      - HTTP_PROXY=$HTTP_PROXY
      - http_proxy=$http_proxy
      - HTTPS_PROXY=$HTTPS_PROXY
      - https_proxy=$https_proxy
      - FTP_PROXY=$FTP_PROXY
      - ftp_proxy=$ftp_proxy
      - NO_PROXY=$NO_PROXY
      - no_proxy=$no_proxy
    # 検証のため、標準入出力をオン
    tty: true
    stdin_open: true
.env
HTTP_PROXY=proxy_url:port
http_proxy=proxy_url:port
HTTPS_PROXY=proxy_url:port
https_proxy=proxy_url:port
FTP_PROXY=proxy_url:port
ftp_proxy=proxy_url:port
NO_PROXY=no_proxy_url
no_proxy=no_proxy_url

注意

.envファイルはdocker-composeコマンドを実行したときのディレクトリにある必要があります(ワーキングディレクトリ)
他の場所では認識しません。

例えばVSCodeのRemote Containerではdocker-composeをVSCodeのルートディレクトリで実行しているので
.envファイルは今VSCodeが開いているルートディレクトリに置かないと、正常に動作しません。

参考:Qiitaのdockerプロキシ記事まとめ

Linux環境の場合:

この記事でほぼ網羅されていますが、
Windowsの場合、Docker Desktop for Windowsで追加の設定をしないとdocker pullができません
次の記事を見て設定してください。

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

Docker で停止中のコンテナを全部動かす

Docker で停止中のコンテナを全部動かす

$ docker start `docker ps -aq`
60f91cccb7dd
Error response from daemon: Cannot link to a non running container: /xxx-mysql AS /xxx-wordpress/mysql
90f0009df4dc
fc6cf5b5a26b
Error: failed to start containers: d949279b7e8b

もう一回同じコマンドを叩く。1

$ docker start `docker ps -aq`
60f91cccb7dd
d949279b7e8b
90f0009df4dc
fc6cf5b5a26b

はい、全部動いた。

最低二回コマンドを叩く。


  1. xxx-mysqlが先に可動していないとxxx-wordpressが可動できないが、先にxxx-wordpressを稼働させようとしたためエラーとなった。 

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

Docker で稼働中のコンテナを全部止める

Docker で稼働中のコンテナを全部止める

$ docker kill `docker ps -q`
d949279b7e8b
90f0009df4dc
fc6cf5b5a26b

稼働中だった3つのコンテナが全て停できた。

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

Nuxt.js + Socket.ioでルームチャットアプリを作る ~ サーバーフレームワーク選べなくなっててつまずいた夏

はじめに

Nuxt + Express + socket.ioでチャットみたいなリアルタイムWebアプリが作れるよ、という記事はいっぱいあったのですが、create-nuxt-appさんが3.Xにアップデートしてサーバーサイドフレームワーク(つまりExpress)を選択できなく(しなくてよく)なり途方にくれていたので記事に残します。

create-nuxt-appのダウングレードの方法もありますが、なにやら想いが込められているようなので。

前提

  • create-nuxt-app: v3.2.0
  • Nuxt on Docker(ただの趣味なのでDocker使わなくてもいい内容です)

最終形態

最終形態はこちらです。
test.gif

ソースコードはこちらです。 => at946/demo_nuxt-socket.io_chat

Nuxtアプリ作成

まずcreate-nuxt-appでNuxtアプリを作ります。(アプリ名はchatにしました)

$ docker run --rm -it -v `pwd`:/app -w /app node yarn create nuxt-app chat

Project name: chat
Programming language: JavaScript
Package manager: Yarn
UI framework: Bulma
Nuxt.js modules: None
Linting tools: None
Testing framework: None
Rendering mode: Universal (SSR / SSG)
Deployment target: Server (Node.js hosting)
Development tools: jsconfig.json

これでカレントディレクトリにchat/ディレクトリができます。ここがアプリ本体なのでchat/配下をホームディレクトリとして活動していきます。

$ cd chat

Docker系を準備

NuxtアプリをDockerで動かすためにDockerfiledocker-compose.ymlを準備します。

Dockerfile
FROM node:14.8

ENV HOME=/app     \
    LANG=C.UTF-8  \
    TZ=Asia/Tokyo \
    HOST=0.0.0.0

WORKDIR ${HOME}
COPY package.json ${HOME}
COPY yarn.lock ${HOME}

RUN apt -y update && \
    apt -y upgrade && \
    yarn install

COPY . ${HOME}
EXPOSE 3000 3001
CMD ["yarn", "run", "dev"]
docker-compose.yml
version: "3"

services:
  nuxt:
    build: .
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - 3000:3000
      - 3001:3001

3000番ポートはNuxtアプリ、3001番ポートはSocket.ioのサーバーサイド用のポートとして使います。

Dockerイメージをビルドしてコンテナを立ち上げます。

$ docker-compose build
$ docker-compose up -d

http://localhost:3000にアクセスしてNuxtアプリが立ち上がればここまではOKです。

image.png

$ docker-compose down

socket.ioでチャット機能を作る

socket.ioのインストール

まずはsocket.ioをインストールします。サーバーサイドのライブラリのsocket.ioとクライアントサイドのライブラリのsocket.io-clientが必要です。

$ docker-compose run --rm nuxt yarn add socket.io socket.io-client

サーバーサイドをコーディング

create-nuxt-app@3.Xで作ったアプリではserver/ディレクトリがないですね。その代わりにserverMiddleware使うといいらしいっす。これは外部APIとかと簡単に連携できるようにってやつらしいです。

まずnuxt.config.jsにserverMiddlewareの設定を追加します。

nuxt.config.js
export default {
  ...
  serverMiddleware: {
    'api': '~/api'
  },
  ...
}

api/ディレクトリ配下にサーバーサイドのコードを作ります。

$ mkdir api
$ touch api/index.js
api/index.js
const app = require('express')()
const server = require('http').createServer(app)
const io = require('socket.io')(server)

io.on('connection', socket => {
  console.log(`socket_id: ${socket.id} is connected.`)

  // send-msgイベントを受け取ったらブロードキャストする
  socket.on('send-msg', msg => {
    socket.emit('new-msg', msg)
    console.log(`receive message: ${JSON.stringify(msg)}`)
  })
})

server.listen(3001)

シンプルにsend-msgイベントをクライアントから受け取ったらsocket.emitnew-msgイベントをブロードキャストします。

なのでクライアントはチャットを送信するときにsend-msgイベントを送ればよくて、サーバーサイドからnew-msgイベントを受け取ったらmsgの内容を表示すればいい、ってことになります。

クライアントサイドをコーディング

pages/chat/index.vueファイルを作成・編集します。

$ mkdir pages/chat
$ touch pages/chat/index.vue
pages/chat/index.vue
<template>
  <section class="section">
    <div class="field">
      <div class="control">
        <input class="input" type="text" v-model="msg" @keypress.enter.exact="sendMessage">
      </div>
    </div>
    <article class="media" v-for="(msg, index) in msgs" :key="index">
      <div class="media-content">
        <div class="content">
          <p>
            <strong>{{ msg.name }}</strong>
            <br>
            {{ msg.text }}
          </p>
        </div>
      </div>
    </article>
  </section>
</template>

<script>
import io from 'socket.io-client'

export default {
  data() {
    return {
      msg: '',
      msgs: [],
      socket: ''
    }
  },
  mounted() {
    this.socket = io('http://localhost:3001')
    this.socket.on('new-msg', msg => {
      this.msgs.push(msg)
    })
  },
  methods: {
    sendMessage() {
      this.msg = this.msg.trim()
      if (this.msg) {
        const message = {
          name: this.socket.id,
          text: this.msg,
        }
        // イベント元はブロードキャストを受けないので自分でmessageを追加する
        this.msgs.push(message)
        // send-msgイベントでmessageをサーバーサイドに投げる
        this.socket.emit('send-msg', message)
        this.msg = ''
      }
    }
  }
}
</script>

デモ1

ここまでできたら一度Dockerイメージをビルドして起動してみましょう。

$ docker-compose build
$ docker-compose up -d

複数タブでhttp://localhost:3000にアクセスします。片方でメッセージを送信すると、もう片方にも表示されます!!

test.gif

いえーい。

$ docker-compose down

ルームをコーディング

ここまででSocket.ioを使ってリアルタイムにチャットすることができるようになりましたが、今のままでは誰でもこのサイトにアクセスしたらチャットが流れてくるようになっちゃいます。
特定の人たちとだけやり取りをしたい場合はSocket.ioのルームを使います。

image.png

出典:Rooms | Socket.IO

今回はhttp://localhost:3000/chat/1とかhttp://localhost:3000/chat/2とか、パスパラメーターでルームを分けて、ルーム内だけでチャットできるようにしてみます。

処理の流れは

  1. clientからserverにルーム参加イベントを送る
  2. serverがclient(socket)をルームに登録しておく
  3. clientからserverにルームにsend-msgイベントを送る
  4. serverがルームの全てのsocketにmsgをブロードキャストする

です。

サーバーサイドをコーディング

サーバーサイドでは、「clientからのルーム参加イベントを受けとり、ルームに参加させる」機能の追加と、「send-msgイベントでルームIDを受け取り、そのルームに対してmsgをブロードキャストする」機能の改修を行います。

api/index.js
  io.on('connection', socket => {
    console.log(`socket_id: ${socket.id} is connected.`)
+
+   // joinイベントを受け取ったらルームに登録する
+   socket.on('join', roomId => {
+     socket.join(roomId)
+     console.log(`socket_id: ${socket.id} joined in room ${roomId}`)
+   }) 
+
-   // send-msgイベントを受け取ったらブロードキャストする
-   socket.on('send-msg', msg => {
-     socket.broadcast.emit('new-msg', msg)
+   // send-msgイベントを受け取ったら指定のルームにブロードキャストする
+   socket.on('send-msg', (msg, roomId) => {
+     socket.to(roomId).emit('new-msg', msg)
      console.log(`receive message: ${JSON.stringify(msg)}`)
    })
  })

server.listen(3001)

クライアントからroomIdを受け取って処理してます。

socket.joinはルーム登録の処理です。引数にルームの名前を渡すだけの簡単メソッドですが、今回はクライアントから受け取るパスパラメーターの値をルーム名にします。

ルームへのブロードキャストはsocket.to(room name).emit(...)でできます。これも先程と大きくは変わらないので理解しやすいですね。

クライアントサイドをコーディング

クライアントサイドでは、「Socketコネクションと同時にルームに参加する」機能の追加と「メッセージ送信時にroomIdを送る」機能の改修をします。

まず、roomIdとなるパスパラメーターを受け取るためにファイル名を変更してからファイルを編集していきます。

$ mv pages/chat/index.vue pages/chat/_id.vue

これでthis.$route.params.idhttp://localhost:3000/chat/xxxxxx部分を取得することができます。

pages/chat/_id.vue
  <script>
  import io from 'socket.io-client'

  export default {
    data() {
      return {
        msg: '',
        msgs: [],
        socket: ''
      }
    },
    mounted() {
      this.socket = io('http://localhost:3001')
+     this.socket.emit('join', this.$route.params.id)
      this.socket.on('new-msg', msg => {
        this.msgs.push(msg)
      })
    },
    methods: {
      sendMessage() {
        this.msg = this.msg.trim()
        if (this.msg) {
          const message = {
            name: this.socket.id,
            text: this.msg,
          }
          this.msgs.push(message)
          // send-msgイベントでmessageをサーバーサイドに投げる
-         this.socket.emit('send-msg', message)
+         this.socket.emit('send-msg', message, this.$route.params.id)
          this.msg = ''
        }
      }
    }
  }
  </script>

以上です!

デモ2

デモしてみましょう。
上の2画面がhttp://localhost:3000/chat/1に、下の2画面がhttp://localhost:3000/chat/2にアクセスしています。
それぞれチャットしたい相手とだけチャットできていますね!

test.gif

まとめ

この記事ではcreate-nuxt-appのバージョンアップで過去記事の通りにはできなかったNuxt+Socket.ioのリアルタイムチャットをlocalで動くまで頑張ってみました。
普通に数日間つまづいてたので誰かの助けになれば幸いです!
また、NuxtやSocket.ioについてはBeginnerなので、こうしたほうがよりよいよ!などアドバイスいただけると嬉しいです。

Reference

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

nginx image に mysql を入れる際の注意点

対象

docker 環境で nginx の公式image に mysql クライアントをインストールする際に詰まった人 :rolling_eyes:

調査&解決

上記のリンクから確認できるが、 公式image は FROM debian:buster-slim を使っている。
ベースイメージが debianであることがわかったので https://hub.docker.com/_/debian を見ると
buster-slim は debian 10系で有ることがわかった。

buster系では mysql-clientが存在しないので default-mysql-server を使用してinstallする

$ sudo apt-get update
$ sudo apt-get install default-mysql-server

これで入る。

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

【備忘】Docker Container の MySQL Server にアクセスする方法メモ

Dockerコンテナ上に立てたMySQL Server にアクセスする際に意外と手間取ったのでメモ。

前提

OS: macOS 10.14.6
docker desktop: v2.3.0.3
Dockerイメージ: https://hub.docker.com/r/mysql/mysql-server

手順

コンテナ起動してアクセス。ポートマッピングを忘れない!

$ docker run --name=mysql-develop \
             -p 3306:3306 \
             -d \
             mysql/mysql-server
$ docker exec -it mysql-develop bash

設定ファイル(/etc/my.cnf)に以下を追記。
docker run で起動している場合、ホストのIPは127.10.0.1です。

my.cnf
bind-address = 127.10.0.1

ルートユーザでコンテナ内からサーバーにアクセス。
パスワードはコンテナ作成時に自動でせいせされるので、ログから確認する。

$ docker logs mysql-develop 2>&1 | grep GENERATED
[Entrypoint] GENERATED ROOT PASSWORD: XXXXXXXX
$ docker exec -it mysql-develop mysql -u root -p
Enter password: # XXXXXXXX

リモートアクセス用のユーザー作成、権限付与。

CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypass';
CREATE USER 'myuser'@'%' IDENTIFIED BY 'mypass';
GRANT ALL ON *.* TO 'myuser'@'localhost';
GRANT ALL ON *.* TO 'myuser'@'%';
flush privileges;

コンテナから抜けて、ホストのクライアントからアクセス。

$ mysql -u remote_user -h '127.0.0.1' -p
Enter password: # mypass入力

参考

https://stackoverflow.com/questions/16287559/mysql-adding-user-for-remote-access

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

Dockerコンテナ上でのbundle installコマンドがcode: 15でエラー終了する時はBUNDLE_PATHの設定を確認する

事象

Docker Imageをクリアした日からCIがエラー終了するようになった

bundle install --cleanが失敗するようになってしまった。

Bundle complete! 62 Gemfile dependencies, 187 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Cleaning all the gems on your system is dangerous! If you're sure you want to
remove every system gem not in this bundle, run `bundle clean --force`.
Service 'xxxx' failed to build: The command '/bin/sh -c bundle install --clean' returned a non-zero code: 15

一度Bundle complete!と表示されるのだが、その後Cleaning all the gems on your system is dangerous!としてcode: 15を返してエラー終了してしまっている。


問題となったコンテナのDockerfile

FROM ruby:2.6.5
ENV RUBYOPT -EUTF-8
ENV LANG C.UTF-8
RUN gem install rails -v 6.0.2
# 以下略

原因

RubyのDocker Imageに入った下記の変更により、BUNDLE_PATHが自動で設定されなくなっていた。
Stop setting `BUNDLE_PATH` by deivid-rodriguez · Pull Request #306 · docker-library/ruby

Dockerfile上ではBUNDLE_PATHを指定していなかったため、Imageでの設定が削除されたことでBUNDLE_PATHの指定が空になってしまい、対象がグローバルになってしまった。
だから以下のようなメッセージが表示されたと考えられる。

Cleaning all the gems on your system is dangerous! If you're sure you want to
remove every system gem not in this bundle, run `bundle clean --force`.

しばらくはキャッシュで古いイメージを使っていたため問題が発生しなかったが、キャッシュをクリアしてImageを再取得したことで問題が発生した。

対応

ENV BUNDLE_PATH=$GEM_HOMEをDockerfileに追加することで解消した(上記PRで削除された箇所を、自前のDockerfileに記載する形)。
(最初はdocker-composeファイルのenvironmentに追加したのだがエラーが解消されませんでした。急いでいたので詳しく検証はできていないですが…)

参考

Newest version breaks build - 'Cleaning all the gems on your system is dangerous!' · Issue #3271 · rubygems/rubygems

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

アリババクラウド上のDockerコンテナにJenkinsを設定する

このチュートリアルでは、Alibaba Cloud上のDockerコンテナでJenkinsを設定します。

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

必要条件

-Ubuntu 18.04 以上がインストールされた Alibaba Cloud ECS インスタンス上で動作する仮想マシン。

-信頼できるインターネット接続。

-管理者権限を持つコンピュータ。

仮想マシンへのDockerのインストール

最初のステップは、ホストマシンにDockerが適切にインストールされていることを確認することです。Dockerがインストールされていることを確認するには、ご使用のマシンで以下の手順に従ってください。

1.パッケージのローカルリポジトリを更新します。

$ sudo apt-get update

2.HTTPSで暗号化されたパッケージをダウンロードできるようにするためのapt-transport-https、Dockerイメージをダウンロードしてインストールしようとするときにセキュリティ証明書をダウンロードできるようにするためのca-certificates、リモートのhttpエンドポイントを照会できるようにするためのcurl、Dockerをインストールするために必要なパッケージであるgnupg-agentとsoftware-properties-agentをインストールします。

$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent Software-properties-common

3.Dockerのoffcial PGPキーを追加します。これは、dockerのレジストリとの通信が暗号化されて安全な状態を維持できるようにするためです。以下のコマンドで行うことができます。

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

4.Dockerの安定版リポジトリを設定します。

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

5.aptパッケージのインデックスを更新します。

$ sudo apt-get update

6.最新版のDockerエンジンとdocker-composeをインストールします。

$ sudo apt-get install docker docker-compose

7.以下のコマンドを実行して、Dockerが正しくインストールされていることを確認します。

$ sudo docker run hello-world

このコマンドは、docker用のテストイメージをダウンロードし、そのイメージを実行します。操作が完全に成功すると、下の画像のようなイメージが送られてくるはずです。

image.png

DockerリポジトリからJenkinsのDockerイメージを取得する

Dockerリポジトリには、Jenkins、Jira、Java、NodeJSなど、さまざまなソフトウェアのイメージが格納されています。Jenkinsの場合、コンテナ化された環境でJenkinsを実行できるようにするためには、JenkinsのDockerイメージを公式のDockerリポジトリからダウンロードする必要があります。そこで、自分でイメージを構築するのではなく、Dockerのレジストリからイメージを引っ張ってきて、インストールしてローカルで実行することにします。

1.docker pullコマンドを実行してJenkinsのイメージを取得します。

$ docker pull jenkins

このコマンドを実行すると、シェルに似たようなテキストが表示されるはずです。

image.png

2.pullコマンドが正常に完了したことを確認するには、ターミナルでdocker imagesコマンドを実行して、jenkins imagesが既にリストアップされていることを確認します。

$ docker images

このコマンドを実行すると、ローカルにインストールされているJenkinsイメージを明確に識別できるように、ターミナルにこのようなプリントが表示されるはずです。

image.png

DockerコンテナでJenkinsを実行する

先ほどのコマンドを実行することで、Dockerを設定し、Jenkinsのdockerイメージをローカルコンピュータにインストールしました。今度はインストール済みのjenkinsのイメージを使って、dockerイメージの中で実行してみましょう。

1.docker psコマンドを入力して、jenkinsのdockerイメージがまだ実行されていないか確認します。

$ docker ps

ターミナルでこのコマンドを実行すると、このような出力が得られるはずです。

image.png

上の画像では、MySQLとwordpressのdockerイメージが動いているのがわかりますが、Jenkinsのイメージはありません。

Jenkinsのdockerイメージは既にあります。しかし、このイメージをコンテナで動かすためには、Jenkinsのdockerのイメージをビルドして実行する必要があります。

2.Jenkinsのdockerのイメージを実行するには、以下のコマンドを実行する必要があります。

$ docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts

上記のコマンドでコンテナ内でJenkinsを実行し、localhostの8080番ポートで利用できるようにします。

注意: 上記のコマンドはJenkinsに永続的なストレージを提供していないため、コンテナが停止したり削除されたりすると、すべてのデータが削除されてしまいます。しかし、本番環境では、そのようなことが起きないようにしたいものです。そのような動作を避けるために、dockerインスタンスにストレージデバイスをアタッチします。

Docker はボリュームを提供しており、これにより docker コンテナにストレージを追加することができます。

3.以下のコマンドを実行して、コンテナの停止や削除時にデータを失わずにJenkinsを実行します。

$ docker run -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts

このコマンドを実行すると、以下のパスにもjenkinsフォルダが作成されます。

$ /var/jenkins_home jenkins/

4.jenkins用のdockerコンテナが作成されている間に、jenkinsはまた、以下のようにターミナルで見つけることができるパスワードを自動的に生成するか、またはファイルの中で見つけたファイルの中で見つけることができます。

$ /var/jenkins_home/secrets/initialAdminPassword

以下は、initialAdminPasswordファイルの内容のサンプルの画面キャプチャです。

image.png

注:パスワードはそこに表示されているものとは異なります。パスワードを知っておく必要があります。端末のパスポートをコピーしておくと後で使えるようになります。

5.ブラウザからJenkinsにアクセスする これを行うには、localhost:8080というアドレスでブラウザを開くと、以下のようなWebページが表示されるはずです。

image.png

6.ターミナルからコピーした管理者パスワードを入力するか、/var/jenkins_home/secrets/initialAdminPassword ファイルから取得すると、インストールページに移動します。

image.png

7.次に、プラグインを直接インストールする場合は「Install suggested plugins」を、特定のJenkinsプラグインをインストールしたい場合は「Select plugins to install」をクリックします。7.次に、目的のプラグインを選択してインストールをクリックします。

image.png

8.インストールプロセスは、あなたが最初の管理者ユーザーを作成するページにリダイレクトされ、その後、いくつかの時間がかかることができます。

image.png

9.別の管理者ユーザーを作成するか、Jenkinsで作成した管理者ユーザーを継続するかを選択しました。ここでは、デフォルトの管理者ユーザーをそのまま継続します。Continue as adminボタンをクリックします。その後、以下のような設定画面が表示されます。

image.png

これらのデフォルト設定を変更する必要はありませんが、「保存して終了」ボタンをクリックするだけで、これらの設定を保存することができます。

10.その後,最後の設定ページに移動し,Jenkinsへのログインに使用する資格情報を教えてくれます。ここでは、adminをデフォルトのユーザ名とし、 initialPasswordファイルからコピーした管理者パスワードを管理者パスワードとしたページの例を示します。

image.png

11.次に、Start Using Jenkinsをクリックするだけで、Jenkinsダッシュボードに移動します。そこでは実行するJenkinsジョブを作成することができます。以下はJenkinsのダッシュボードの画面キャプチャです。

image.png

結論

これでこのチュートリアルは終了です。今回のチュートリアルでは、Ubuntuを実行しているLinux仮想マシンにdockerをインストールして設定する方法、Jenkins Imageをインストールして設定する方法、そしてコンテナ化された仮想マシン内で実行する方法を学びました。

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

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

Racher:アリババクラウドにインストールしてDockerアプリケーションを管理する方法

このチュートリアルでは、Alibaba Cloud ECSインスタンスにRacherをインストールする方法と、Racherを使ってDockerアプリケーションを管理する方法を学びます。

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

前提条件

このチュートリアルでは、以下のアイテムが必要です。

  • 新たに作成した 2 台の Alibaba Cloud インスタンスと Ubuntu 16.04 がインストールされていること。
  • Rancherサーバーとして機能する ECS インスタンスに設定されている静的 IP アドレス 192.168.0.100 と、ランチャークライアントとして機能する ECS インスタンスに設定されている静的 IP アドレス 192.168.0.103。
  • 両方のインスタンスに root パスワードを設定します。 参考までに、新しい ECS インスタンスを作成してインスタンスに接続するを参照してください。次に、Ubuntu 16.04インスタンスにログインしたら、apt-get update -yコマンドを実行して、ベースシステムを最新の利用可能なパッケージでアップデートします。

Dockerをインストールする

このチュートリアルを始める前に、両方のインスタンスにDockerの最新の安定版がインストールされていることを確認する必要があります。デフォルトでは、Ubuntu 16.04のデフォルトリポジトリでは、最新の安定版Dockerは利用できません。そのため、インスタンスにDockerのリポジトリを追加する必要があります。

まず、以下のコマンドで apt が HTTPS 経由でリポジトリを利用できるようにします。

apt-get install apt-transport-https ca-certificates curl software-properties-common

次に、以下のコマンドでGPGの公式キーをダウンロードして追加します。

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

次に、以下のコマンドで鍵の指紋を確認します。

apt-key fingerprint 0EBFCD88

出力は以下のようになります。

pub   4096R/0EBFCD88 2017-02-22
      Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid                  Docker Release (CE deb) <docker@docker.com>
sub   4096R/F273FCD8 2017-02-22

次に、以下のコマンドでDockerリポジトリを追加します。

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

次に、リポジトリを更新し、以下のコマンドでDockerをインストールします。

apt-get update -y
apt-get install docker-ce=17.09.1~ce-0~ubuntu -y

Dockerをインストールしたら、以下のコマンドでDockerの状態を確認します。

systemctl status docker

出力は以下のようになります。

● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-12-04 20:36:26 IST; 1min 0s ago
     Docs: https://docs.docker.com
 Main PID: 14498 (dockerd)
   CGroup: /system.slice/docker.service
           └─14498 /usr/bin/dockerd -H unix://

Dec 04 20:36:24 rancher dockerd[14498]: time="2018-12-04T20:36:24.456058066+05:30" level=warning msg="Your kernel does not support swap memory 
Dec 04 20:36:24 rancher dockerd[14498]: time="2018-12-04T20:36:24.456185632+05:30" level=warning msg="Your kernel does not support cgroup rt pe
Dec 04 20:36:24 rancher dockerd[14498]: time="2018-12-04T20:36:24.456222954+05:30" level=warning msg="Your kernel does not support cgroup rt ru
Dec 04 20:36:24 rancher dockerd[14498]: time="2018-12-04T20:36:24.458818614+05:30" level=info msg="Loading containers: start."
Dec 04 20:36:25 rancher dockerd[14498]: time="2018-12-04T20:36:25.632077835+05:30" level=info msg="Default bridge (docker0) is assigned with an
Dec 04 20:36:25 rancher dockerd[14498]: time="2018-12-04T20:36:25.894066060+05:30" level=info msg="Loading containers: done."
Dec 04 20:36:26 rancher dockerd[14498]: time="2018-12-04T20:36:26.580044220+05:30" level=info msg="Docker daemon" commit=4d60db4 graphdriver(s)
Dec 04 20:36:26 rancher dockerd[14498]: time="2018-12-04T20:36:26.581073448+05:30" level=info msg="Daemon has completed initialization"
Dec 04 20:36:26 rancher systemd[1]: Started Docker Application Container Engine.
Dec 04 20:36:26 rancher dockerd[14498]: time="2018-12-04T20:36:26.784977406+05:30" level=info msg="API listen on /var/run/docker.sock"

Rancherのインストール

次に、RancherサーバーのインスタンスにRancherサーバーをインストールする必要があります。rancher/serverのDockerイメージをダウンロードし、以下のコマンドを実行することでコンテナ内のRancherサーバーを起動することができます。

docker run -d --restart=unless-stopped -p 8080:8080 rancher/server:stable

Rancher サーバーが正常にインストールされると、ポート 8080 を使用して Web ブラウザからアクセスできるようになります。

Rancher の設定

今、あなたのウェブブラウザを開き、URLを入力してください http://192.168.0.100:8080次のページにリダイレクトされます。

image.png

まず、ユーザーを管理するための Rancher アクセスコントロールを設定する必要があります。Rancher は、Active Directory、Azure AD、Github、OpenLDAP、SAML、ローカル認証など、多くのアクセスコントロールをサポートしています。

ここでは、Rancher のローカル認証を設定します。

設定するには、ADMIN メニューからアクセスコントロールをクリックします。以下のようなページが表示されるはずです。

image.png

次に LOCAL Access Control をクリックし、ユーザー名とパスワードを入力して、Enable Local Auth ボタンをクリックします。すると、以下のページで Local Authentication が有効になっている Rancher Dashboard が表示されるはずです。

image.png

Rancher サーバーに Rancher クライアントを追加する

次に、Rancher クライアントを Rancher Server インスタンスに追加する必要があります。

これを行うには、Rancher ダッシュボードに移動し、[インフラストラクチャー]メニューをクリックし、[ホスト]ボタンをクリックします。以下のページが表示されるはずです。

image.png

ここで、「ホストの追加」ボタンをクリックします。以下のページにホスト登録URLが表示されているはずです。

image.png

ここで、「保存」ボタンをクリックします。以下のようなページが表示されるはずです。

image.png

ここで、カスタムホストタイプを選択し、RancherクライアントのIPアドレスを入力します。次に、ボックスから Docker コマンドをコピーします。

次に、Rancher Client インスタンスにログインし、ターミナルを開き、以下のようにコマンドを貼り付けます。

docker run -e CATTLE_AGENT_IP="192.168.0.103"  --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.11 http://192.168.0.100:8080/v1/scripts/B8DD56FA4C0200C93870:1514678400000:76ua9Llt9e58W6MMYzYmwMVXAg

このコマンドは、Rancher Agent ホスト上に新しい Rancher コンテナをダウンロードして作成します。プロセスが正常に完了すると、以下のような出力が表示されるはずです。

Status: Downloaded newer image for rancher/agent:v1.2.11

INFO: Running Agent Registration Process, CATTLE_URL=http://192.168.0.100:8080/v1
INFO: Attempting to connect to: http://192.168.0.100:8080/v1
INFO: http://192.168.0.100:8080/v1 is accessible
INFO: Configured Host Registration URL info: CATTLE_URL=http://192.168.0.100:8080/v1 ENV_URL=http://192.168.0.100:8080/v1
INFO: Inspecting host capabilities
INFO: Boot2Docker: false
INFO: Host writable: true
INFO: Token: xxxxxxxx
INFO: Running registration
INFO: Printing Environment
INFO: ENV: CATTLE_ACCESS_KEY=8DEEDD0366EBBA2368EE
INFO: ENV: CATTLE_AGENT_IP=192.168.0.103
INFO: ENV: CATTLE_HOME=/var/lib/cattle
INFO: ENV: CATTLE_REGISTRATION_ACCESS_KEY=registrationToken
INFO: ENV: CATTLE_REGISTRATION_SECRET_KEY=xxxxxxx
INFO: ENV: CATTLE_SECRET_KEY=xxxxxxx
INFO: ENV: CATTLE_URL=http://192.168.0.100:8080/v1
INFO: ENV: DETECTED_CATTLE_AGENT_IP=192.168.0.103
INFO: ENV: RANCHER_AGENT_IMAGE=rancher/agent:v1.2.11
INFO: Launched Rancher Agent: f2242a231e5c774a80004c7a930145b9711406fd6e22d1af6a2aaf508d1ee863

次に、Rancher ダッシュボードに戻り、閉じるボタンをクリックしてください。新しく追加された Rancher クライアントが以下のページに表示されているはずです。

image.png

Rancher を使って新しいコンテナを作成する

Rancher サーバーとクライアントのインストールと設定が完了したので、Rancher を通して新しいコンテナを作成しましょう。

Rancher ダッシュボード上の INFRASTRUCTURE メニューから Containers をクリックしてください。以下のページが表示されるはずです。

image.png

ここで、「コンテナの追加」ボタンをクリックします。以下のようなページが表示されるはずです。

image.png

image.png

コンテナ名を指定し、画像を選択し、ポート番号を指定して作成ボタンをクリックします。コンテナが正常に作成されると、以下のページに新しく作成されたWebサーバーコンテナが表示されるはずです。

image.png

結論

これで、Ubuntu 16.04 サーバーに Docker を使って Rancher をインストールし、設定することができました。これで、RancherのWebインターフェースを使って、Dockerコンテナの作成、起動、停止、削除などを簡単に管理できるようになりました。

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

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

docker-composeのenv_fileと.envファイルの違い

docker-composeにおいて、今まで混同していた

  • docker-compose.yml中のenv_fileで読み込むファイル
  • .envという名前のファイル

の違いについて、他の人が同じ過ちをしないように書き留めておきます。

LinuxとWindowsでは環境変数の扱いが微妙に異なるので、Windowsに慣れている人やdocker for windowsを使っている人が引っかかりやすいと思います。

基本的にこの質問と解答と同じ内容ですが、少し情報を足しておきます。

docker-compose cannot understand my env_file | stack overflow

docker-composeと環境変数

公式リファレンス
Dockerドキュメント | compose中の環境変数
に沿って、知識を整理しながら解説します。

docker-compose.yml中で使うホストの環境変数

docker-compose.yml中ではホスト側のシェルの環境変数が使えます。

例えば、

docker-compose.yml
web:
  image: "webapp:${TAG}"

と書いておいて、host側で環境変数TAGが設定されていればその値が挿入されます。
例えばTAGv1.5という値が設定されていれば、docker-compose buildで作られるimage名はwebapp:v1.5となります。

設定した環境変数にどのような値が挿入されるかは、docker-compose configコマンドで確認できます。

$ echo $TAG
# Windowsの場合は echo %TAG%で確認
v1.5

$ docker-compose config

version: '3'
services:
  web:
    image: 'webapp:v1.5'

.envファイル

ただ、いつもホストに使いたい環境変数が設定されているとは限らないです。
その場合の回避策として、docker-compose.ymlで使う環境変数のデフォルト値を.envというファイルで設定できます。
例えば.envファイルに

.env
TAG=v1.5

のように設定されていれば、image名は上と同様webapp:v1.5となります。

.envファイルはdocker-composeコマンドを実行したときのディレクトリにある必要があります(ワーキングディレクトリ)
他の場所では認識しません。
(Declare default environment variables in file参照)

この.envファイルによる設定は、ホストに使いたい環境変数がない場合の回避策なので、
もちろんホストに同名の環境変数が設定されていれば、そちらが優先されます。

$ export TAG=v2.0
# Windowsの場合は set TAG=v2.0で環境変数を設定
$ docker-compose config

version: '3'
services:
  web:
    image: 'webapp:v2.0'

立ち上げたコンテナ中の環境変数

上の話とは別にdocker-compose.yml中のenvironmentの項目を使うことで、docker-compose rundocker-compose upで立ち上げたコンテナに環境変数を設定できます。

docker-compose.yml
web:
  environment:
    - DEBUG=1

とすると、立ち上がったコンテナ中では

$ echo $DEBUG
1

と環境変数が設定されています。

docker-compose.yml中のenv_fileの項目

このコンテナ中の環境変数を別ファイルに書いておくこともできます。例えばweb-variables.envというファイルに

web-variables.env
DEBUG=1
FOO=bar

と書いておき、

web-variables.env
web:
  env_file:
    - web-variables.env

と、docker-compose.yml中のenv_fileの項目で読み込むファイルを指定しておけば、
コンテナ中では

$ echo $DEBUG
1
$ echo $FOO
bar

と環境変数が設定されています。

以上から、

  • env_fileで読み込むファイル
  • 先程述べた.envファイル

全く働きが別だということがわかると思います。

まとめ

  • docker-compose.yml中の$...は基本的にホストの環境変数であって、お手軽に使える変数ではない
  • env_file.envファイルは全く別

この問題にはまったきっかけ

最後に、検索することで、できるだけこの問題で引っかかている人が解決できるようにするために、
この問題にはまったきっかけを記しておきます。

docker-compose.yml中の環境変数を普通の変数のように使おうとしていた

docker-compose.yml中の$...に代入する値を場合によって使い分けて、
いろんな場合に対応させようとしたときにこのenv_fileと.envファイルに苦しみました。
本来ならば、-fオプションを使ったりして、docker-compose.ymlを分割すべきなのかもしれません。

docker-composeのプロキシ設定をしたかった

プロキシ下でdocker-composeする場合はdocker-composebuild中や、
立ち上がったコンテナでHTTP_PROXYなどのプロキシ用の環境変数を設定しなければなりません。

これを解決するためにdocker-composebuild>argsの項目やenvironment:の項を設定すればいいのですが、
ここでこのenv_fileと.envファイルに苦しみました。

これらを踏まえ、プロキシ下でのdocker-composeするための記事を作りました。

docker-composeでのプロキシ設定を一つのファイルにまとめる

VSCodeのRemote Containerで.envファイルを使おうとした

Advanced Container Configuration | VSCode
VSCodeのdockerを使ったリモートデバッグ機能(Remote Container)において、
devcontainer.jsonからdockerComposeFileの項でdocker-compose.ymlを指定し、リモートコンテナを立ち上げようとしました。
その際、プロキシを設定するために.envファイルを使おうとしましたが、
.envファイルをdocker-compose.ymlと同じフォルダにおいてもRemote Containerでは正しく設定できませんでした。

原因は上で述べた通り、
.envファイルはdocker-composeコマンドを実行したときのディレクトリにある必要がある
ということでした。

Remote Containerではdocker-composeをVSCodeのルートディレクトリで実行しているので、
ルートディレクトリに.envファイルはを置いたところ、正常に動作しました。
(Github Microsoft VSCode issue #222参照)

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

【Docker環境構築/Rails6~,MySQL】ローカル環境で作成中の既存アプリをDocker環境に移行する手順

はじめまして、こんにちは!
ローカル環境で作成中の既存アプリケーションをDocker環境に移行する手順について、私自身が実施した内容です。初学者ですが頑張って環境構築しましたので、ふり返りのためにも記録しておきたいと思います!

環境によっては手順どおりには行かないと思います。
またプログラミング初学者で勉強の為に試行錯誤して実施しておりますので、誤っている事、不要なことがあるかもしれません。その際はご指摘頂けるとありがたいです。

環境

  • Ruby 2.6.5
  • Rails 6.0.0
  • MySQL 5.6

事前準備

  • Docker Desctopをインストール
  • Dokerデーモンが起動している状態

Docker Desctopは「Stable」となっている方をダウンロード(無料、安定バージョン)します。
Dockerデーモンは、mac起動時に自動で立ち上がります。上部のメニューバーのクジラのアイコンが表示されて「Docker Desctop is running」となっていれば大丈夫です。

手順①既存アプリのディレクトリに以下3つのファイルを配置

スクリーンショット 2020-08-18 0.53.10.png

  • Dockerfile
  • docker-compose.yml
  • entrypoint.sh

アプリケーションのディレクトリ直下に3つのファイルを新規作成する

▼Dockerfile記述内容

FROM ruby:2.6.5

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

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

WORKDIR /myapp
COPY Gemfile ./Gemfile
COPY Gemfile.lock ./Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

▼docker-compose.yml記述内容

version: '3'
services:
  db:
    image: mysql:5.6 #既存アプリとあわせる。ターミナルに「mysqladmin version」で確認
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "4306:3306"  #Sequel ProでDBを確認する為、4306としておく
    volumes:
      - mysql-data:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
volumes:
  mysql-data:

▼entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

手順②config/database.ymlの編集

configディレクトリにあるdatabase.ymlを以下のように編集

▼config/database.yml

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db # database.ymlの記述とあわせておく

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

手順③Dockerイメージの作成

% docker-compose build

手順④MySQLコンテナを起動

% docker-compose up -d

この時点ではwebは起動してなくてよい。
「docker-compose ps」コマンドでdbのStateがUPとなっていればよい。

手順⑤DBを作成する

% docker-compose run web rails db:create

database.ymlをもとにwebコンテナからmysqlコンテナへ接続して、DBを作成する。成功すると下記表示。

Created database 'myapp_development'
Created database 'myapp_test'

手順⑥マイグレーションを実行

% docker-compose run web rails db:migrate

database.ymlをもとにwebコンテナからmysqlコンテナへ接続して、マイグレーションを実行する。成功していれば下記のような実行結果。

== 20200812024158 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0091s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0109s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0120s
== 20200812024158 DeviseCreateUsers: migrated (0.0326s) =======================

手順⑦webコンテナも起動させる

% docker-compose up -d

上記実行後、「docker-compose ps」コマンドでweb、db共にUPとなっていれば成功。

手順⑧gemのインストール

% docker-compose exec web bundle install

最後に!SequelProに接続

スクリーンショット 2020-08-18 1.47.43.png

  • 標準を選んで、ホストに自身を表す「127.0.0.1」
  • パスワードはdocker-compose.ymlに記載のパスワード
  • ポートはdocker-compose.ymlに記載のポート番号

以上です!
localhost:3000に接続するとアプリケーションを確認できると思います!

参考にさせて頂いた記事

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