20190707のdockerに関する記事は11件です。

Docker メモ

導入してみて、詰まったところをメモします。

Dockerとは

仮想環境を簡単に作れるもの。VirtualBoxなどと比べると軽量で高速らしい。

インストール

まずは Docker Community Edition をインストール。

インストールしたら docker を起動して、ターミナルから確認

$ docker -v
Docker version 18.09.2, build 6247962

基本的な構成

ざっくりとした構成図です。

alt

DockerコンテナはDockerイメージを元に作成されます。Dockerコンテナが仮想環境です。

Dockerイメージは予めDockerHubに用意されているものを取得するか、自分で作成したDockerfile(テキストファイル)をbuildすることで作成できます。

コンテナを作ってブラウザからアクセスしてみる

まずはイメージとコンテナの確認。どちらも存在しません。

$ docker images
REPOSITORY  TAG IMAGE ID  CREATED SIZE

$ docker ps -a
CONTAINER ID  IMAGE COMMAND CREATED STATUS  PORTS NAMES

コンテナを作成。

$ docker run --name myNginx -d -p 8080:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
fc7181108d40: Pull complete 
d2e987ca2267: Pull complete 
0b760b431b11: Pull complete 
Digest: sha256:96fb261b66270b900ea5a2c17a26abbfabe95506e73c3a3c65869a6dbe83223a
Status: Downloaded newer image for nginx:latest
259abccb75f8af516fc5ff31a29cee018e28d42d654f830302d1d3c0dda4146e

再度イメージとコンテナの確認。Dockerイメージがダウンロードされて、コンテナが作成、起動されています。

$ docker images
REPOSITORY  TAG     IMAGE ID      CREATED     SIZE
nginx       latest  f68d6e55e065  4 days ago  109MB

$ docker ps
CONTAINER ID  IMAGE   COMMAND                  CREATED             STATUS                        PORTS                  NAMES
259abccb75f8  nginx   "nginx -g 'daemon of…"   58 seconds ago      Up 57 seconds                 0.0.0.0:8080->80/tcp   myNginx

ブラウザから http://localhost:8080/ にアクセスするとページが表示されます。

Welcome to nginx!
...

コンテナの動作確認

$ docker ps

コンテナの停止

$ docker stop {CONTAINER ID}

Dockerイメージや、Dockerコンテナはどんどん溜まって行くため不要であれば削除します。

コンテナの削除

$ docker rm {CONTAINER ID}

イメージの削除

$ docker rmi {IMAGE ID}

Dockerfile からの Build

ファイル名Dockerfileでファイルを作成。

FROM centos:7
RUN yum update -y 
RUN yum install -y ...
...

Dockerfileのあるディレクトリまで移動してbuildする。

$ cd {path to Dockerfile}
$ docker build 

参考


以下、未整理


DockerのIP

$ docker-machine env
$ docker-machine ip

コンテナの作成

$ docker run -it ubuntu

コンテナにアクセス

起動中のコンテナにアクセスするにはexecコマンドを使います。

コンテナの停止・削除

$ docker stop $(docker ps -q)
$ docker rm $(docker ps -q -a)

イメージの削除

$ docker rmi $(docker images -q)

docker-compose

# 起動
# -d でコンテナをデーモン化
$ docker-compose up -d

# 停止
$docker-compose down

Wordpress

docker-compose を使う

  • ./docker-compose.ymlを作成する
  version: '3.1'

  services:
    # mysql ※ 5.7はダメ(2019.06.07)
    db:
      image: mysql:5.6
      container_name: mysql
      environment:
        MYSQL_ROOT_PASSWORD: wwcom999999
        MYSQL_DATABASE: wordpress
        MYSQL_USER: wordpress
        MYSQL_PASSWORD: wordpress
    # wordpress
    wordpress:
      image: wordpress:latest 
      restart: always
      container_name: wp 
      ports:
        - "8080:80"
      depends_on:
        - db
      volumes:
        - ./var/www/html:/var/www/html
      environment:
        WORDPRESS_DB_HOST: db:3306
        WORDPRESS_DB_NAME: wordpress
        WORDPRESS_DB_USER: wordpress
        WORDPRESS_DB_PASSWORD: wordpress
  1. マウント用のディレクトリ作成

    ホストマシンからファイル編集ができるように、コンテナにマウントするためのディレクトリを作成する。

    $ mkdir -p ./var/lib/www

  2. 初期化

    $ docker-compose up -d

  3. IP の確認
    ブラウザからアクセスするために、dockerのIPを確認

    $ docker-machine ip
    192.168.99.100

  4. ブラウザから192.168.99.100:8080へアクセスする。

  • vmware toolbox の設定
    Oracle VM VirtualBoxマネージャーから以下を開く 設定 > ネットワーク > 高度 > ポートフォワーディング 以下の設定を追加する。 ホストポート:80 ゲストポート:80

その他

  • 停止 $ docker-compose stop
  • 再開 $ docker-compose start
  • 停止と削除 $ docker-compose down
  • 確認 $ docker-compose ps ## プラグイン
  • welcart )
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker で ヘッドレス Chrome を動かしてスクレイピングする

ヘッドレス Chrome を動かしてウェブサイトをスクレイピングするための Docker イメージを作成しました。

この Docker イメージは指定された URL をヘッドレス Chrome で取得して HTML を標準出力にダンプします。
手軽に Vue.js や React で実装されたページの HTML を取得するときに便利です。

$ docker pull grohiro/headless-chrome
$ docker run --rm -t grohiro/headless-chrome http://www.google.com/ | head -5 | cut -b -100
<!DOCTYPE html>
<html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta charset="UTF-8"><meta
"clickmod";else{var f=b.which||b.keyCode||b.key;D&&3==f&&(f=13);if(13!=f&&32!=f)f=!1;else{var m=B(b)
b;e.event=A;a.i.push(e)}if("touchend"==e.event.type&&e.event._mouseEventsPrevented){b=e.event;for(va
c&&(c="focusout"),e=w(b,e),b.attachEvent("on"+c,e));return{m:c,l:e,capture:f}}},O=function(a,d){if(!

単一のページを取得したいだけならプログラムの中から Docker を直接起動して HTML を取得できます。

<?php
// PHPの例
$cmd = "docker run --rm -t grohiro/headless-chrome http://www.google.com";
exec($cmd, $output, $status);
if ($status !== 0) {
  throw new \Exception("コマンドの実行がエラーになりました");
}
$html = implode("\n", $output);
$dom = @DOMDocument::loadHTML($html);
$xpath = new DOMXPath($dom);
echo $xpath->query('//title')[0]->nodeValue;
// => Google

Docker イメージの作成は https://qiita.com/rotelstift/items/7dafcdcae3ca18b65b26 こちらの記事を参考にしました。

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

Docker + macでLittleSLAMを動かす

SLAM入門: ロボットの自己位置推定と地図構築の技術(友納 正裕) のサンプルコード、LittleSLAMをMacのDockerで動かす。
gnuplotを使っているので、ホストにXQuartzを用意してXを表示する。

Prepare files

Clone the repo

$ git clone --recursive https://github.com/furo-org/LittleSLAM.git

もしくは

$ git clone https://github.com/furo-org/LittleSLAM.git
$ cd LittleSLAM
$ git submodule init
$ git submodule update

Download the dataset

https://github.com/furo-org/LittleSLAM の通り、支持されたリンクからデータセットをダウンロードする。
LittleSLAM/datasetディレクトリに置くことにする。

$ cd /path/to/LittleSLAM
$ mkdir dataset
$ cd dataset
$ wget https://furo.org/software/little_slam/dataset.zip
$ unzip dataset.zip

path/to/LittleSLAM/dataset以下に *.lscファイルが置かれる。

Prepare X11

dockerコンテナ内からgnuplotで描画したのをホスト(Mac)のGUIで見れるよう、Xを準備する

参考: http://raphine.hatenablog.com/entry/2018/08/14/004634

Install XQuartz

  1. https://www.xquartz.org/ からXQuartzをダウンロード→インストール
  2. インストール後、macからログアウト→ログイン

Enable X11

  1. XQuartzのメニュー→「環境設定」→「セキュリティ」タブ→「ネットワーク・クライアントからの接続を許可」にチェック
  2. XQuartzを終了→起動
  3. この後起動するdockerコンテナからのXの接続を許可
  $ xhost + 127.0.0.1

Run LittleSLAM in a docker container

Launch a docker container

$ docker run -it \
-e DISPLAY=docker.for.mac.localhost:0 \
-v /path/to/LittleSLAM:/workspace \
-w /workspace \
--name little-slam \
debian:stretch bash
  • -e DISPLAY=docker.for.mac.localhost:0: Xの接続
  • /workspace: コンテナ内の作業ディレクトリを指定。好きな場所を指定すればよい。
  • --name little-slam: dockerコンテナの名前を指定。好きな名前を付ければよい。
  • debian:stretch: この例ではdebian:stretchイメージを利用。好きなイメージを使えばよい。

以下は、上記で起動したdockerコンテナ内での作業となる。
https://github.com/furo-org/LittleSLAM/blob/master/doc/install-linux.md の通りに進めていけばよい。

Build LittleSLAM

# apt update
# apt install build-essential cmake libboost-all-dev libeigen3-dev gnuplot gnuplot-x11
# mkdir build
# cd build
# cmake ..
# make

Run LittleSLAM

# cd /workspace/build/cui
#  ./LittleSLAM ../../dataset/corridor.lsc
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerの開発環境構築の方法

はじめに

先日Dockerの開発環境構築をする機会があったのでその方法を忘れないようにまとめておきます。なお、必要になる技術や環境は以下の通りです。

・使用PC:MAC
・テキストエディタ:Visial Studio Code

Dockerの開発環境構築の方法

1. Docker Hubからイメージをダウンロードする

① Docker Hub(https://www.docker.com/products/docker-hub) にアクセスしてDockerをダウンロードする。
② Finderを開き、Dockerを『ダウンロード』から『アプリケーション』にドラッグ&ドロップする。
③ Dockerアプリケーションを起動させる。
④ 起動させるとクジラとコンテナの画像がでてくるので、クジラの絵をコンテナにドラック&ドロップする

2. Visial Studio CodeからDockerを操作する

① 『command + shift + @』でターミナルを出す。
② Dockerの動作を確認する

docker version

③ Docker Hubからイメージをダウンロードする(今回は例としてubuntuというイメージをダウンロードします)

docker pull ubuntu:16.04

④イメージがダウンロードできているか確認する

docker images

⑤コンテナをつくり、名前をつける(ここでは『first-ubuntu』と命名)

docker run -it -d --name first-ubuntu :ubuntu:16:04

⑥起動しているコンテナを確認して、⑤でつくったコンテナが起動しているか確認する

docker ps

⑦⑤でつくったコンテナに入る

docker exec -it first-ubuntu pwd 

⇒ 『/(ルート)』が表示されれば⑤のコンテナのフォルダの頂点に入れたことになる

⑧⑤でつくったコンテナの中身を参照して、コンテナのフォルダに入れたか確認する。

docker exec -it first-ubuntu ls 

おわりに

これでコンテナの中身を操作できます。細かい操作コマンドは別の記事でまとめます。

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

Dockerの仕組みを超初心者向けに超初心者がまとめてみた

はじめに

先日超初心者にもわかるようにDockerの仕組みを説明してもらえる機会があったので、そこで教えてもらった内容を自分のアウトプット用としてまとめておきます。なお、超初心者用にかなり言葉を噛み砕いてとても簡単に説明してもらったものなので、Dockerの仕組みを熟知している人が見ると厳密には違う部分もあるかもしれませんが、「大雑把に言うとこんな感じだよね~」くらいで捉えてもらえると幸いです。

Dockerってなに?

A. 簡単に言うと、自分のパソコンの中にもうひとつパソコンを搭載できるサービスのこと

ちなみに、超初心者の私はDockerの仕組みを部屋とテントに例えて説明してもらうと理解しやすかったです。自分の部屋(=自分のパソコン)にテント(=もうひとつのパソコン)を張っているところを想像してみてください。このとき自分の部屋(=自分のパソコン)はテント(=もうひとつのパソコン)にスペースを貸している状態になります。このスペースを貸している状態のことを仮想化と言います。この仮想化こそがDockerの真骨頂のサービスです。

どうして仮想化を使ったほうがいいの?

A. 仮想化には以下のメリットがあります。

・ネット環境がなくてもサービスの開発ができる
・テント(=もうひとつのパソコン)は何回でもつくったり壊したりできる
・テント(=もうひとつのパソコン)は何個でもつくれるので開発しようとしている技術を比較しながら開発できる

このように、アプリケーションを効率的に開発することができるので、仮想化を利用することが勧められています。ちなみに、仮想化サービスはDocker以外にもいくつかあるみたいなので気になる人はぜひググってみてください。

Dockerではどんなサービスを提供しているの?

A. Dockerでは2つのサービスを提供しています。

  1. Docker Engine:もうひとつのパソコン(テント)をつくることが出来る技術のこと
  2. DockerHub:(他の)Dockerユーザーが作成したコンテナをアップロード・共有できるサービス

DockerユーザーはDockerHubから使いたいテント(もうひとつのパソコン)ををつくるための材料をダウンロードすることができます。この材料のことをイメージと言い、これを元にしてDockerユーザーはテント(もうひとつのパソコン)を自分のパソコンにつくることができます。

また、ダウンロードしたイメージは自分たちが使いやすいようにイメージをカスタマイズすることで使うことができます。そしてこのイメージをカスタマイズしたもの=テント(もうひとつのパソコン)であり、これをDocker用語でコンテナと言います。コンテナの中にはWebサーバーパッケージなどを含むライブラリ機能とアプリケーションを作ることが出来る機能が搭載されています。

なお、このイメージをカスタマイズしたコンテナはDockerHubにアップロード・共有することができ、それをまたほかのユーザーがダウンロードして使うこともできます。

おわりに

ここまでDockerの仕組みを簡単にまとめてきました。多分文字だけで理解するのは難しい部分も多くあると思います。私自身も実際に絵や図にまとめて理解した部分も多くあるので、もしこれで理解しにくいな~と思う部分があれば絵や図にまとめてみると少し理解しやすくなるかもしれません。

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

Dockerの使い方

Dockerマウントの罠

dockerを使っていると、マウントしたくなります。pycharmの設定でDockerを使うこともできるらしいですが、よくわからないので使っていません。そうすると、pycharmで編集したファイルがそのままコンテナ内でも編集されていてほしいわけです。そんなわけでフォルダのマウントは非常に使えるわけですが、注意点が一つ。

                 /rootにマウントするな

docker run -v /Users/Name/Project:/root
としてしまいますと、大半の場合バグります。
理由としては、Dockerfileでいろいろとした設定が大抵/rootに入っているからです。
上のコマンドを打ってしまうと、Docker imageでセットアップされた/rootが全て吹き飛びます。

デバッグ時にコードを書き換えて反映したいときは、/Users/Name/Project:/root/source

などとしましょう。そうするとローカルでの変更が全てsource以下のファイルに反映されます。

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

Mac + Docker + Git Labインストール

Docker on Macで、GitLabを構築した時のメモです。

0. 追記

記事を書き終えた後に気づいたのですが、docker-composeでインストールする方法も公式ドキュメントに書かれていました・・・(;ω;)
Mac用にボリュームを書き直せば動きそうです。

 Installing GitLab using docker-compose(公式)

Mac用にボリュームを書き直した記事もありました。

 MACでDocker(docker-compose)を使用してローカルで使用するgitlabを起動

1. はじめに

基本的には以下記事を参考にしていただければ8割型は解決します。
私もお世話になりました。ありがとうございました。

 dockerを使ってmacOSにGitlabを構築する

上記手順でうまくいかない場合は、公式ドキュメントを見ましょう。
私はこの2つでどうにかなりました。
 
 Install Gitlab with docker(公式)

Docker使わずにMac上に直接インストールする記事もいくつかありますが、
Docker を使う方が楽だし、Macも汚れないのでオススメです。

2. 詰まったところ

(1) localhostにアクセスしても、It worksと表示される。

公式ドキュメント にも書かれていますが、初回起動は、GitLabが立ち上がるまでに少し時間がかかるようです。
全然立ち上がらないので、あれ?あれ?と再起動を繰り返してしまいました。
docker logs -f gitlab でログが見られるので、気長に起動を待ちましょう。

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

Nuxt.js + Rails(API) on DockerのHello Worldするべ!

Goal

友人からNuxt.jsいいよーと言われたのでひとまず触ってみるかというノリでNuxt.js + Rails(API) on DockerのHello Worldをめざします!

この記事のゴールはDocker上でフロントエンドとしてNuxt.js、バックエンドとしてRailsが連携しあってRailsのscaffold的にUserのCRUDができることです。
図にすると以下のような感じです。

Untitled Diagram (2).png

Table of contents

  1. Dockerコンテナの準備
  2. Nuxt.jsのHello world
  3. Rails(API)のHello world
  4. Nuxt.js + Rails(API)のHello world

Dockerやdocker-composeはすでにインストール済みの前提でいきます!

1. Dockerコンテナの準備

まずはNuxt.jsやRailsをDocker上で動作させるためのファイルの準備をしていきます。
Nuxt.jsは「docker で nuxt.js を開発環境を建てるだけ - Qiita」を参考にさせていただきました。
Rails(API)については「Rails on Docker(alpine)でAPIコンテナをつくってみた - Qiita」にて記事投稿しております。

詳細については各記事をご参考いただければ幸いですが、最終的なアウトプットは以下のようなものです。

DirectoryStructure
/
|--front/
|    |--Dockerfile
|--back/
|    |--Dockerfile
|    |--Gemfile
|    |--Gemfile.lock #空ファイル
|--docker-compose.yml
front/Dockerfile
FROM node:12.5.0-alpine

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

WORKDIR ${HOME}

RUN apk update && \
    apk upgrade && \
    npm install -g npm && \
    npm install -g vue-cli

ENV HOST 0.0.0.0
EXPOSE 8080
back/Dockerfile
FROM ruby:2.6.3-alpine3.10

ENV RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata postgresql-dev postgresql" \
    DEV_PACKAGES="build-base curl-dev" \
    HOME="/app" \
    LANG=C.UTF-8 \
    TZ=Asia/Tokyo

WORKDIR ${HOME}

ADD Gemfile ${HOME}/Gemfile
ADD Gemfile.lock ${HOME}/Gemfile.lock

RUN apk update && \
    apk upgrade && \
    apk add --update --no-cache ${RUNTIME_PACKAGES} && \
    apk add --update --virtual build-dependencies --no-cache ${DEV_PACKAGES} && \
    bundle install -j4 && \
    apk del build-dependencies

ADD . ${HOME}

CMD ["rails", "server", "-b", "0.0.0.0"]
back/Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5'
docker-compose.yml
version: "3"

services:
  db:
    container_name: sample_db
    image: postgres:11.4-alpine
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - ./back/tmp/db:/var/lib/postgresql/data

  back:
    container_name: sample_back
    build: back/
    volumes:
      - ./back:/app
    depends_on:
      - db
    ports:
      - 3000:3000

  front:
    container_name: sample_front
    build: front/
    command: npm run dev
    volumes:
      - ./front:/app
    ports:
      - 8080:3000

ここまでできたらbuildしてimageを作成しましょう。

$ docker-compose build

2. Nuxt.jsのHello world

imageができあがったらまずはNuxt.jsのアプリを作っていきます。

$ docker-compose run --rm front npx create-nuxt-app

? Project name                   --> sample_app  # アプリ名
? Project description            --> sample_app  # アプリの説明
? Author name                    --> me          # アプリの作成者
? Choose the package manager     --> Npm
? Choose UI framework            --> None
? Choose custom server framework --> None
? Choose Nuxt.js modules         --> Axios
? Choose linting tools           --> -
? Choose test framework          --> None
? Choose rendering mode          --> Universal (SSR)

Nuxtアプリが作成できたらアクセスできるか確認しときます。

$ docker-compose up front

http://localhost:8080にアクセスして以下のようなページにアクセスできればNuxt.jsのHello world完了です!

image.png

(参考)Nuxt.jsではホットリローディングというファイルの変更を自動で反映してくれる機能を有効にすることができます。npm run devコマンドでホットリローディングが有効になると公式で説明されていますが何やらうまくいくときといかない時がありました...うまくいかない場合は「IT研修でVuePress+Express+Nuxt on Dockerでシステムを作成した話 - エンジニアの卵の成長日記」を参考に以下のような設定を書き加えることでホットリロードされるようになりました。

front/nuxt.config.js
export default {
// 省略
  watchers: {
    webpack: {
      poll: true
    }
  }
// 省略
}

3. Rails(API)のHello world

まずRailsアプリを作成しましょう。--apiをオプションにつけることでAPIモードに不要なもの、例えばViewなどが含まれないようにrails newすることができます。

$ docker-compose run --rm back rails new . -f -d postgresql --api

Railsアプリが作成されたらDB接続の設定をします。

back/config/database.yml
##### 省略
default: &default
  adapter: postgresql
  encoding: unicode
  host: db            # add
  username: postgres  # add
  password:           # add
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 
##### 省略

DBの設定が完了したらDBを作成します。

$ docker-compose build back
$ docker-compose run --rm back rails db:create

DBの作成が完了したら、scaffoldでAPIを作ってみます。name属性をもつUserモデルを作ります。

$ docker-compose run --rm back rails g scaffold user name:string
$ docker-compose run --rm back rails db:migrate

Hello worldとして、testという名前のユーザーをAPIリクエストで作成してみます。

Rails APIでどのエンドポイントに何メソッドでリクエストすればいいかはrails routesコマンドで調べるとわかりやすいです。

$ docker-compose run --rm back rails routes
Prefix Verb   URI Pattern            Controller#Action
users  GET    /users(.:format)       users#index
       POST   /users(.:format)       users#create
user   GET    /users/:id(.:format)   users#show
       PATCH  /users/:id(.:format)   users#update
       PUT    /users/:id(.:format)   users#update
       DELETE /users/:id(.:format)   users#destroy

詳しい説明は省きますが、HTTPメソッド、URLパターン、アクションの関係性がわかるので、
ユーザーを作成する場合は「/usersにPOSTリクエスト」、特定のIDのユーザーの情報を取得する場合は「/users/:idにGETリクエスト」ということがわかります。
これを踏まえてcurlリクエストしてユーザー作成をしてきます。

$ docker-compose up -d back
$ curl -X POST http://localhost:3000/users -d 'user[name]=test'
$ curl http://localhost:3000/users/1
{"id":1,"name":"test","created_at":"2019-07-04T14:40:49.443Z","updated_at":"2019-07-04T14:40:49.443Z"}

これでRails APIのHello world完了です!

コンテナは停止しておきましょう。

$ docker-compose down

4. Nuxt.js + Rails(API)のHello world

さて、実際にはNuxt.jsのコンテナからRails(API)のコンテナにリクエストを流すので、Rails(API)のポートを外部に公開する必要はありません。誰からでもAPIのリクエストを受け取ってしまう状態はセキュリティ的にもよろしくありませんのでbackコンテナの外部公開ポートを削除しておきます。

docker-compose.yml
##### 省略
  back:
    container_name: sample_back
    build: back/
    volumes:
      - ./back:/app
    depends_on:
      - db
#   ports:        # delete
#     - 3000:3000 # delete
##### 省略

続いてNuxt.jsをいじっていきます。Hello worldでやりたいことは、

  1. http://localhost:8080/users/:idにアクセスして「Hello, (User.name)」と表示させたい
  2. http://localhost:8080/users/newにアクセスしてユーザーを追加したい

といったところにします。

4-1. http://localhost:8080/users/:idにアクセスして「Hello, (User.name)」と表示させたい

まずはhttp://localhost:8080/users/:idにアクセスした時にルーティングされるページを作成します。

$ mkdir front/pages/users
$ touch front/pages/users/_id.vue
front/pages/users/_id.vue
<template>
  <h1>Hello, {{ name }}</h1>
</template>

<script>
export default {
  asyncData({ $axios, params }) {
    return $axios.$get(`http://back:3000/users/${params.id}`)
      .then((res) => {
        return { name: res.name }
      })
  }
}
</script>

$axios.$getでGETメソッドでAPIをリクエストしています。リクエスト先はhttp://back:3000/users/${params.id}としていますが、backはbackコンテナを意味していますので、Railsアプリが入ったコンテナの/user/${params.id}にGETリクエストを飛ばしていることになります。
レスポンスの値からnameを変数として取り出し、template内の{{ name }}に入れます。

この状態でコンテナを起動してhttp://localhost:8080/users/1にアクセスすると、Rails(API)のHello worldで作成したtestユーザーの情報が取得できています。
が、Backコンテナが立ち上がっていないといけない状態になったのでdepends_onしておきましょう。

docker-compose.yml
##### 省略
  front:
    container_name: sample_front
    build: front/
    command: npm run dev
    volumes:
      - ./front:/app
    ports:
      - 8080:3000
    depends_on:
      - back
##### 省略
$ docker-compose up

image.png

4-2. http://localhost:8080/users/newにアクセスしてユーザーを追加したい

続きましてユーザーの新規登録です。こちらはPOSTリクエストしてあげることで実現できます。

先ほどと同様にhttp://localhost:8080/users/newにアクセスしたときに表示されるページを作っていきます。
このページでは、Nameを入力してsubmitするとRails APIの方にPOSTリクエストを飛ばしてUserを新規登録できるようにしたいと思います。新規登録したらそのUserのHelloページ(4-1で作成)にページ遷移するようにしましょー。

まずはじめに、Rails APIにリクエストを飛ばせるようにconfigをいじっていきます。

front/plugins/axios.js
export default function({ $axios, redirect }) {
    $axios.setToken('access_token')

    $axios.onResponse(config => {
        $axios.setHeader('Access-Control-Allow-Origin', 'http://back:3000')
    })
}
front/nuxt.config.js
export default {
// 省略
  plugins: [
    'plugins/axios'
  ],
  modules: [
    '@nuxtjs/axios'
  ],
  axios: {
    proxy: true
  },
  proxy: {
    '/api/': { target: 'http://back:3000', pathRewrite: { '^/api/': '/' } }
  },
// 省略
}

ここらへんの設定をしないとCORSエラーってのがおきちゃう。すごくつまった。
Nuxt.jsのメソッド内で外部APIを叩くとcorsエラーが起きる - Qiita」「nuxt.js で axios から外部APIを叩くとCORSエラーを解決 - Qiita」の記事を参考にしました!
4-1で実施したasyncDataはSSRなので不要なようですが、通常メソッド内でリクエストをしたい場合は信頼するドメインへのリクエストのみを許可する必要があるみたいですね。

さて、上記の設定が終わったら実際にページを作っていきます。

front/pages/users/new.vue
<template>
  <section>
    <div>
      <h1>New user</h1>
      <form @submit.prevent="post">
        <label for="name">Name: </label>
        <input id="name" v-model="name" type="text" name="name" />
        <button type="submit">submit</button>
      </form>
    </div>
  </section>
</template>

<script>
export default {
  data() {
    return {
      name: ''
    }
  },
  methods: {
    post() {
      this.$axios.post(
        '/api/users',
        {
          name: this.name
        }
      ).then((res) => {
        this.$router.push(`${res.data.id}`)
      })
    }
  }
}
</script>

このページ(http://localhost:8080/users/new)にアクセスすると下のような画面が出てきます。
image.png

POSTリクエストするあたりを説明します!

5行目:<form @submit.prevent="post">
formをレンダリングしてますが、@submit.preventでsubmit時に22行目で定義しているpost()メソッドを呼び出してます。

22行目〜31行目:POSTリクエスト
大まかに形としては

this.$axios.post(url, data).then((res) => {成功した後の動作})

という感じです。
urlには先ほどproxyで定義した/api/を用いて/api/usersを指定します。これでhttp://back:3000/usersにリクエストすることになります。
dataにはリクエストデータを記載します。今回はform内で入力しているv-model="name"の値をリクエストしたいので、{ name: this.name }としてます。
成功した後の動作としては登録したUserのHelloページへ遷移するとしてました。ページ遷移はメソッド内の場合はthis.$router.push(パス)でできるので、レスポンスデータから登録されたidを取得して、

this.$router.push(`${res.data.id}`)

とすることでPOSTリクエストに成功したときに作成したユーザーのHelloページへ自動遷移されます。

ここまで作成したら、Helloページ側のGETリクエスト先も/api/を使った記述に変更しておきます。これしないとthis.$router.push時にリクエスト失敗しちゃいました。

front/pages/users/_id.vue
// 省略
-    return $axios.$get(`http://back:3000/users/${params.id}`)
+    return $axios.$get(`/api/users/${params.id}`)
// 省略

ここまでで完成です。実際にhttp://localhost:8080/newにアクセスしてみてNameを入力しsubmitしてみましょう。

$ docker-compose up

入力したNameの「Hello, xxxxx」の画面に遷移したらNuxt.js + Rails(API)のHello worldは成功です!

Afterword

Nuxt.js初体験、Vue.jsとかも触ったことがなかったので結構苦戦をしいられました...
特にaxiosのPOSTリクエストには...かなりの時間を...うぅ...
同じくHello worldに苦しむ方の助けになれば幸いです!
引き続き勉強していかねば〜。

Reference

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

dockerコマンドの補完を設定する

どうも、若松です。

dockerコマンドを使っていると、わかってるけど単語のスペルが出てこないなどで、サブコマンドやオプションをhelpで調べたり、ググる場面が多いかと思います。
そんなときにdockerにはコマンドを補完してくれる機能あるので、紹介したいと思います。

補完設定

実は公式にドキュメントも用意されています。
http://docs.docker.jp/compose/completion.html

私の環境がMac且つbashのため、以下はそれに合わせたコマンドとなります。

brew install bash-completion
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose > /usr/local/etc/bash_completion.d/docker-compose

補完実行

補完を試すのは簡単です。

サブコマンド

例えば、dockerのサブコマンドがわからなくなった場合、 docker と打ってtabボタンを押すだけで以下のような結果が得られます。

$ docker
attach      deploy      images      logs        push        secret      tag
build       diff        import      network     rename      service     top
checkpoint  events      info        node        restart     stack       trust
commit      exec        inspect     pause       rm          start       unpause
config      export      kill        plugin      rmi         stats       update
container   help        load        port        run         stop        version
cp          history     login       ps          save        swarm       volume
create      image       logout      pull        search      system      wait

オプション

例えば、 docker images のオプションがわからなくなった場合、 docker images -- と打ってtabボタンを押すだけで以下のような結果が得られます。

$ docker images --
--all       --digests   --filter    --format    --help      --no-trunc  --quiet

まとめ

dockerコマンドはサブコマンドやオプションが充実している分、覚えるのは難儀です。
ですので、補完をうまく使って、快適なdockerライフを送りましょう。

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

コンテナにログインして内部を調査できるワンライナー

どうも、若松です。

コンテナイメージを作成するときはDocekerfileを作成すると思いますが、その前にベースイメージ内部を確認したいことが多いと思います。

そこで、ベースイメージをpullした状態からコンテナへログインするワンライナーをご紹介します。

AmazonLinux2コンテナへログインするワンライナー

docker run -it amazonlinux:2 /bin/bash

AlpineLinuxコンテナへログインするワンライナー

docker run -it alpine /bin/sh

まとめ

ベースイメージにログインできるとDockerfileを作成するための材料が揃えやすいので、このワンライナーは有用かと思います。

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

作成したLaravelコンテナを軽量化する

どうも、若松です。

前回はDockerでLaravelを起動するまでをまとめました。
https://qiita.com/t_wkm2/items/9b2011af9569627fee40

しかしながら、現在のコンテナイメージはお世辞にも軽量とは言えません。
コンテナイメージサイズはコンテナ起動時間に直結するため、できるだけ軽量化していきたいと思います。

Dockerfile

FROM amazonlinux:2 as vender

# PHPインストール
RUN amazon-linux-extras install -y php7.3
RUN yum install -y php-pecl-zip php-mbstring php-dom

# Composerインストール
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer

# 環境変数設定
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME "/opt/composer"
ENV PATH "$PATH:/opt/composer/vendor/bin"

# Laravelインストール
RUN composer global require "laravel/installer"

# Laravelプロジェクト作成
WORKDIR /var/www
RUN composer create-project laravel/laravel laravel

FROM php:7.3-alpine

# ビルド用コンテナから必要なコンテンツをコピー
COPY --from=vender /opt/composer/vendor/ /opt/vender/
COPY --from=vender /var/www/ /var/www/

# ポートを公開
EXPOSE 8000

# Laravelサーバーを実行
WORKDIR /var/www/laravel
CMD ["php","artisan","serve","--host","0.0.0.0"]

軽量化に際して覚えておくこと

マルチステージビルド

マルチステージビルドは、一般的にビルドに必要なコンテンツの生成フェーズと実行に必要なコンテンツに絞ってコンテナを固めるフェーズに分けてコンテナをビルドすることを指します。
ビルド時に必要だが実行時にには必要ない(一般的にDeveloperKitのような)ものを実行するコンテナから除外できるため、コンテナイメージの軽量化が期待できます。

squashオプション

Dockerfileでビルドする際、Step毎にコンテナのレイヤーが生成され、最終的なコンテナはそのレイヤーを含むためにサイズが肥大化しがちです。
ビルド時にsquashオプションを用いると、最終的にレイヤー1つに集約してくれるため、コンテナイメージの軽量化が期待できます。

Alpine Linux

詳細は割愛しますが、軽量OSとしてコンテナ界隈では有名です。
https://ja.wikipedia.org/wiki/Alpine_Linux

Alpine Linuxをベースとすることで、その他のイメージをベースとするよりも、コンテナイメージの軽量化が期待できます。

Dockerfile詳細

ビルド用イメージ

FROM amazonlinux:2 as vender

前回同様、AmazonLinux2をベースとしていますが、後段でしようするためにエイリアスとして as vender を付けています。

省略

# PHPインストール
# Composerインストール
# 環境変数設定
# Laravelインストール
# Laravelプロジェクト作成
# ポートを公開
# Laravelサーバーを実行

上記は前回と同じなため、解説を省略します。

実行用イメージ

FROM php:7.3-alpine

PHP公式から提供されているAlpineLinuxのイメージを使用します。
これによってAlpineLinux且つPHP7.3の環境を構築できます。

ビルド用コンテナから必要なコンテンツをコピー

COPY --from=vender /opt/composer/vendor/ /opt/vender/
COPY --from=vender /var/www/ /var/www/

前段のビルド用コンテナから必要なコンテンツをコピーします。
ここで前段で用いた、 as vender 効力を発揮します。

コンテナビルド

docker build -t laravel . --squash

ビルド時に --squash オプションを付加します。
これによってレイヤーを1つに集約し、計量化を図ります。

軽量化前と軽量化後の比較

軽量化前

docker images laravel
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
laravel         latest              xxxxxxxxxxxx         xx seconds ago        748MB

軽量化後

docker images laravel
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
laravel         latest              xxxxxxxxxxxx         xx seconds ago        117MB

まとめ

少しの工夫でコンテナが軽量化できることがわかっていただけたと思います。
最初にも述べたように、コンテナイメージサイズはコンテナ起動時間に直結するため、積極的に軽量化を図っていきたいですね。

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