20191128のdockerに関する記事は8件です。

php7.4のLaravel環境をDockerでつくる

はじめに

DockerでLaravel環境作ってログインできるまでをハンズオン形式で進めます。
ローカル環境ちゃちゃっと作って開発したい人向けなので、詳細説明はありません。
せっかくなので最近リリースされたPHP7.4を使ってみます。

環境

  • php7.4
  • Apache2
  • MySQL5.7

0. 事前準備

0-1. Dockerインストール

Mac,Windows ProならDocker、Homeならdocker toolbox
dockerならHyper-V設定も忘れずに

会社でよくあるWindowsProなら↓を参考に
https://www.koreyome.com/web/docker-install-for-windows/
0. CPU仮想環境設定を確認
1. Hyper-V設定
2. Dockerインストール
3. docker-compose

インストール確認

$ docker-compose -v

0-2. VSCodeのターミナルを準備(任意)

初心者でもつまずかないよう統一して VSCode の Terminal を git bash にしています。
GitBashは入っている前提です。

  1. setting表示 (Ctl+,)
  2. terminal.integrated.shell.windows 入力
  3. Edit in settings.json 選択
  4. GitBash 選択
    (例) "terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe"
  5. Terminal表示(Ctl+Shift+@)
  6. 1:bash になる

1. ディレクトリ構成とファイル作成

githubからcloneするか、ファイルを作成してください。

1-1. クローンする場合

git clone https://github.com/qvtec/laravel-docker-base.git

2-1. ファイルを作成する場合

ディレクトリ構成は下記のようになります

docker
├── db
│   └── my.conf
├── php-apache
│   ├── 000-default.conf
│   ├── default-ssl.conf
│   ├── php.ini
│   └── Dockerfile
├── .env
└── docker-compose.yml

Dockerfile 作成

composer も node もインストールしているので、別コンテナにしてもいいかもしれません

Dockerfile
FROM php:7.4.0-apache

COPY ./php.ini /usr/local/etc/php/
COPY ./sites/*.conf /etc/apache2/sites-available/

ARG TZ=Asia/Tokyo
ARG NODE_VERSION=8.x

RUN set -xe; \
    apt-get update -yqq && \
    apt-get install -yqq --no-install-recommends \
      apt-utils vim gettext git \
      default-mysql-client \
      # for gd
      libfreetype6-dev \
      libjpeg62-turbo-dev \
      libpng-dev \
      libwebp-dev \
      libxpm-dev \
      # for ImageMagick
      libmagickwand-dev \
      # for zip
      libzip-dev zip unzip \
      # for oniguruma
      libonig-dev \
    && docker-php-ext-install bcmath gettext mbstring mysqli pdo pdo_mysql zip \
    && docker-php-ext-configure mbstring --disable-mbregex \
    && docker-php-ext-configure zip --with-libzip \
    # gd
    && docker-php-ext-install -j$(nproc) iconv \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
    # imagick
    && pecl install imagick \
    && docker-php-ext-enable imagick \
    # enable mod_rewrite
    && a2enmod rewrite \
    # enable ssl
    && a2enmod ssl \
    # enable site
    && a2ensite default-ssl \
    # for ssl
    && apt-get update \
    && apt-get -y install ngrep \
    && openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "/C=JP/CN=localhost" \
        -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt \
    # set timezone
    && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
    # node
    && curl -sL https://deb.nodesource.com/setup_$NODE_VERSION | bash - \
    && apt-get install -y nodejs npm \
    # install composer
    && cd '/' \
    && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer

ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin

# laravel installer
RUN composer global require "laravel/installer" \
    && composer global require "laravel/envoy"

WORKDIR /var/www/html

docker-compose.yml 作成

docker-compose.yml
version: '3'

services:
  work:
    build:
      context: ./php
    volumes:
      - ${PROJECT_PATH}:/var/www/html:cached
      - node_modules:/var/www/html/node_modules
    ports:
      - ${WEB_PORT}:80
      - ${WEB_SSL_PORT}:443
    depends_on:
      - mysql

  mysql:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASS}
      TZ: ${TZ}
    ports:
      - ${DB_PORT}:3306

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=root
      - PMA_PASSWORD=root
    ports:
      - ${PMA_PORT}:80

  redis:
    image: redis:latest
    ports:
      - ${REDIS_PORT}:6379
    volumes:
      - redis_data:/data
    command: redis-server

volumes:
  mysql_data:
  node_modules:
  redis_data:

.env 作成

COMPOSE_PROJECT_NAME はプロジェクト名に変更する
使っていないポートにする

.env
COMPOSE_PROJECT_NAME=laravel-docker-base
PROJECT_PATH=../src

WEB_PORT=80
WEB_SSL_PORT=443
DB_PORT=3306
PMA_PORT=8080
REDIS_PORT=6379

TZ=Asia/Tokyo
DB_NAME=docker
DB_USER=docker
DB_PASS=secret

apache conf 作成

httpとhttpsの両方を作成します

000-default.conf
<VirtualHost *:80>
  ServerName local.test.com
  DocumentRoot /var/www/html/public/

  <Directory /var/www/html/public>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  ErrorLog /var/log/apache2/error.log
  CustomLog /var/log/apache2/access.log combined
</VirtualHost>

ssl が不要の場合は、下記ファイルが不要で
Dockerfile の a2ensite default-ssl と # for ssl の項目を削除する

default-ssl.conf
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        ServerName local.test.com
        DocumentRoot /var/www/html/public
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/access.log combined
        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
        SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>

        <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
        </Directory>
        Options Indexes FollowSymLinks

        <Directory "/var/www/html/public/">
            AllowOverride All
            Require all granted
        </Directory>
    </VirtualHost>
</IfModule>

php 設定ファイル

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

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

mysql 設定ファイル

my.conf
[mysqld]
character-set-server=utf8
datadir = /var/lib/mysql

2. Docker起動

2-1. docker設定ファイルの作成

cloneしている場合は.env.exampleをコピーして.envを修正する

cd docker/
cp .env.example .env

2-2. ビルドと起動

docker-compose up -d --build

2-3. コンテナ接続

docker-compose exec work bash

3. Laravelインストール

workコンテナで実行する

3-0. Laravelプロジェクト作成

laravel new

3-1. Laravel設定ファイル

cp .env.example .env
DB_HOST=mysql
DB_USSERNAME=root
DB_PASSWORD=root

CACHE_DRIVER=redis
REDIS_HOST=redis

MAIL_DRIVER=log

3-2. composer install

composer dump-autoload
composer install

3-3. マイグレーション

php artisan migrate

4. hosts設定と表示

127.0.0.1 local.admin.com

https://local.admin.com/

表示できましたか?

エラー対応

ハンズオンでエラーになった人がいたので対処法

ERROR: for web Cannot create container for service web: b'Drive sharing failed for an unknown reason'
ERROR: Encountered errors while bringing up the project.

bドライブ使ってないと思うので、dockerの設定変更が必要
http://kdnakt.hatenablog.com/entry/2019/09/12/080000

xamppでmysqlが接続できなくなった

ポート変更が必要
.envで3306→3316とか使ってないポートに変更する

さいごに

laradockを使っていましたが遅かったので、phpの公式のphp-apacheを使うようになりました。
まだdocker歴が短いので、ベストな状態かはわかりません。
なにかあれば教えてください。

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

Ubuntu の Desktop 環境を Docker で

本日は

を参考に自分の環境でも再現したよ〜報告を書きます.Ubuntuさん基本的にターミナルベースでしか使わないので応用はとくに考えてないのですが・・・

環境

ホスト:macOS Catalina
Docker: Docker version 19.03.5, build 633a0ea

Dockerfile

FROM ubuntu:16.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
    ubuntu-desktop \
    samba-common-bin \
    x11-apps \
    sudo

ARG uid=1000
ARG gid=1000
RUN groupadd -g ${uid} developer && \
    useradd -u ${gid} -g developer -G sudo -r developer && \
    mkdir -p /home/developer/.config/nautilus &&\
    chown ${uid}:${gid} -R /home/developer && \
    mkdir -p /var/lib/samba/usershares

RUN echo 'Defaults visiblepw'             >> /etc/sudoers
RUN echo 'developer ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# set locale to initialize terminal property
RUN locale-gen en_US.UTF-8  
ENV LANG en_US.UTF-8  
ENV LANGUAGE en_US:en  
ENV LC_ALL en_US.UTF-8

USER developer
WORKDIR /home/developer

使い方

下記のようなシェルスクリプトを作っておきます.

init.sh
docker build -t udesk .
xhost + 127.0.0.1
HOSTDISPLAY=host.docker.internal:0
docker run --rm -it\
       -e DISPLAY=$HOSTDISPLAY \
       -v /tmp/.X11-unix/:/tmp/.X11-unix \
       --name udesk \
       udesk /bin/bash -c "nautilus"
xhost - 127.0.0.1

あとは bash init.sh でイメージのビルドから起動までできます.他のターミナルを開いておいて docker stop udesk で止めることができます.--rm オプションをつけてるので終わるとコンテナが消えてしまいます.ですので引き続き使いたい人は --rm を取り除いてコンテナを再起動する感じでお願いします.

  • 上の init.sh で書いている xhost +/ xhost - のテクニックはDocker のコンテナで matplotlib の描画結果を表示させたいな場合にも応用が効きますね.
  • Linux がホストの場合は xhost + local:docker/ xhost - local:docker とか HOSTDISPLAY=$DISPLAY としておくとうまくいくはずです.

References

References for those who would like to try with XForwarding

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

docker上にoracle環境を構築

docker上にoracle環境を構築

目的

お仕事でOracleに触れる機会が増えたのでWindows上で気軽に操作できる環境を作ってみる。
方法としては、Windows版の評価版Oracleを導入したり、VMWareなどの仮想環境上に構築する案もあるがdockerを利用することにした。dockerでのデータ永続化の方法を中心に検証してみる。

参考サイト

上記のサイトを参考に、最低限必要な以下のファイルを改造してデータ永続化のいい方法が無いか試みる。

  • docker-images/OracleDatabase/SingleInstance/dockerfiles/12.2.0.1
  • docker-images/OracleDatabase/SingleInstance/dockerfiles/buildDockerImage.sh

目標

Oracleのコンテナを破棄してもデータは永続化されていて、次にOracleのイメージよりコンテナを起動した時に、きちんとデータが引き継がれていること。
イメージ的には、以下のようなOracleを起動したり、データのバックアップ・リストアが行えること。

Oracleの起動

1.データ永続用のoradataボリュームの作成

$ docker volume create oradata

2.oracle起動

(1) 初回起動時

docker run -ti --rm --name oracle12c -p 1521:1521 \
       -e ORACLE_SID=TEST \
       -e ORACLE_PDB=SAMPLE \
       -e ORACLE_CHARACTERSET=JA16EUCTILDE \
       -v oradata:/opt/oracle/oradata \
      oracle/database:12.2.0.1-se2

(2) 次回からの起動

docker run -d --name oracle12c -p 1521:1521 -v oradata:/opt/oracle/oradata oracle/database:12.2.0.1-se2

3.パスワード変更

パスワードをREADME.mdに記載の通り docker の run での環境変数(-e ORACLE_PWD=<your database passwords>)で指定すると、docker exec で接続し、envと叩くとパスワードが見えるので、パスワードは後から設定する。

$ docker exec -ti oracle12c ./setPassword.sh 'P@ss2wd'
The Oracle base remains unchanged with value /opt/oracle
SQL*Plus: Release 12.2.0.1.0 Production on Thu Nov 28 09:41:24 2019
Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Connected to:
Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
SQL> 
User altered.
SQL> 
User altered.
SQL> 
Session altered.
SQL> 
User altered.
SQL> Disconnected from Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
$

データバックアップ・リストア

以下のようにexpdp/impdpでバックアップ・リストが行えるようにする。

  • バックアップ
$ expdp system DUMPFILE=dmp_db.dmp LOG=exp.log FULL=Y
  • リストア
$ impdp system DUMPFILE=dmp_db.dmp LOG=exp.log FULL=Y

検討事項

その1

runOracle.sh を見てみると、以下のようになっているから毎回runするときは、同じ値が環境変数ORACLE_SIDに設定されている必要がある。

# Check whether database already exists
if [ -d $ORACLE_BASE/oradata/$ORACLE_SID ]; then
   symLinkFiles;
....
else
  # Remove database config files, if they exist
....
  # Execute custom provided setup scripts
  $ORACLE_BASE/$USER_SCRIPTS_FILE $ORACLE_BASE/scripts/setup
fi;

本当は、$ORACLE_BASE/oradata/dbconfig/XXXX があれば、パスからXXXXの部分を環境変数ORACLE_SIDを設定して欲しいが、runOracle.shで未設定の場合デフォルトでは以下のように決め打ちで設定している。

# Default for ORACLE SID
if [ "$ORACLE_SID" == "" ]; then
   export ORACLE_SID=ORCLCDB
else
....

setPassword.sh には、以下のような処理があるので、取得できないことはないようだ。

ORACLE_SID="`grep $ORACLE_HOME /etc/oratab | cut -d: -f1`"

しかし、/etc/oratab は runOracle.sh で以下のようにして作成しているので先に、環境変数ORACLE_SIDが必要になる。。。。

cp $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/oratab /etc/oratab

その2

expdp/impdpのデフォルトでのデータ出力先は /opt/oracle/admin/$ORACLE_SID/dpdump になっているため、コンテナを破棄した時に消えてしまう。

デフォルトの出力先を /opt/oracle/oradata/$ORACLE_SID/dpdump にどうやって変更するか。

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

Node.jsでMySQLに接続するのをDockerでやってみた

この記事は富士通クラウドテクノロジーズ Advent Calendar 2019 5日目の記事です。
4日目は @tmtms さんの MySQL Parameters を拡張した でした。

はじめに

  • ※本記事は、 Node.js超入門[第2版] のサンプルコードをDocker上で動かす趣旨のものです。 よって、書籍で言及されている階層は触れません。

はじめまして。Node.jsを勉強中の新卒エンジニアです。
配属したてホヤホヤです。
今回は Node.js超入門[第2版] を使って勉強したときの話をします。

この書籍の内容をDockerで実現しようとした経緯ですが、そのまま「Dockerを理解したかったから」です。
弊社の研修でもDockerについて触れていただいたのですが、一度教わっただけでは理解が難しいものでした。
というわけで、サンプルコードを写経するだけになりがちだった(主観です)プログラミングの本で、ついでに理解を深めようという魂胆です。

今回は、書籍の Chapter5「値とデータをマスターしよう!」の、Section5-3~5-4 で書かれている、Node.jsでDBにアクセスして情報を取得し、ブラウザに表示するプログラムを紹介します。書籍が手元にある方はぜひ確認してみてください。

環境構築

必要な環境

参考記事:

解説

  • 今回は、Node.jsもMySQLも、Dockerコンテナとして生成しています。
  • Node.jsサーバーは、 docker-compose.yml から Dockerfile を呼び出す形で書き、MySQLサーバーは docker-compose.yml 内で定義しています。
  • docker-compose.yml で指定するMySQLのDockerイメージは、MySQLのバージョンが8よりも前になるように古いものを使っています。 8以降はそのままだとNode.jsとの連携ができないようです。
  • init-mysql.sh は、ローカル環境から、データベース用のコンテナにアクセスし、テーブル作成->データ挿入までを行っています。
  • 実は、docker/db/my.cnfdocker-compose.yml の2か所で mysqld を設定しているのですが、どちらかを消すとなぜかエラーになってしまうため(!)そのままにしてあります。いい方法ががありましたら教えていただけると幸いです・・・。
  • 余談ですが、今回のコードは、いままで述べてきたものとは別のDockerfileでExpress-generatorを実行し、 docker cp でローカルにファイルをコピーしてから作成していきました。 めんどうくさいことをしたなと自分で思います。

動作確認

  • 上記のリポジトリをcloneします。
  • リポジトリに移動
  • docker-compose up -d でコンテナを立ち上げます。
  • すこし(10秒ほど)時間をおきます。(コンテナが出来上がるまで待つ)
  • ローカルで ./init-mysql.sh を実行します。
  • localhost/hello にアクセスし、 docker/db/sql/002-insert-records.sql で入れたデータが表示されていることを確認してください。
  • ↓ こんなふうに表示されます。

image.png

おわりに

まず、Node.jsについての書籍を読み、サンプルを実行してみることで、Node.jsの挙動についてざっくりと理解できるようになりました。
加えて、それらをDocker上の環境で行うことで、
いままで「VirtualBoxより軽い仮想化するアプリケーション?」という認識だったDockerについての理解も深まりました。
Linuxのコンソールの扱いも以前よりわかるようになってきました。
やっと .profile.vimrc をカスタマイズできるようになり、快適なUbuntu生活をしております。

また、試行錯誤して、調べたり人に聞いたりしていくことが学びへの近道だと実感しました。
例えば、MySQLのバージョンに関しては自分では調べきれず、先輩方の知恵をお借りしました。
ありがとうございました。

まだまだエンジニアとしては若輩者ですが、これからもっと勉強してスキルをつけ、開発をたくさんしていけたらと思います。

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

Vue.jsの開発環境をDockerで構築する手順

Vue.jsの開発環境をDockerで構築する手順を整理します。

実際に環境構築した後のソースコードはこちら

事前準備

Dockerで開発環境を構築するために必要な事項を確認します。

Vue CLI

今回は Vue CLI でアプリを作ります。

Vue CLI をインストールしてない場合は、そのインストールからおこないます。(ついでに @vue/cli-init もインストールします。)

sudo npm install -g @vue/cli @vue/cli-init

バージョン確認できれば、正常にインストールできています。

vue -V
@vue/cli 4.0.5

インストール後、webpack-simple でアプリを作成します。

vue init webpack-simple your_app_name

Docker

Docker をインストールしていない場合は、Docker Desktop on Mac もしくは Docker Desktop on Windows 等からインストールしてください。

バージョン確認できれば、正常にインストールできています。

docker version

合わせて docker-compose コマンドが使えることも確認しておきます。

docker-compose --version

開発環境 Docker 化の手順

それでは本題に入り、Vue.jsの開発環境をDockerで構築する手順を整理します。

1. vue-cli-service のインストール

まず Docker コンテナ内で Vue.js を起動するのに必要な vue-cli-service をインストールします。

npm install --save @vue/cli-service

インストール後、package.jsonscripts.serve の設定を追加します。(該当箇所以外は省略してます。)

package.json
{
  "scripts": {
    "serve": "node_modules/.bin/vue-cli-service serve"
  }
}

2. webpack のインストール

アプリ起動時にコンパイルエラーが出ないように、webpack を追加しておきます。

npm add webpack@latest

3. Docker の設定

必要な下準備が整ったので、Docker の設定ファイルを書いていきます。

Dockerfile.dev の作成

アプリのルートディレクトリに Dockerfile.dev を作成します。

Dockerfile.dev
FROM node:10.17.0-alpine3.9

# make the 'app' folder the current working directory
WORKDIR /app

# copy both 'package.json' and 'package-lock.json' (if available)
COPY package*.json ./

# install project dependencies
RUN npm install

# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . .

CMD ["npm", "run", "serve"]

  • FROM Docker イメージのベース(バージョンは DockerHub で選んでください)
  • WORKDIR ワーキングディレクトリの作成
  • COPY package*.json ./ 依存関係のコピー
  • RUN npm install 依存関係のインストール
  • COPY . . Docker コンテナ内にファイルを渡す
  • CMD ["npm", "run", "serve"] コマンドでサーバ起動

.dockerignore の作成

また、.dockerignore を作成し、無視してOKなファイルを Docker に知らせます。

.dockerignore
node_modules
.git
.gitignore

Docker の設定は以上です。

4. Dockerコンテナ内で起動

コマンドを叩けば、Docker コンテナ内で Vue.js のアプリを起動できます。

docker build

まず、Dockerfile.dev から Docker イメージをビルドします。

docker build --tag your_app_name:latest --file Dockerfile.dev .
  • --tag タグ名(タグをつけて build すれば、その名前で run できる)
  • --file 設定ファイルを指定(デフォルトは Dockerfile

docker run

ビルドした Docker イメージを使ってコンテナを起動します。

docker run --rm -it --name your_app_container -p 8080:8080 -v ${PWD}:/app -v /app/node_modules your_app_name:latest
  • --rm 終了時にコンテナを自動削除
  • -i ターミナルのテキストコマンドをコンテナに入力
  • -t いい感じのフォーマットでターミナルに出力
  • --name コンテナに名前をつける
  • -p ポートマッピング
  • -v Docker ボリューム(ローカルのコードを参照させれば、変更をただちに反映可)
  • $(PWD) present working directory

問題なければ、ブラウザから http://localhost:8080/ でアクセスできます。Yay!

localhost:8080

ターミナルで Ctrl + C でコンテナを終了できます。

docker-compose でより簡単に起動

毎回毎回 docker build...docker run... とコマンドを叩くのは面倒なので、docker-compose を使ってより簡単に起動できるようにします。

docker-compose の設定

docker-compose.yml をルートディレクトリに作成し、Docker コマンドの内容を YML 形式で記述します。

docker-compose.yml
version: '3.7'

services:
  web:
    container_name: web
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - '.:/app'
      - '/app/node_modules'
    ports:
      - '8080:8080'

設定はこれだけです。

docker-compose コマンド

これにより以下のコマンドが使えます。

docker-compose up

コンテナの起動します。

docker-compose up

先ほどと同様にhttp://localhost:8080/ でアクセスできます。

かなりシンプルになりました。

docker-compose up --build

コンテナを再ビルドして起動します(変更を反映させられる)。

docker-compose up --build

docker-compose up -d

コンテナをバックグラウンドで起動します。

docker-compose up -d

docker-compose down

コンテナを終了させます。

docker-compose down

docker-compose にテストを追加

docker-compose.ymltest サービスを追加し、そのコンテナ内でテストを実行できるようにします。

docker-compose.yml
version: '3.7'

services:
  web:
    container_name: web
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - '.:/app'
      - '/app/node_modules'
    ports:
      - '8080:8080'
  test:
    container_name: test
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - '.:/app'
      - '/app/node_modules'
    command: ["npm", "run", "test"]

※ *Vue.js でのテストのセットアップ手順は、「Vue.js ユニットテストの基本まとめ」参照

次のコマンドでテスト用のコンテナサービスを起動できます。

docker-compose up test

サービス名を指定しない場合は、web・test の両サービスが起動します。

docker-compose up

トラブルシューティング

発生する可能性のあるエラーとその解決方法をまとめておきます。

エラー(その1)

エラー内容

docker run 実行時に vue-cli-service がないと怒られる場合。

sh: vue-cli-service: command not found

解決方法

vue-cli-service をインストールすることで解決します。

npm install --save @vue/cli-service

エラー(その2)

エラー内容

docker run 実行時に script: serve がないと怒られる場合。

npm ERR! missing script: serve

解決方法

package.jsonscripts.serve を追加することで解決します。

package.json
{
  "scripts": {
    "serve": "node_modules/.bin/vue-cli-service serve"
  }
}

エラー(その3)

エラー内容

docker run 実行時に compilation.templatesPlugin... のコンパイルエラーが起きる場合。

ERROR  Failed to compile with 1 errors 
  TypeError: compilation.templatesPlugin is not a function

解決方法

Webpack を追加することで解決します。

npm add webpack@latest

エラー(その4)

エラー内容

docker-compose up 実行時にコンテナ名が被っていると怒られる場合。

ERROR: for web  Cannot create container for service web: Conflict. The container name "/web" is already in use by container "f4acb3dbb5". You have to remove (or rename) that container to be able to reuse that name.

解決方法

名前が重複しているコンテナを取り除くことで解決します。

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

cute-filesをオフラインで使う

はじめに

オフライン環境で複数のメンバーにファイルを配るためにcute-filesを使ってみました。

ベースとなる環境はこちらの記事を元に構成しました。

webブラウザさえあればアクセス可能なのでお手軽ですね。。。と思っていたのですが、オフラインでアクセスできず。

どうやらindex.html内で「jquery-1.11.0.min.js」をクライアントにGETさせているのですが、そのURLがインターネット上のものでした。
なので、ローカルに保存した「jquery-1.11.0.min.js」を読み込ませるように少し手を加えてみました。

ファイル構成

/どこか/cutefiles
           |--cutefiles
           |  |--Dockerfile
           |  |--index.html
           |  |--jquery-1.11.0.min.js
           |--docker-compose.yml

/data/cutefiles
           |--配布したいファイル

docker-compose.yml

data-cutefiles:
  image: busybox:buildroot-2014.02
  volumes:
      - /data/cutefiles:/cutefiles
cutefiles:
  build: cutefiles
  volumes_from:
    - data-cutefiles
  ports:
    - "3000:3000"

Dockerfile

FROM node:4.4
RUN npm install -g cute-files2@1.0.3
RUN sed -i 's/http:\/\//\/\//g' \
        /usr/local/lib/node_modules/cute-files2/frontend/index.html
RUN mv /usr/local/lib/node_modules/cute-files2/frontend/index.html /usr/local/lib/node_modules/cute-files2/frontend/index.html.org
COPY ./jquery-1.11.0.min.js /usr/local/lib/node_modules/cute-files2/frontend/
COPY ./index.html /usr/local/lib/node_modules/cute-files2/frontend/
WORKDIR /cutefiles
EXPOSE 3000
CMD ["/usr/local/bin/cute-files"]

index.html

「script src="jquery-1.11.0.min.js」が元のindex.htmlから変更した箇所になります。

<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>Cute file browser</title>
    <!-- Include our stylesheet -->
    <link href="assets/css/styles.css" rel="stylesheet"/>
  </head>
  <body>
    <div class="filemanager">
      <div class="search">
        <input type="search" placeholder="Find a file.." />
      </div>
      <div class="breadcrumbs"></div>
      <ul class="data"></ul>
      <div class="nothingfound">
        <div class="nofiles"></div>
        <span>No files here.</span>
      </div>
    </div>
    <!-- Include our script files -->
    <script src="jquery-1.11.0.min.js"></script>
    <script src="assets/js/script.js"></script>
  </body>
</html>

jquery-1.11.0.min.js

こちらからダウンロードして配置する。



オフラインでもjqueryファイルをクライアントが読み込むことができるようになるので、ページも表示できるようになりました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】もっと早く知りたかったデバッグ用gem 'better_errors','binding_of_caller'

はじめに

先日伊藤さんのこちらの動画(↓)を見ました。
プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意 - YouTube

「いや、なんでもっと早く見なかった!」と思うくらい具体的なデバッグ手法が諸々解説されています。

そこで出てきたgem better_errors&binding_of_callerの導入方法と見方について簡単にまとめます。

今まで

  • puts デバッグ
  • binding.pry
  • rails serverのログ

を使ってエラーと闘っていましたが、この2つのgemはもっと早く知りたかったです:sweat_smile:

この記事が役に立つ方

  • エラーに苦しんでいるRails初心者

この記事のメリット

  • デバッグの効率が上がる

環境

  • macOS Catalina 10.15.1
  • zsh: 5.7.1
  • Ruby: 2.6.5
  • Rails: 5.2.3
  • Docker: 19.03.5

better_errorsとは?

デフォルトのエラー画面をわかりやすく整形してくれるgem。

binding_of_callerとは?

上記better_errorsと一緒に使うことで、ブラウザ上でirbを使えるようになるgem。
※本記事では使用方法について触れていません。

導入方法

Gemfile
group :development do
  gem 'better_errors'
  gem 'binding_of_caller'
end

Gemfileに上記追記し、

bundle install

で完了。簡単!

※Dockerを使用している場合はもうひと手間必要

app/config/environments/development.rb
BetterErrors::Middleware.allow_ip! "0.0.0.0/0"

仮想環境を使っている方は、うまく動作しないようです。
私はDockerを使っていますが、上記コードを追記してサーバー再起動で動作しました。
Gem 『Better errors』が動かないとき | HippoBlog

使用例

ArgumentErrorが出ていた場合

form_withを使おうとしたらエラーが出た場合を例にします。

いつもの赤いエラー画面から表示が変わっています。
スクリーンショット 2019-11-28 14.54.16.png

エラーメッセージが最上部にあるのは変わりませんが、
その下に2つタブがあります。これが超便利。

  • Application Frames
  • All Frames

1. Application Frames

最初はApplication Framesが表示されています。
ここでは、自分の書いたコードを対象にエラーに関係する箇所を明示してくれています。
スクリーンショット 2019-11-28 14.54.16.png

2. All Frames

次に、All Framesをクリックすると、自分が書いた箇所以外(gemやActiveSupportなど)まで踏み込んでエラーに関係する箇所が表示されます。

それぞれクリックしていくとコードが表示されます。

例えば今回は、form_withのソースコードまで表示してくれます。
スクリーンショット 2019-11-28 14.55.22.png

form_withの最初の1行を抜き出すとこんな感じです。

def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block)

これで指定すべき引数がわかり、今回は

「いけね!そういえばmodel:って書き忘れた!」

と気づくことが出来ます。便利!


その他、NoMethodError~ for nil:NilClassとか出ていたら、ブラウザでそのまま変数の中身を確認したり出来て非常に便利です。
スクリーンショット 2019-11-28 15.57.41.png
※画像最下部がコンソールになっています。

おわりに

最後まで読んで頂きありがとうございました:bow_tone1:

デバッグ手法は学び始めの段階でなるべく多くリストアップしておいたほうが効率がいいと思いますが、better_errorsはもっと早く導入していたかったです:sweat_smile:

伊藤さんのYoutube、非常に勉強になるのでまた他の動画も見させて頂きます。

参考にさせて頂いたサイト(いつもありがとうございます)

プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意 - YouTube
プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意(解説動画付き) - Qiita
Gem 『Better errors』が動かないとき | HippoBlog
【Rails】better_errorsとbinding_of_callerで自分でエラーを解決できるようになろう【初心者向け】 - Qiita

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

Azure VM(Ubuntu 18.4 LTS)にGPU対応Docker環境を構築する

環境

Azure Virtual Machine Ubuntu 18.4 LTS (VMサイズ: NV6_Promo)
Docker version 19.03.5
Tesla M60
NVIDIA-SMI 440.33.01
Driver Version: 440.33.01
CUDA Version: 10.2

モチベーション

Azure Platformには、Data Science Virtual Machines(DSVM)というGPUを利用したMachine Learning開発環境向けの各種ドライバやライブラリ等がプリインストールされている便利なVirtual Machineがあるのですが、残念ながらLinux版ではPythonのバージョンが3.5なのです・・・。
f文字列とか多用しているのでとても困ってしまいます。
試しにDSVMでPythonのバージョンだけ上げようかとチャレンジしたのですがイバラの道が見えたので即時撤退しました。
DSVMはMachine Learningの開発/実行環境が即座に構築できるのがウリであり、その分お値段も無印VMよりだいぶ盛っているのに、これではとてもやっていられません。
ということで、無印VMにMachine Learning環境を構築することにしました。

構築手順

Azure Portal上で実行可能な部分については割愛します。
VMを作成してsshでログインしたところからのスタートです。

[ディスクマウント]

システムディスクだけで充分だよ! という方はこの項は飛ばしてください。
NV6_Promo(というか大体のAzure VM)ではOSディスクとして30GiBしか割り当てられていません。
ちょっとこれだと心許ないので、データディスクを追加して利用することがほとんどだと思います。
それは良いんですが、Linux環境だとVMを作るたびに毎度毎度、手作業でディスクをマウントしないといけないので面倒です。なんとかなりませんか?

それはさておき、ディスクをマウントしていきましょう。

対象ディスクの探索

対象のディスクを探すために下記コマンドでSCSI ディスクの一覧を出力させます。
追加したデータディスクが一つであれば、sdcが対象のディスクなので飛ばしてしまっても構いません。
この項での紹介もsdcであることを前提に進めていきます。
異なる場合は適宜、書き換えて実行してください。

コマンド
dmesg | grep SCSI

パーティション分割

fdiskでパーティション分割していきます。
標準入力でコマンドの入力を求められるので、下記の通りに入力していきます。

コマンド
sudo fdisk /dev/sdc
標準入力
Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-10485759, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-10485759, default 10485759):
Using default value 10485759
標準入力
Command (m for help): p

Disk /dev/sdc: 5368 MB, 5368709120 bytes
255 heads, 63 sectors/track, 652 cylinders, total 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x2a59b123

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            2048    10485759     5241856   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

mkfs コマンドを使用してパーティションにファイル システムを書き込みます。
追加したデータディスクが一つであれば、下記コマンドをそのままコピペで実行してください。

コマンド
sudo mkfs -t ext4 /dev/sdc1

ディスクのマウント

rootディレクトリにdatadriveという名前のディレクトリを作成し、そこをマウントポイントとしてドライブをマウントします。
ディレクトリの名前は任意のもので構いません。

コマンド
sudo mkdir /datadrive
sudo mount /dev/sdc1 /datadrive

VM再起動時も自動でドライブがマウントされるように設定します。
blkid ユーティリティでドライブのUUIDを確認します。
下記の出力例と実際のUIIDは異なるので、出力例をコピペしないように注意してください。

コマンド
sudo -i blkid
出力例
/dev/sda1: UUID="11111111-1b1b-1c1c-1d1d-1e1e1e1e1e1e" TYPE="ext4"
/dev/sdb1: UUID="22222222-2b2b-2c2c-2d2d-2e2e2e2e2e2e" TYPE="ext4"
/dev/sdc1: UUID="33333333-3b3b-3c3c-3d3d-3e3e3e3e3e3e" TYPE="ext4"

vimで /etc/fstab ファイルを開きます。

コマンド
sudo vi /etc/fstab

/etc/fstab ファイルの末尾に下記の行を追加します。
尚、実際のUUIDは下記のものとは異なるため、くれぐれもそのままコピペしないように注意してください。

/etc/fstab
UUID=33333333-3b3b-3c3c-3d3d-3e3e3e3e3e3e   /datadrive   ext4   defaults,nofail   1   2

/etc/fstabファイルを保存して閉じたらVMを再起動してください。

コマンド
sudo reboot

ここまでの手順で問題がなければ、VMが無事に再起動し、新しいドライブがマウントしたことがdfコマンドで確認できると思います。

[Dockerのインストール]

続いて、Dockerをインストールしていきます。
apt-getを多用していますが、参考リンクのdocker docsおよびNVIDIA公式サイトのドライバインストール手順の記載内容を尊重してそのようにしています。
aptまったく使われてなくて草生えますよっと。

コマンド
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get install docker-ce docker-ce-cli containerd.io
docker -v

[Dockerイメージの保存場所を変更]

せっかくデータディスクを追加したのに、このままではOSディスクがDockerに食いつぶされてしまうのでDockerイメージ等の保存先を変更します。

データディスクをマウントしたディレクトリにdockerの保存場所を作成します。

コマンド
sudo mkdir /datadrive/docker

dockerのsystemdの設定ファイルをvimで開きます。

コマンド
sudo vi /lib/systemd/system/docker.service

ExecStartの実行コマンドを書き換えます。

docker.service
[変更前]
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

[変更後]
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -g /datadrive/docker

docker.serviceを保存して終了します。
後は設定を更新してデーモンを再起動すればOKです。

コマンド
sudo systemctl daemon-reload
sudo systemctl restart docker

データディスクにDocker関連のファイルが作成されていることを確認します。

コマンド
sudo ls -la /datadrive/docker/

[NVIDIAドライバをインストール]

UbuntuリポジトリからNVIDIAのドライバをインストールします。

コマンド
sudo apt install nvidia-headless-440 nvidia-utils-440

[DockerのNVIDIA対応のためのパッケージをインストール]

コマンド
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit

[CUDA 10.2をインストール]

コマンド
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb
sudo apt-key add /var/cuda-repo-10-2-local-10.2.89-440.33.01/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda
rm -f cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb

CUDAをインストールしたら~/.bashrcにパスを追加して再起動します。

~/.bashrc
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
コマンド
sudo reboot

再起動したらドライバの状態を確認します。

コマンド
nvidia-smi
出力例
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla M60           On   | 0000B7A7:00:00.0 Off |                  Off |
| N/A   35C    P0    47W / 150W |      0MiB /  8129MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

[Dockerコンテナの作成]

DockerコンテナはNVIDIAからUbuntu 18.4向けに公開されているリポジトリを利用して作成します。
コンテナの名前は任意です。

コマンド
sudo docker run --gpus all --name oreno-container --restart=always --privileged -d -t -i -v /datadrive/oreno-container:/datadrive nvidia/cuda:10.2-devel-ubuntu18.04 /bin/bash

動作確認

作成したコンテナからGPUを利用可能かを確認します。
nvidia-smiでドライバが認識されていたとしても実際には正常にセットアップされていない場合があるので注意が必要です。
今回は、darknetをインストールして正常に動作するかを確認しようと思います。

コンテナにログインします。

コマンド
sudo docker exec -it oreno-container /bin/bash

確認作業に必要なパッケージをインストールします。

コマンド
apt update && apt install -y git vim wget

続いてdarknetのソースコードをダウンロードします。

コマンド
cd /root
git clone https://github.com/pjreddie/darknet

darknetでGPUを利用するためにビルドの設定を変更します。

コマンド
cd darknet
vi Makefile
Makefile
[変更前]
GPU=0

[変更後]
GPU=1

Makefileを保存して終了したらビルドを実行します。

コマンド
make

ビルドに成功したらYOLOv3の学習済モデルをダウンロードします。

コマンド
wget https://pjreddie.com/media/files/yolov3.weights

画像の物体検出を行います。問題なく環境が構築されていれば出力例のように結果が出力されます。

コマンド
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
出力例
Loading weights from yolov3.weights...Done!
data/dog.jpg: Predicted in 0.270799 seconds.
dog: 100%
truck: 92%
bicycle: 99%

以上です。

参考リンク

[ポータルを利用し、データ ディスクを Linux VM に接続する]
https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/attach-disk-portal

[Get Docker Engine - Community for Ubuntu]
https://docs.docker.com/install/linux/docker-ce/ubuntu/

[Dockerイメージの格納先変更]
https://qiita.com/RyoMa_0923/items/e1174b2951411ddd1d08

[NVIDIA Docker]
https://github.com/NVIDIA/nvidia-docker

[CUDA Toolkit 10.2 Download and Install]
https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=deblocal

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