20200328のdockerに関する記事は19件です。

Docker上のRailsアプリにWebpackerを導入してみる

はじめに

この記事では、既存のRailsアプリにWebpackerを導入する手順を書いていきます。
WebpackerやWebpackを使用したことがない方向けです。

開発環境

Rails 5.2.3
ruby 2.5
mariadb 10.1
docker

Webpackerとは

Railsでwebpackを使用するためのgemパッケージです。
複数のjs,css,画像などを一つにまとめることにより、
ファイルの取得にかかる時間を短縮できるというメリットがあります。

実装

gemのインストール

まずアプリにgemパッケージをインストールします。

Gemfile
gem 'webpacker', '~> 4.x' 

Gemfileを更新したら、bundle installします。

yarnのインストール

Webpackerはyarnというnode.jsのパッケージマネージャを使用するそうなので、
Dockerにyarnをインストールするためのコマンドを追記します。

Dockerfile
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 && \
    apt-get update && apt-get install yarn

Webpackerの起動

docker-compose.yml
  webpacker:
    build: .
    environment:
      NODE_ENV: development
      RAILS_ENV: development
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    command: ./bin/webpack-dev-server
    ports:
      - '3035:3035'

アプリ用のコンテナにWebpackerホスト名の環境変数を追加します。

docker-compose.yml
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    tty: true
    stdin_open: true
    depends_on:
      - db
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
  # 以下を追記
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker

これでdocker-compose up --buildをすると、Webpackerが起動してくれます。
このあたりは、公式ドキュメントにわかりやすく記載されています。

基本的な使い方

Webpackerをインストールすると、config/webpacker.ymlが作成されます

config/webpacker.yml
default: &default
  source_path: app/javascript
  source_entry_path: packs # この配下のファイルをエントリーポイントとして読み込む
  ...
構成
app/javascript:
  ├── packs:
  │   # ここに置いたファイルが読み込まれる
  │   └── application.js
  └── javascripts:
  │   └── application.js
  └── stylesheets:
      └── application.scss

javascripts/application.js, stylesheets/application.css
アプリケーション全体に適用させたい場合は以下のように書きます。

packs/application.js
import '../javascripts/application.js'
import '../stylesheets/application.scss'
app/views/layouts/application.html.erb
<%= javascript_pack_tag 'applocation' %>
<%= stylesheet_pack_tag 'application' %>

これでビューに反映することができます。

ちなみに、今回はWebpackerの実行コマンドに./bin/webpack-dev-serverを指定しているため、
jsファイルの中身を更新するとブラウザをリロードすることなく自動的に変更を反映してくれます。
ただ、ファイル自体を追加するなど、構成を変更した場合はrailsを再起動する必要があります。

ページ毎に適用するファイルを分ける場合

構成
app/javascript:
  ├── packs:
  │   └── application.js
  └── javascripts:
  │   └── application.js
  │   └── tasks:
  │       └── application.js
  │       # 実際の処理が書かれているjavascriptファイル
  │       └── index.js
  │       └── show.js
  └── stylesheets:
      └── application.scss

エントリーポイントであるpakcs配下にjsファイルを読み込むためのエントリーファイルを作成します。

構成
app/javascript:
  ├── packs:
  │   └── application.js
  │   # 追加
  │   └── tasks:
  │       └── index.js
  │       └── show.js
  └── javascripts:
  │   └── application.js
  │   └── tasks:
  │       └── index.js
  │       └── show.js 
  └── stylesheets:
      └── application.scss

追加したファイルにインポート文を記述します。

packs/tasks/index.js
import '../../javascripts/tasks/index.js'
packs/tasks/show.js
import '../../javascripts/tasks/show.js'

それぞれのページでjavascriptを呼び出します。

app/views/tasks/index.html.erb
<%= javascript_pack_tag 'tasks/index.js' %>
app/views/tasks/show.html.erb
<%= javascript_pack_tag 'tasks/show.js' %>

そのほか

Bootstrap4を適用させる

Webpackerを導入したところ、Bootstrapが効かなくなりました。
こちらのサイトを参考に設定。
https://qiita.com/rhistoba/items/f724dae231d7e28bf477

confirmを動作させる

Webpackerを導入したところ、confirmダイアログが効かなくなりました。
こちらのサイトを参考に設定。
https://qiita.com/mokuo/items/a50a27a83c3328c116a7

Github ActionsでWebpackerを動作させる

Github Actionsで用意されているUbuntuにはyarnがデフォルトで入っているようですが、
そのままだとエラーが出てしまいました。
yarn upgradeを追記することで動作するようになりました。

.github/workflows/ruby.yml
    - name: Compile with Webpacker
      run: |
        yarn upgrade
        bundle exec rake webpacker:compile
      env:
        NODE_ENV: test 

最後に

ご指摘、コメントお待ちしております。

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

DockerComposeでWSLからdockerを使用するときのVolumeについて

WSLにdockerをインストール

この記事ではDocker for Windowsをインストールし、Hyper-V上で
Dockerが起動することを前提としています。

WSL2の場合は、上記のインストールがいらないそうですが、
まだ、Insider Previewでしか使用できないようなので、
Docker for Windowsのインストールを前提とし、
expose deamon on~~のチェックを入れてDockerが起動していることを前提にしています。

image.png

dockerをWSLにインストールする方法は
https://docs.docker.com/install/linux/docker-ce/ubuntu/
に記載している為、省略します。

だいたいこのあたりは他の方もブログがQittaに記載しているので、
すぐにインストールができると思います。

問題はVolumeの設定

まず最初にdocker-compose.ymlやDockerfile
dockerにマウントするソースなどは
/home/{{username}}
のフォルダではなく、
/c/Users/{{username}}
などのWindows上のフォルダに保存しましょう。

※注意
通常ならWindowsのCドライブに格納したファイルは/mnt/c/・・・・
となるのですが、

WSLで/etc/wsl.confを新規作成(編集)し、以下の内容を追記します。

/etc/wsl.conf
[automount]
root = /
options = "metadata"

そうすると、/mnt/c/・・・・・ではなく/c/・・・・となります。
この設定と、/c/Users/{{username}}などのWindows上のフォルダに保存することによって
docker-compose.ymlに記載した
Volumeを相対パスにすることが可能です。

docker-compose.ymlやDockerfileをソースと一緒に
gitで管理している場合は、基本で記載されていると思いので、この点を知っておくと便利です。

なぜWSLからDockerを使うのか?

答えは、EDIがVScodeだから!!

最近のVSCodeにはRemote-WSLという機能があるのはご存知ですか?

RailsやPHPなどの開発の際、VScodeの機能を十分に活かそうとすると

  • PHPやRubyなどをWindows上にインストールが必要
  • ファイルを新規作成すると、改行コードがCRLF
  • gitでcore.autocrlf=falseにする必要がある

開発環境Windows⇔実行環境Linux間の弊害が発生します。
PHPやRubyなどをWindows上にインストールが必要は
結局WSL上にインストールが必要にはなりますが、
windowsとは違いバージョンの切り替えも容易ににできるのと、
コマンドベースでインストールもできるため、開発環境手順書を作らずとも
shellを容易しておけば、新しく開発者が増えた場合も容易に開発環境構築ができます。

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

NextCloudをDockerでデプロイする(SMB対応)

NextCloudを使ってみようと思ったのですが、公式のDockerイメージだけでは外部ストレージとしてSMBが利用できなくて少し詰まったので、メモとして残します。

apt-getでsmbclientのみをインストールする方法もあるみたいですが、ファイルサーバ側でSMBv1/CIFSを無効化していると「Protocol negotiation failed: NT_STATUS_CONNECTION_RESET」というエラーが出て接続できませんでした。

環境

Fedora release 30

前提

docker/docker-composeが使えること。

作業

適当なディレクトリを作成し、Dockerfileとdocker-compose.ymlを作成する。
ボリュームのマウント場所が気に入らない場合は修正してください。

Dockerfile
FROM nextcloud:apache
RUN apt-get update && apt-get install -y libsmbclient-dev smbclient && pecl install smbclient && docker-php-ext-enable smbclient
docker-compose.yml
version: '2'

services:
  db:
    image: postgres:11-alpine
    restart: always
    volumes:
      - /dockerdata/nextcloud/db:/var/lib/postgresql/data
    environment:
      TZ: Asia/Tokyo
      POSTGRES_PASSWORD: #適当なパスワード
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud

  app:
    build: ./
    ports:
      - 8080:80
    volumes:
      - /dockerdata/nextcloud/app:/var/www/html
    restart: always
    depends_on:
      - db
    environment:
      TZ: Asia/Tokyo
      POSTGRES_PASSWORD: #適当なパスワード
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_HOST: db:5432

起動

docker-compose build --pull
docker-compose up -d

確認/adminユーザー作成(数分放置)
http://localohost:8080
2resized.png

ログインしたら「アプリ>あなたのアプリ>External storage support」を有効にする
3resized.png

「設定>管理>外部ストレージ」でファイルサーバの情報を入力してチェックマークをクリックで完了。
1resized.png

httpsでインターネットに公開する

リバースプロキシ+Let's Encryptで暗号化し、その後ろにNextCloudをぶら下げます。
インターネット側から80/443で実行しているホストにアクセスできること、利用するドメインが名前解決できることが前提です。
リバースプロキシに後から別のコンテナをぶら下げられるようにネットワークはexternalにしておきます。

docker-compose.yml
version: '2'

services:
  db:
    image: postgres:11-alpine
    restart: always
    volumes:
      - /dockerdata/nextcloud/db:/var/lib/postgresql/data
    environment:
      TZ: Asia/Tokyo
      POSTGRES_PASSWORD: #適当なパスワード
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud

  app:
    build: ./
    expose:
      - 80
    volumes:
      - /dockerdata/nextcloud/app:/var/www/html
    restart: always
    depends_on:
      - db
    environment:
      TZ: Asia/Tokyo
      POSTGRES_PASSWORD: #適当なパスワード
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_HOST: db:5432
      VIRTUAL_HOST: #あなたのドメイン名
      LETSENCRYPT_HOST: #あなたのドメイン名
      LETSENCRYPT_EMAIL: #メアド

  nginx-proxy:
    image: jwilder/nginx-proxy
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /dockerdata/nginx-proxy/certs:/etc/nginx/certs:ro
      - /dockerdata/nginx-proxy/htpasswd:/etc/nginx/htpasswd
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro

  letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    restart: always
    volumes:
      - /home/web/wordpress/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    volumes_from:
      - nginx-proxy

networks:
  default:
    external:
      name: shared

補足

自宅サーバなどで公開したい場合のDDNS設定を書きました。
Route53+MyDNSでサーバを公開する(複数サブドメイン/自動IP報知/Let's Encrypt対応)

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

Docker + create-react-app v3.4.1でサーバーが立ち上がらないバグ

起きたバグ

react-scripts startでサーバーを立ち上げようとしても

node_1  | yarn run v1.22.4
node_1  | $ react-scripts start
node_1  | ℹ 「wds」: Project is running at http://172.26.0.2/
node_1  | ℹ 「wds」: webpack output is served from 
node_1  | ℹ 「wds」: Content not from webpack is served from /usr/src/app/react-sample/public
node_1  | ℹ 「wds」: 404s will fallback to /
node_1  | Starting the development server...
node_1  | 
node_1  | Done in 25.46s.
docker-react-app_node_1 exited with code 0

というメッセージが表示されサーバーが終了する。

原因

create-react-app v3.4.1で取り込まれた下記の修正

https://github.com/facebook/create-react-app/commit/7e6d6cd05f3054723c8b015c813e13761659759e

process.stdout.isTTYかprocess.env.CIがtrueじゃないと開発用サーバーが停止するらしい。

解決方法

上のコミットのメッセージに

// Gracefully exit when stdin ends
(標準入力が終了したら正常終了するよ)

とあるので標準入力を終わらせないオプションをdocker-compose.ymlに追加。
具体的には下記のオプション

stdin_open: true

と追加するだけ。

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

Rails × Docker ログに「Cannot render console from Allowed networks」と出力される対処法

ログに「Cannot render console from Allowed networks」と出力される対処法

環境

ruby 2.5.1
rails 5.2.4
docker 19.03.8

Ruby on Railsの開発環境で、DockerかVagrantを使っていて、”Cannot render console from 172.20.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255″ 「このIPアドレスではレンダリングできない」と言われた場合

うぉおおん?

Started GET "/" for 172.20.0.1 at 2020-03-28 09:15:23 +0000
web_1  | Cannot render console from 172.20.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255

Image from Gyazo

対処法は簡単だった

Webコンソールの設定で172.20.0.1ネットワークをホワイトリストに登録する

ホワイトリストとは?

config/environments/development.rbconfig.web_console.whitelisted_ips = ‘172.20.0.1’を追加(IPアドレスは自身のログに書いてあるIPアドレスを記述)

config/environments/development.rb
config.web_console.whitelisted_ips ='172.20.0.1'

Image from Gyazo

これで解決しました

docker → kubernetesに関してこれから投稿していきます。

docker公式

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

DockerでMySQLサーバを立ち上げ、.sqlファイルからDBを作るまで

はじめに

環境 : macOS catalina 10.15.3
Docker Desktop : 2.2.0.4(43472)
Docker Compose : 1.25.4

ローカルファイル構成

以下、図参照
スクリーンショット 2020-03-28 16.49.37.png

自前のsqlファイルを使いたかったので、それをDBフォルダ配下に配置

以下に示すファイルの中身はDockerでMySQLを使ってみるを引用

docker-compose.yml

version: "3"
services:
  mysql:
    build: ./mysql/
    volumes:
      - ./mysql/db:/docker-entrypoint-initdb.d
    image: local_mysql
    environment:
      - MYSQL_ROOT_PASSWORD=

Dockerfile

FROM mysql

EXPOSE 3306

ADD ./my.cnf /etc/mysql/conf.d/my.cnf

CMD ["mysqld"]

my.conf

[mysqld]
character-set-server=utf8

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8

コンテナ起動

$ Docker-Compose up -d --build

# コンテナへログイン
$ docker exec -it Docker-mysql_mysql_1 bash -p

# MySQLを起動
$ mysql -u root -p -h 127.0.0.1  # パスワードはdocker-compose.ymlで記述したやつ

DB作成したい場合

DB作成コマンド

$ create database hoge_db;

DBができているか確認

$ mysql -u root -p -h 127.0.0.1  

パスワードはdocker-compose.ymlで記述したやつ
DB内に入れたら

mysql> show databases;

作ったDBがあればOK

.sqlファイルからDBを作る場合

mysqlからはexitして以下のコマンドを叩く

mysql -u root -p < インポートしたいsqlファイル

既存のDBを指定することも可能
success的なメッセージが出れば完了

参考資料

DockerでMySQLを使ってみる

MySQLで.sqlファイルを実行する

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

DockerでMySQLコンテナを立ち上げ、.sqlファイルからDBを作るまで

はじめに

環境 : macOS catalina 10.15.3
Docker Desktop : 2.2.0.4(43472)
Docker Compose : 1.25.4

ローカルファイル構成

以下、図参照
スクリーンショット 2020-03-28 16.49.37.png

自前のsqlファイルを使いたかったので、それをDBフォルダ配下に配置

以下に示すファイルの中身はDockerでMySQLを使ってみるを引用

docker-compose.yml

version: "3"
services:
  mysql:
    build: ./mysql/
    volumes:
      - ./mysql/db:/docker-entrypoint-initdb.d
    image: local_mysql
    environment:
      - MYSQL_ROOT_PASSWORD=

Dockerfile

FROM mysql

EXPOSE 3306

ADD ./my.cnf /etc/mysql/conf.d/my.cnf

CMD ["mysqld"]

my.conf

[mysqld]
character-set-server=utf8

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8

コンテナ起動

$ Docker-Compose up -d --build

# コンテナへログイン
$ docker exec -it Docker-mysql_mysql_1 bash -p

# MySQLを起動
$ mysql -u root -p -h 127.0.0.1  # パスワードはdocker-compose.ymlで記述したやつ

DB作成したい場合

DB作成コマンド

$ create database hoge_db;

DBができているか確認

$ mysql -u root -p -h 127.0.0.1  

パスワードはdocker-compose.ymlで記述したやつ
DB内に入れたら

mysql> show databases;

作ったDBがあればOK

.sqlファイルからDBを作る場合

mysqlからはexitして以下のコマンドを叩く

mysql -u root -p < インポートしたいsqlファイル

既存のDBを指定することも可能
success的なメッセージが出れば完了

参考資料

DockerでMySQLを使ってみる

MySQLで.sqlファイルを実行する

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

DockerでMySQLコンテナを立ち上げて.sqlファイルからDBを作る

環境

macOS : catalina 10.15.3
Docker Desktop : 2.2.0.4(43472)
Docker Compose : 1.25.4

ローカルファイル構成

以下、図参照
スクリーンショット 2020-03-28 16.49.37.png

自前のsqlファイルを使いたかったので、それをDBフォルダ配下に配置

以下に示すファイルの中身はDockerでMySQLを使ってみるを引用

docker-compose.yml

version: "3"
services:
  mysql:
    build: ./mysql/
    volumes:
      - ./mysql/db:/docker-entrypoint-initdb.d
    image: local_mysql
    environment:
      - MYSQL_ROOT_PASSWORD=

Dockerfile

FROM mysql

EXPOSE 3306

ADD ./my.cnf /etc/mysql/conf.d/my.cnf

CMD ["mysqld"]

my.conf

[mysqld]
character-set-server=utf8

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8

コンテナ起動

$ Docker-Compose up -d --build

# コンテナへログイン
$ docker exec -it Docker-mysql_mysql_1 bash -p

# MySQLを起動
$ mysql -u root -p -h 127.0.0.1  # パスワードはdocker-compose.ymlで記述したやつ

DB作成したい場合

DB作成コマンド

$ create database hoge_db;

DBができているか確認

$ mysql -u root -p -h 127.0.0.1  

パスワードはdocker-compose.ymlで記述したやつ
DB内に入れたら

mysql> show databases;

作ったDBがあればOK

.sqlファイルからDBを作る場合

mysqlからはexitして以下のコマンドを叩く

mysql -u root -p < インポートしたいsqlファイル

既存のDBを指定することも可能
success的なメッセージが出れば完了

参考資料

DockerでMySQLを使ってみる

MySQLで.sqlファイルを実行する

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

aws-shell を dockerでクリーンに動かす

TL;DR

https://github.com/hiroga-cc/docker-images/blob/master/aws-shell/Dockerfile

詳細

aws-shell の調子が良くないので、dockerでクリーンに実行します。

aliasでdockerを動かし、かつ ~/.aws をボリュームとしてマウントする、という構成です。

# alias aws-shell='docker run --rm -it -v "$HOME/.aws:/root/.aws" hiroga/aws-shell:latest'
FROM python:3.7.7-alpine3.11

RUN pip install --upgrade pip;\
    pip install --upgrade aws-shell
ENTRYPOINT [ "aws-shell" ]

今後の改善点

  • できれば毎度イメージを作るのを避けたいので start を利用したいのだが、 startにprofileオプションを渡す方法が思いつかないです...
  • Creating doc index が毎回走るのもなんとかしたい。コンテナビルド時にindexを作るという手もあるが...うーん。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Lambda Layersを作成する時はdocker-lambdaやyumdaが便利

はじめに

docker-lambda のビルドイメージで各ラインタイムバージョンに対応した Layer が作れる!

$ docker run --rm -v $(pwd):/var/task lambci/lambda:build-python3.8 \
> pip install -r requirements.txt -t python/lib/python3.8/site-packages/

AWS Lambdaで 実行したいソフトウエアパッケージは yumda で Layer 化できる!

$ docker run --rm -v $(pwd)/git-layer:/lambda/opt lambci/yumda:2 yum install -y <package>

一からやると環境準備は結構大変

AWS Lambda や Lambda Layers のよくある注意点としてネイティブバイナリの扱いがあります。
Lambda 実行環境は、特定の Amazon Linux 環境とカーネルバージョンに基づいているため、
Lambda 内で使用されるネイティブバイナリも該当の環境でコンパイルされている必要があります。

また現在は Amazon Linux のサポート終了の過渡期でもあり、使用するランタイムのバージョンにより
Amazon Linux ベースなのか Amazon Linux 2 ベースな異なるところもやっかいな点です。
例えば Python の場合は 2020/3/28 時点で以下のようになっています。

Version OS
Python 3.8 Amazon Linux 2
Python 3.7 Amazon Linux
Python 3.6 Amazon Linux
Python 2.7 Amazon Linux

AWS Lambda Runtimes
https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html

パッケージ作成の度にEC2を起動するのもさすがに面倒です。
また Docker Hub で公開されている Amazon Linuxのコンテナイメージ を使ってもよいのですが、
このイメージには最小限のパッケージセットしか含まれていないため、
これをベースイメージとして対象のランタイム環境を追加でインストールする必要があります。
複数のランタイムやバージョンを対象に開発する場合、環境毎に Dockerfile やイメージを管理
するのもちょっと大変かなと思います。

前置きが長くなりましたが、そんな時は docker-lambda や yumda が便利です。

docker-lambda

docker-lambda とは

docker-lambda は Dockerコンテナ内で AWS Lambda の実行環境を限りなく近く再現します。
(が、完全なコピーではありません)
Docker Hub の lambci/lambda でコンテナイメージが公開されています。
AWS Severless Hero の Michael Hart 氏を中心に OSS として開発されています。

docker-lambda
https://github.com/lambci/docker-lambda

AWS SAM CLI の中でもLambda関数の実行環境として採用されています。
SAM CLI で Lambda 関数を ローカルで Invoke する際には内部的には docker-lambda が動いています。

docker-lambda のビルドイメージ

docker-lambda には Lambda 関数の ビルドとパッケージを行うためのビルドイメージも提供されています。
ビルドイメージは build-python3.x といったイメージタグでランタイムバージョンごとに用意されています。
ビルドイメージに追加でインストールされているパッケージは
https://hub.docker.com/r/lambci/lambda/#build-environment を参照してください。
AWS CLI や AWS SAM CLI も含まれているので、やろうと思えばコンテナ内でもろもろできちゃいます。

python3.8 互換の layer を作成する例

lambci/lambda:build-python3.8 を使用します。
requirements.txt に 追加したいライブラリを記載しておきます。
ここではシンプルに pandas のみを追加しています。

requirements.txt
pandas

ビルドイメージ内で pip install して、ライブラリを Layer に含めます。

$ docker run --rm -v $(pwd):/var/task lambci/lambda:build-python3.8 \
> pip install -r requirements.txt -t python/lib/python3.8/site-packages/

$ zip -r pandas-1.0.3.zip ./python > /dev/null

複数バージョンに互換性を持たせた Layer としたい場合は 各バージョン毎にビルドイメージと
site-packages を指定して docker run してから zip します。
以下のようなディレクトリ構造になります。
展開後のパッケージサイズの制限(250MB)には注意する必要があります。

.
`-- python
    `-- lib
        |-- python3.6
        |   `-- site-packages
        |-- python3.7
        |   `-- site-packages
        `-- python3.8
            `-- site-packages

先ほどの Layer を使用して 以下のような超簡易コードで動作確認してみると、、、

lambda_function.py
import pandas as pd;

def lambda_handler(event, context):
    pd.show_versions()

実行できました!

START RequestId: 813889ca-958c-4b60-ae1d-442870679429 Version: $LATEST

INSTALLED VERSIONS
------------------
commit           : None
python           : 3.8.2.final.0
python-bits      : 64
OS               : Linux
OS-release       : 4.14.165-102.205.amzn2.x86_64
machine          : x86_64
processor        : x86_64
byteorder        : little
LC_ALL           : None
LANG             : en_US.UTF-8
LOCALE           : en_US.UTF-8

pandas           : 1.0.3
numpy            : 1.18.2
~~以下省略~~

yumda

yumda を使用すると AWS Lambda 環境で実行可能なソフトウェアパッケージを
yum コマンドで用意することができます。docker-lambda と同様 OSS として開発されています。

yumda – yum for Lambda
https://github.com/lambci/yumda

コンテナイメージは lambci/yumda で公開されています。
Amazon Linux 2 環境向けのイメージとAmazon Linux 環境用のイメージが用意されていますので
nodejs10.x、nodejs12.x、python3.8、java11、ruby2.7 は lambci/yumbda:2 を、
それ以外のランタイムバージョンでは lambci/yumbda:1 を使用します。

Amazon Linux 2 環境向けに利用可能なパッケージを確認するには以下のようなコマンドを実行します。

$ docker run --rm lambci/yumda:2 yum list available
Loaded plugins: ovl, priorities
Available Packages
GraphicsMagick.x86_64        1.3.34-1.lambda2                            lambda2
GraphicsMagick-c++.x86_64    1.3.34-1.lambda2                            lambda2
ImageMagick.x86_64           6.7.8.9-18.lambda2                          lambda2
OpenEXR.x86_64               1.7.1-7.lambda2.0.2                         lambda2
OpenEXR-libs.x86_64          1.7.1-7.lambda2.0.2                         lambda2
~~以下省略~~

もしくは 以下からも確認できます。
https://github.com/lambci/yumda/blob/master/amazon-linux-2/packages.txt

パッケージは独自のリポジトリで管理されており、GitHub Issues で追加のリクエストを提出できますが、
Amazon Linux core リポジトリおよび amazon-linux-extras リポジトリに既に存在するものを
追加する方針であるようです。

Please file a GitHub Issue with your request and add the package suggestion label. For now we'll only be considering additions that already exist in the Amazon Linux core repositories, or the amazon-linux-extras repositories (including epel).

yumda で Layer を作成する例

ここでは 試しに python3.8 の Lmabda 関数で git コマンドを実行してみます。

lambda_function.py
import subprocess

def lambda_handler(event, context):
    return subprocess.check_output(
        "git --version;exit 0",
        stderr=subprocess.STDOUT,
        shell=True
    )

当然ながら Lambda Layers を使わない場合、実行結果は commnad not found になります。

$ aws lambda invoke --function-name git-layer-test outfile
ExecutedVersion: $LATEST
StatusCode: 200

$ cat outfile
/bin/sh: git: command not found

yumda で Layer を作成します。

$ docker run --rm -v $(pwd)/git-layer:/lambda/opt lambci/yumda:2 yum install -y git
$ cd git-layer
$ zip -yr ../git-2.25.0-1.zip . > /dev/null

以下のようなディレクトリ構成で git とその依存関係がインストールされていることを確認できます。

.
|-- bin
|-- etc
|   |-- alternatives
|   |-- pki
|   |-- prelink.conf.d
|   `-- ssh
|-- lib
|   |-- fipscheck
|   `-- nss
|-- libexec
|   |-- git-core
|   `-- openssh
`-- share
    |-- git-core
    `-- licenses

Layer を publish して先ほどの Lambda 関数に設定します。

$ aws lambda publish-layer-version \
> --layer-name git-2-25-0-1 --zip-file fileb://git-2.25.0-1.zip

$ aws lambda update-function-configuration \
>  --function-name git-layer-test \
>  --layers arn:aws:lambda:ap-northeast-1:123456789012:layer:git-2-25-0-1:1

実行してみると git の version が返ってきました!

$ aws lambda invoke --function-name git-layer-test outfile
ExecutedVersion: $LATEST
StatusCode: 200

$ cat outfile
git version 2.25.0

参考: 公開済みの Lambda Layers を使う

ここまで書いておいてなんですが、Sevelress Application Repository でも Lambda Layers が
多数登録されていますし、λ AWSome Lambda Layers というGitHubリポジトリにも
様々な Layer のリストがまとめられています。
これらに必要なものが公開されていれば、それを使わせていただくのが楽ですね!

以上です。
参考になれば幸いです。

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

dockerでよく使うコマンド一覧【Rails】

土台
$ docker-compose run web ~

MySQLを使う場合

$ docker-compose run web rails new . --force --database=mysql
$ docker-compose build

model作成

docker-compose run web bundle exec rails g model (モデル名) (カラム名)

バックグラウンドでコンテナ起動

docker-compose up -d

コンテナ再起動

docker-compose restart

Gemfile変更時(基本的には)

$ docker-compose build

DBへテストデータ投入

$ docker-compose run web bundle exec rake db:seed

DBへテストデータを一から入れ直したい時
(テーブル削除、作成、マイグレーション)

$ docker-compose run web bundle exec rake db:drop
$ docker-compose run web bundle exec rake db:create
$ docker-compose run web bundle exec rake db:migrate
$ docker-compose run web bundle exec rake db:seed

dockerコンテナ、イメージ削除

$ docker rm $(docker ps -q -a)
$ docker rmi $(docker images -q)

補足: kaminari設定ファイル生成

$ docker-compose run web bundle exec rails g kaminari:config

補足: kaminari(bootstrap4)ファイル生成(bootstrap4)

$ docker-compose run web bundle exec rails g kaminari:views bootstrap4

補足: kaminariページネーションファイル生成

$ docker-compose run web bundle exec rails g kaminari:config

Rspecを使う場合(Gemfileにはrspecの記述をする)

$ docker-compose run web bundle exec rails g rspec:install 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dockerでよく使うコマンド一覧

MySQLを使う場合

$ docker-compose run web rails new . --force --database=mysql
$ docker-compose build

model作成

docker-compose run web bundle exec rails g model (モデル名) (カラム名)
バックグラウンドでコンテナ起動

docker-compose up -d
コンテナ再起動

docker-compose restart

Gemfile変更時(基本的には)

$ docker-compose build

DBへテストデータ投入

$ docker-compose run web bundle exec rake db:seed

DBへテストデータを一から入れ直したい時
(テーブル削除、作成、マイグレーション)

$ docker-compose run web bundle exec rake db:drop
$ docker-compose run web bundle exec rake db:create
$ docker-compose run web bundle exec rake db:migrate
$ docker-compose run web bundle exec rake db:seed

dockerコンテナ、イメージ削除

$ docker rm $(docker ps -q -a)
$ docker rmi $(docker images -q)

補足: kaminari設定ファイル生成

$ docker-compose run web bundle exec rails g kaminari:config

補足: kaminari(bootstrap4)ファイル生成(bootstrap4)

$ docker-compose run web bundle exec rails g kaminari:views bootstrap4

補足: kaminariページネーションファイル生成

$ docker-compose run web bundle exec rails g kaminari:config

Rspecを使う場合(Gemfileにはrspecの記述をする)

$ docker-compose run web bundle exec rails g rspec:install 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Folding@Home Setup

はじめに

ASRock Japanさんのツイートにより興味を持ったが日本語文献が少ないため書いた。

目次

  • Passkey
  • SetUp
  • Windows
  • Docker
  • よくある問題

Passkey

ユーザー登録みたいなもの。
使用することで個人の識別と結果の集計さらにポイントへのボーナスが付くので使用しておくと良さそう。
以下URLの公式サイトから取得
https://apps.foldingathome.org/getpasskey

Nameに使用したい任意の名前、Emailにメールアドレスを入れて送信。
image.png

少し待てばメールが送信されPasskeyが取得完了。
image.png

SetUp

Windows

Install

仮想環境に構築したWindows10 Home 1909を使用している。
公式サイトからダウンロード
https://foldingathome.org/start-folding/

ファイアウォールの設定が求められたらアクセスを許可。
インストールが完了するとブラウザが開くが、一旦無視して右下の通知領域からFolding@homeを右クリックしAdvanced Controlをクリック。
image.png

Config

左上のConfigureをクリックしIdentity Tabを選択し下記の項目を入力しSave。

Name: Passkeyを登録した名前
Team: 任意のTeam Number(ASRock JapanさんのTeamに入る場合は252872)
Passkey: Emailに送信されたPasskey
image.png

Fold

Folding Powerは環境に合わせて設定 基本はMediumでいいと思う。
Foldをクリックすることで作業が始まる。
image.png

Docker

Dockerが入ってる環境の場合Dockerを使用することもできる。
Client: 19.03.8
Server: 19.03.8
Docker-compose: 1.25.3, build d4d1b42b

docker-compose.yml
version: '3.7'
services:
  folding-at-home:
    image: johnktims/folding-at-home
    restart: always
    ports:
      - 7396:7396
    command: >
      -user={Passkeyに登録した名前}
      -team={任意のTeam Number(ASRock JapanさんのTeamに入る場合は252872)}
      -passkey={Emailに送信されたPasskey}
      -gpu=false
      -smp=true
      -power=full

よくある問題

  • Foldをクリックしたのに始まらない
    • Work Serverから仕事が来るのを待っています。
    • 少し待ってみましょう。
  • 次の仕事が来ない
    • 定期的にWork Serverに仕事の問い合わせをしています。
    • Next Attemptに時間がかかる場合はリスタートするといいかもしれません。
  • CPUまたはGPUの温度が高い
    • 長時間かかる仕事も来るため冷却性能、室温などを見直しましょう。
    • ノートパソコンの場合は厳しいかもしれません。
  • ファンがうるさい
    • そのうちファンの音が心地よくなってくるかもしれません。
    • 悟りを開きましょう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker Compose を使って自分好みの Redmine 実行環境を作ってみた

タイトルのとおりです。

前半部にやりたかったことと結果をまとめます。
後半部に、結果にいたるまでの試行錯誤っぷりをダラダラと書き並べていきます。

やりたかったこと

  • 最新バージョンの Redmine を動かしてみたい(執筆時の最新バージョンは 4.1.0)
  • 素の Linux 上に Ruby のインストールから始めるのは面倒なので Docker でサクッと済ませたい
  • データベースは PostgreSQL が使いたい(これは単なる個人的な好み)
  • プラグインやテーマもまとめて入れたい
  • あまり手数をかけて作りたくない(Docker 等の作法に多少反してても、そこは目をつぶりたい…)

結果

ファイル一式を GitHub で公開しています。ディレクトリ構成や細かい内容はそちらで確認してください。

以下の環境で起動と簡単な操作までを確認しました。

  • OS: Ubuntu 18.04
  • Docker: 19..03.8
  • Docker Compose: 1.25.4

これから使い込んで動作に問題ないか確認しようとしています。

全体のざっくりとした説明

  • Redmine と PostgreSQL を Dcoker Compose でひとまとめに構築
  • Redmine は公式の Passenger 版イメージを使用
    • configuration.yml やプラグイン、テーマは Dockerfile で追加
  • PostgreSQL は公式イメージをベースに PGroonga を追加でインストール
  • リバースプロキシサーバーやリマインダー通知は含めていない

個別ファイルの説明

docker-compose.yml

docker-compose,yml
version: "3.7"

services:

  redmine:
    build: ./redmine
    container_name: myfav-redmine
    restart: always
    depends_on:
      - db
    ports:
      - "3000:3000"
    environment:
      TZ: Asia/Tokyo
      REDMINE_DB_POSTGRES: db
      REDMINE_DB_DATABASE: redminedb
      REDMINE_DB_USERNAME: redmineuser
      REDMINE_DB_PASSWORD: redminepassword
      REDMINE_PLUGINS_MIGRATE: "true"
    volumes:
      - "/srv/redmine/files:/usr/src/redmine/files:z"
      - "/var/log/redmine:/usr/src/redmine/log:z"

  db:
    build: ./db
    container_name: myfav-redmine-db
    restart: always
    environment:
      TZ: Asia/Tokyo
      POSTGRES_DB: redminedb
      POSTGRES_USER: redmineuser
      POSTGRES_PASSWORD: redminepassword
    volumes:
      - "dbdata:/var/lib/postgresql/data"

volumes:
  dbdata:
  • 必要に応じて Listen するポート、データベース名/ユーザー/パスワードを書き換えてください
  • 添付ファイルとログはホスト側にバインドマウントしています(パスは変更してもよいです)
  • プラグインの追加や更新を考慮して、起動時に redmine:plugins:migrate を実行するようにしています
  • Dockerfile を変更したときは、起動前に docker-compose build の実行が必要です

Redmine の Dockerfile

redmine/Dockerfile
FROM redmine:4.1-passenger

COPY config/configuration.yml config

RUN set -eux; \
        \
        apt-get update && apt-get install -y --no-install-recommends \
                antiword \
                catdoc \
                catdvi \
                djview \
                djview3 \
                gcc \
                gzip \
                libemail-outlook-message-perl \
                libwpd-tools \
                libwps-tools \
                libxapian-dev \
                make \
                poppler-utils \
                ruby-xapian \
                uuid \
                uuid-dev \
                unrtf \
                unzip \
                xapian-omega \
                xpdf \
                xz-utils \
        ; \
        \
# install plugins
        gosu redmine git clone --depth 1 https://github.com/akiko-pusu/redmine_banner.git plugins/redmine_banner; \
        gosu redmine git clone --depth 1 https://github.com/akiko-pusu/redmine_issue_badge.git plugins/redmine_issue_badge; \
        gosu redmine git clone --depth 1 https://github.com/akiko-pusu/redmine_issue_templates.git  plugins/redmine_issue_templates; \ 
        gosu redmine git clone --depth 1 https://github.com/clear-code/redmine_full_text_search.git plugins/full_text_search; \        
        gosu redmine git clone --depth 1 https://github.com/danmunn/redmine_dmsf.git plugins/redmine_dmsf; \
        gosu redmine git clone --depth 1 https://github.com/jbbarth/redmine_base_deface.git plugins/redmine_base_deface; \
        gosu redmine git clone --depth 1 https://github.com/jbbarth/redmine_drafts.git plugins/redmine_drafts; \
        gosu redmine git clone --depth 1 https://github.com/onozaty/redmine-view-customize.git plugins/view_customize; \
        \
# install themes
        gosu redmine git clone -b redmine4.1 --depth 1 https://github.com/farend/redmine_theme_farend_bleuclair.git public/themes/bleuclair; \
        \
# install gems
        gosu redmine bundle install;
  • ホスト側の config/configuration.yml に、メールサーバーなどの設定を記述します
  • redmine_dmsf の実行に必要な OS 側のパッケージを apt-get でインストールしています
  • プラグイン、テーマは必要に応じて追加、変更してください
    • bundle install で Gem のビルド等に失敗するときは、apt-get の行に必要なパッケージを追加してください

PostgreSQL の Dockerfile

db/Dockerfile
FROM postgres:12

RUN set -eux; \
        \
        apt-get update && apt-get install -y --no-install-recommends \
                ca-certificates \
                wget \
        ; \
        \
        mkdir pgroonga-work; \
        cd pgroonga-work; \
        \
        wget https://packages.groonga.org/debian/groonga-archive-keyring-latest-buster.deb; \
        apt-get install -y ./groonga-archive-keyring-latest-buster.deb; \
        apt-get update && apt-get install -y --no-install-recommends \
                groonga-tokenizer-mecab \
                postgresql-12-pgroonga \
        ; \
        \
        cd ..; \
        rm -rf pgroonga-work;
  • PostgreSQL 12 に PGroonga を追加インストールしています
  • redmine_full_text_search の実行には TokenMecab も必要なため追加でインストールしています

結果に至るまで

正直なところ、全然わからん…の連続でした。Docker で Redmine を動かすのは 前記事 以来のことで、その当時は素の Redmine を動かした程度の経験しかなかったです。

以下、心の声を含めて試行錯誤の過程をダラダラと書き並べていきます。

  • Passenger 版の Redmine ってどういう構成なんや… つーか、Passenger って Apache とかに組み込んで動かすんとちゃうの?
  • configuration.yml ってどうやってコンテナ側に置けばええねん…
    • せや、手元に Dockerfile 作って COPY したれ!
    • それやったらついでにプラグインやテーマも Dockerfile に書けばええやんけ!
      • この気づきがあったので、その後が楽になったと思っています。最初はプラグインやテーマのディレクトリをホスト側にバインドマウントしてましたが、コンテナ内に閉じ込めておいた方が OS 側パッケージの追加インストールも含めて管理しやすいです。
  • PGroonga ってどうやって入れたらええんや…
    • Groonga 公式の Dockerfile があるやんけ! これ使うたろ!
      • TokenMecab が入ってなくてダメでした…(ベースが Alpine やから入れ方わからん…)
    • おとなしく PostgreSQL 公式のイメージに追加インストールするか… でも、本体の Dockerfile 見てると apt-get で入れたパッケージをビルドが終わったら巻き戻したりしてるし、こういうこと必要なんかな…
      • わからんからそのままにしといたれ…
  • これで Redmine 側の apt-get もどうにかなるな…でも、追加したファイルのオーナーってどうやって書き換えるんやろ
    • 本体に gosu ってのが入ってる… 詳細はわからんけど便利そうやからそのまま使うたれ!(Golang で書かれたユーティリティツールのようです)

まあ、なんというか…くぅ~疲れましたw

おわりに

Docker Compose を使って簡単に好みの Redmine 環境が作れるようになりました。これで色んな実験がしやすくなったかな、と感じています。

きっと、プラグイン開発なども捗るんじゃなかろうか…と。先生の次回作にご期待ください…(涙)

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

Railsの既存AppをDockerに切り替える際に役立つ記事

既存のAppをDockerに切り替える

過去に制作したRailsアプリをDockerで構築したいと思います。

参考になる記事

基本的にこの記事を使って、進めていきました。
Ruby on Rails 「途中まで作ったアプリにDockerを導入したい」に挑戦してみる(MySQL / Sequel Pro)

build時のエラーが出たら、下記の資料が役立ちます。
Docker docker-compose up時、You must use Bundler 2 or greater with this lockfile. という地獄のエラー

  1. Gemfile.lockの記述を削除して、空状態にする。(Dockerに切り替える際に阻害してしまう)
  2. Dockerfileのbundlerのバージョンを指定(RUN gem install bundler -v 1.3.0)
  3. $ docker-compose run web bundle install
  4. 改めてbuildする

これで進めました

docker
FROM ruby:2.5.1

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

RUN mkdir /app_name 

ENV APP_ROOT /app_name 
WORKDIR $APP_ROOT

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

RUN gem install bundler -v 1.3.0
RUN bundle install
ADD . $APP_ROOT

Ruby | bundler を特定のバージョンに切り替えて実行する

起動する際にエラーが出た場合
docker-compose up したらdriver failed programming external connectivity on endpointが出てきた

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

RailsアプリにDockerとCircleCIを導入した際、DB周りでエラーになったときの対処法

こんにちは、ペーパーエンジニアのよしこです。

CircleCIでgit push時に自動テスト(RSpec)しているRailsアプリに、Dockerを導入しました。

その際にデータベース周りで躓いたエラーがあります。

同じエラーの報告が少なかったので、エラー解消した対処法を共有します。

エラー文

git pushをトリガーにCircleCIがテストを実行するのですが、その前にデータベースを構築します。
そこでエラーが出ていました。

circleci/config.yml
# DBをセットアップ
- run:
    name: DBをセットアップ
    command: bin/rails db:schema:load --trace

※全文は下記

  #!/bin/bash -eo pipefail
bin/rails db:schema:load --trace
** Invoke db:schema:load (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Invoke db:check_protected_environments (first_time)
** Invoke environment 
** Invoke db:load_config 
** Execute db:check_protected_environments
rails aborted!
PG::ConnectionBad: could not translate host name "db" to address: Name or service not known
/home/circleci/project/vendor/bundle/gems/pg-0.20.0/lib/pg.rb:56:in `initialize'
.
.  省略
.
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:schema:load => db:check_protected_environments

Exited with code exit status 1
CircleCI received exit code 1

環境

Ruby : 2.6.3
Rails : 5.1.6
postgres : 12.2
CircleCI : 2.1
Docker-compose version: '3'

結論

database.ymlに、test環境でhost: localhostを追加することで解決しました。

config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

  username: postgres
  password: 
  host: db
  timeout: 5000

development:
  <<: *default
  database: haito_notice_development

test:
  <<: *default
  database: haito_notice_test
  host: localhost    # <<<<<追加<<<<<

production:
  <<: *default
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>

Dockerのimage上ではdbとしてDB構築していますので、develop環境やproduction環境ではhost: dbとする必要があります。

しかし私の場合は、CircleCIのDocker imageをtest環境かつhost: 127.0.0.1 (localhost)で構築しているため、これに合わせてあげる必要があったのではと理解しています。

CircleCI

基本、公式のドキュメントを元に記載していますが、
別のエラー対処のためにworkflowsやcommandsを現在は適用していないため参考程度に。

circleci/config.yml
version: 2.1
jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.3-stretch-node
        environment:
          BUNDLE_JOBS: 3
          BUNDLE_RETRY: 3
          BUNDLE_PATH: vendor/bundle
          PGHOST: 127.0.0.1
          PGUSER: postgres
          RAILS_ENV: test
      - image: circleci/postgres:12-alpine
        environment:
          POSTGRES_USER: postgres
          POSTGRES_DB: app_test
    steps:
      - checkout
      - restore_cache:
          name: 依存関係キャッシュを復元
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            - v1-dependencies-
      - run:
          name: Bundler を指定
          command: bundle -v
      - run:
          name: バンドルをインストール
          command: bundle check || bundle install
      - save_cache:
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - run:
          name: 静的コード解析を実行(RuboCop)
          command: bundle exec rubocop
      - run:
          name: DBの起動まで待機
          command: dockerize -wait tcp://localhost:5432 -timeout 1m
      - run:
          name: DBをセットアップ
          command: bin/rails db:schema:load --trace
          # ここでエラーが起こっていました!!!
      - run:
          name: テストを実行(RSpec)
          command: |
            bundle exec rspec --profile 10 \
                              --format RspecJunitFormatter \
                              --out test_results/rspec.xml \
                              --format progress \
                              $(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
      - store_test_results:
          path: test_results

Docker

念の為記載します。
こちらもDocker公式のドキュメントを参考に作っています。

# Dockerfile

FROM ruby:2.6.3
RUN apt-get update -qq && \
    apt-get install -y nodejs \
                      postgresql-client

RUN mkdir /app
ENV APP_ROOT /app
WORKDIR $APP_ROOT

COPY ./Gemfile $APP_ROOT/Gemfile
COPY ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install
COPY ./ $APP_ROOT

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
entrypoint.sh
#!/bin/bash
set -e

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

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
docker-compose.yml
version: '3'
services:
  db:
    image: postgres:12-alpine
    environment:
      POSTGRES_HOST_AUTH_METHOD: 'trust'
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

ご指摘やご不明な点などがございましたらお気軽にご連絡ください。

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

Kubernetesで和牛を給付する

Motivation

コンテナ管理基盤であるKubernetesには、Kubernetes Operatorという概念があり
任意のオブジェクトをKubernetes上で管理することができる。
このKubernetes Operatorを用いると和牛も管理することができるので給付してみる。

ここで、Kubernetes Operatorを開発するツールは、下記の通りいくつか存在しているが
エコシステムが充実しているOperator SDKを採用した。

Operator SDK
Kubebuilder
Metacontroller

QuickStart

環境

和牛の配り方

Quay.ioのアカウント登録

quay.png

https://github.com/operator-framework/operator-sdk#quick-start

operator-sdkを用いて和牛Operatorの雛形を作成

TMPDIR=`mktemp -d` && cd $TMPDIR
mkdir $TMPDIR  && cd $TMPDIR
operator-sdk new wagyu-operator --repo github.com/delicious/wagyu
cd wagyu-operator

operator-sdk add api --api-version=app.example.com/v1alpha1 --kind=Wagyu

operator-sdk add controller --api-version=app.example.com/v1alpha1 --kind=Wagyu

和牛コントローラの処理を一部書き換え

実際にはデプロイされるPodのImageを差し替えている

sed 's|Image:   "busybox"|Image:   "quay.io/iaoiui727/wagyu:latest"|g' -i pkg/controller/wagyu/wagyu_controller.go

和牛OperatorのDockerイメージ作成

export USER=<quay.ioで作成したユーザ名>
operator-sdk build quay.io/$USER/wagyu-operator
docker login quay.io

DockerイメージのPush

docker push quay.io/$USER/wagyu-operator

Quay.ioでリポジトリをpublicにする

make_repository_public.png

Kubernetesクラスタの構築

kind create cluster

和牛Operatorのマニフェスト内で、先ほどquayにアップロードしたDockerイメージを使うよう変更

sed -i "/Command/d" pkg/controller/wagyu/wagyu_controller.go 
sed -i "s|REPLACE_IMAGE|quay.io/$USER/wagyu-operator|g" deploy/operator.yaml

Operator用のサービスアカウント、ロールを用意

kubectl create -f deploy/service_account.yaml
kubectl create -f deploy/role.yaml
kubectl create -f deploy/role_binding.yaml

和牛のCRD(Custom Resource Definition)を生成

和牛というCRDリソースがKubernetesに登録される

kubectl create -f deploy/crds/app.example.com_wagyus_crd.yaml 

和牛というCRDリソースの定義を確認できるようになる

 k get wagyu
NAME            AGE
example-wagyu   1m

和牛Operatorを起動

kubectl create -f deploy/operator.yaml

和牛Operatorの起動を確認

kubectl get po
NAME                              READY   STATUS    RESTARTS   AGE
wagyu-operator-7d87f94966-c7rbt   1/1     Running   0          18s

和牛インスタンスを起動

kubectl create -f deploy/crds/app.example.com_v1alpha1_wagyu_cr.yaml 

正常に起動していることを確認

kubectl get pod -l app=example-wagyu
kubectl describe appservice example-appservice

給付された和牛を確認

kubectl logs example-wagyu-pod 
? 

Clean up

kind delete cluster

まとめ

Operator SDKを用いてKubernetes上で和牛を給付できた
今回はGo言語で検証したが、Operator SDKではAnsible, Helmも対応しているので利用してみたい。

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

ラズパイで作る中規模Kubernetesクラスター

背景・目的

ラズパイで15台のワーカーノードからなる中規模Kubernetesシングルコントロールプレーンクラスターを構築しましたのでその紹介と共に構築方法などの知見の共有ができたらなと思い、本記事を投稿しました。

ラズパイでKubernetesクラスターを構築するための手順とビルド用スクリプトをこちらのGitHubリポジトリにまとめましたので合わせてご覧ください。

* なお、ご自身でクラスターの構築を行う場合、本リポジトリ上のスクリプトを使用して頂いても構いませんが、これらスクリプトにはなんの保証もありません
たとえこれらのスクリプトを利用したことで何か問題が発生した場合、作者はなんの責任も負いませんのでご了承下さい
raspberrypi_kubernetes_cluster.jpg
* なお、ここでの中規模とはワーカーノード10台以上を指します

要求

  • マスターノード用Raspberry Pi:1台
  • ワーカーノード用Raspberry Pi:1台以上
  • Raspberry Piがクラスターとして稼働するための最低限の周辺機器で構成されており、初期設定済みであること
  • SSHでpiユーザにログインできること

サポート

Raspberry Pi

* ワーカーノードを10台以上にする場合、マスターノードにRaspberry Pi 3を使用するとメモリが足りなくなり、Kubernetesがうまく動作しなくなる可能性があります
10台以上のワーカーノードでクラスターを構築する場合にはマスターノードにRAMが2GBか4GBのRaspberry Pi 4を使用してください

* マスターノードに2GB/4GB RAMのRaspberry Pi 4を使用した場合、現状(2020-03-27 JST)ではクラスターに参加できるワーカーノードの上限数は定かではありません
なお、マスターノードがRaspberry Pi 4 RAM 4GBの場合、ワーカーノードが15台で構築されたクラスターの動作は確認しております

Docker

  • v19.03.8

Kubernetes

  • v10.15.0

Kubernetesクラスターの構築方法

オプション設定

下記の項目はオプションです。
クラスター構築に対して直接関連していません。
しかし、下記の設定を適用することでクラスターのパフォーマンスを上げることができます。

ラズパイのGPUメモリの使用量を最小化させる

本項目を適用するとGPUメモリの使用量を最小化することができます。

ディスプレイを使用してラズパイを動作させる場合、ある程度のGPUメモリを割り当ててあげる必要があります。
本クラスターではディスプレイを使用せず、SSHでアクセスして設定を行いますのでGPUメモリへの割当値を最小にしたいと思います。
なお、デフォルトの割当メモリは64MBで下限値は16MBです。

/boot/config.txtに対して、下記の項目を追加してください。

/boot/config.txt
gpu_mem=16

設定は以上となりますが、設定項目を反映するために再起動が必要です。

下記のコマンドを実行してください。

command
sudo reboot

ラズパイの内蔵Wi-FiとBluetoothの機能を無効化する

本項目を適用すると 消費電力を抑えることができます。

Raspberry Pi 3以降のラズパイにはWi-FiモジュールとBluetoothモジュールが内蔵されており、デフォルトではそれぞれの機能は有効になっています。
本クラスターでは各機能は使用しませんので無効化します。

/boot/config.txtに対して、下記の項目を追加してください。

/boot/config.txt
dtoverlay=pi3-disable-wifi  
dtoverlay=pi3-disable-bt

設定は以上となりますが、設定項目を反映するために再起動が必要です。

下記のコマンドを実行してください。

command
sudo reboot

共通設定

下記の項目はマスターノード、ワーカーノード、共通の設定です。

ラズパイ上でDockerを動作させるためにcgroupを有効化する

ラズパイでDockerを動作させるためにはカーネルパラメータのcgroupの設定が必要です。
/boot/cmdline.txtファイルを開き、"cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1" を反映してください。
変更例を下記に示します。

/boot/cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=xxxxxxxx-xx rootfstype=ext4 cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 elevator=deadline fsck.repair=yes rootwait

* "root=PARTUUID=xxxxxxxx-xx" にはご自身のUUIDを記載してください

設定は以上となりますが、設定項目を反映するために再起動が必要です。
下記のコマンドを実行してください。

command
sudo reboot

Dockerのインストール

Raspberry Pi 3の場合

1. Dockerのインストール

Raspberry Pi 3上にDockerをインストールします。
以下のコマンドを実行してください。

command
git clone https://github.com/izewfktvy533zjmn/Build_RasPi_Kubernetes_Cluster.git
cd Build_RasPi_Kubernetes_Cluster/scripts/docker/raspi3
chmod +x ./install_docker_for_raspi3.sh
sudo ./install_docker_for_raspi3.sh

実行が終了すると、最後に下記のメッセージが現れます。

terminal
Done.
You should reboot your Raspberry Pi.

メッセージに従い、リブートします。

command
sudo reboot
2. Dockerの動作検証

リブート後、再度ログインを試みます。
下記のコマンドを実行し、Dockerがインストールされているか確認します。

command
docker -v

下記の結果のように、Dockerのバージョンが表示されればインストールは成功しています。

terminal
Docker version 19.03.8, build afacb8b

次に、Dockerの動作確認を行います。
下記のコマンドを実行してください。

command
docker info

以下のような結果が得られれば、Dockerは正常に動作しています。
docker_info.png
* 上記の画像はRaspberry Pi 4で実行した場合の結果ですが、Dockerが正常に動作している場合はほぼ同様の内容が得られます

Raspberry Pi 4の場合

1. Dockerのインストール

Raspberry Pi 4上にDockerをインストールします。
以下のコマンドを実行してください。

command
git clone https://github.com/izewfktvy533zjmn/Build_RasPi_Kubernetes_Cluster.git
cd Build_RasPi_Kubernetes_Cluster/scripts/docker/raspi4
chmod +x ./install_docker_for_raspi4.sh
sudo ./install_docker_for_raspi4.sh

実行が終了すると、最後に下記のメッセージが現れます。

terminal
Done.
You should reboot your Raspberry Pi.

メッセージに従い、リブートします。

command
sudo reboot
2. Dockerの動作検証

リブート後、再度ログインを試みます。
下記のコマンドを実行し、Dockerがインストールされているか確認します。

command
docker -v

下記の結果のように、Dockerのバージョンが表示されればインストールは成功しています。

terminal
Docker version 19.03.8, build afacb8b

次に、Dockerの動作確認を行います。
下記のコマンドを実行してください。

command
docker info

以下のような結果が得られれば、Dockerは正常に動作しています。
docker_info.png

Kubernetesのインストール

ラズパイにKubernetesをインストールします。
以下のコマンドを実行してください。

command
git clone https://github.com/izewfktvy533zjmn/Build_RasPi_Kubernetes_Cluster.git
cd Build_RasPi_Kubernetes_Cluster/scripts/kubernetes
chmod +x ./install_kubernetes.sh
sudo ./install_kubernetes.sh

実行が終了すると、最後に下記のメッセージが現れます。

terminal
Done.

マスターノードの設定

DockerとKubernetesのインストールが完了したマスターノード上で下記のコマンドを実行し、クラスター構築の初期化を行います。

commnd
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=${MASTER_NODE_IP_ADDRESS} --kubernetes-version v1.10.5 --ignore-preflight-errors=SystemVerification

マスターノードの初期化時に発行されるトークンの有効期限を無期限にするにはコマンドに "--token-ttl=0" を追加して実行します。

command
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=${MASTER_NODE_IP_ADDRESS} --kubernetes-version v1.10.5 --ignore-preflight-errors=SystemVerification --token-ttl=0

* ${MASTER_NODE_IP_ADDRESS}にはご自身のマスターノードのIPアドレスを記載してください

以下は実行例です。

command
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.3.252 --kubernetes-version v1.10.5 --ignore-preflight-errors=SystemVerification --token-ttl=0

実行コマンドが成功すると以下のような結果が得られます。
Kubernetesマスターノードの初期化
上記の結果をもとに以下のコマンドを実行し、クラスター構築の初期化を完了させます。

command
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

最後に、以下のコマンドを実行し、初期化したクラスターに対してネットワークプラグインの適用を行います。

command
cd Build_RasPi_Kubernetes_Cluster
cd cni
kubectl apply -f ./kube-flannel-arm.yaml

マスターノードの設定は以上です。

ワーカーノードの設定

クラスター構築におけるマスターノードの初期化時に得られた結果をもとにワーカーノードをクラスターに参加させます。

command
sudo kubeadm join ${MASTER_NODE_IP_ADDRESS}:6443 --token ${TOKEN} --discovery-token-ca-cert-hash ${DISCOVERY_TOKEN_CA_CERT_HASH_SHA256} --ignore-preflight-errors=SystemVerification

ワーカーノードがRaspberry Pi 4の場合は実行コマンドに "--ignore-preflight-errors=CRI" を追加して実行する必要があります。

command
sudo kubeadm join ${MASTER_NODE_IP_ADDRESS}:6443 --token ${TOKEN} --discovery-token-ca-cert-hash ${DISCOVERY_TOKEN_CA_CERT_HASH_SHA256} --ignore-preflight-errors=SystemVerification --ignore-preflight-errors=CRI

以下は実行例です。

command
sudo kubeadm join 192.168.3.252:6443 --token 7j6n1c.op2bgtxhem0opf4j --discovery-token-ca-cert-hash sha256:5128b0b624d57a44e08ecb0dfbb27c10469d3055bbe0fec1274e740930e9f3d9 --ignore-preflight-errors=SystemVerification --ignore-preflight-errors=CRI

クラスターへの参加が成功すると以下のような結果が得られます。
Kubernetesマスターノードの初期化
ワーカーノードの設定は以上です。

Kubernetesクラスターの動作検証方法

ここでは、Kubernetesクラスターの構築方法に従って構築したクラスターの動作検証を行います。

ワーカーノードにおける稼働状況の確認

マスターノードにて下記のコマンドを実行し、ワーカーノードがクラスター上で稼働しているか確認します。

command
kubectl get nodes -o wide

以下は実行例です。
kubectl_get_nodes.png

コンテナデプロイメントの検証

マスターノード上で以下のコマンドを実行し、ワーカーノード上でnginxのコンテナを起動させます。

command
cd Build_RasPi_Kubernetes_Cluster
cd sample
kubectl apply -f ./sample-nginx-dp.yaml

以下は実行例です
* この実行例ではreplicas数を調整しています
kubectl_get_pods.png
上記の結果に記載されているIPアドレスに対してHTTPリクエストを送り、ワーカーノード上でnginxのサービスにが稼働しているか検証します。

以下は実行例と実行結果です。

command
curl 10.244.14.3

curl.png
上記のような結果が得られればKubernetesクラスターは正常に動作しています。

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

Dockerを学習するための記事一覧

Dockerを学習するための記事をまとめてみました

エラーの対策も記述してます。

Running bundle update will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
ERROR: Service 'web' failed to build: The command '/bin/sh -c bundle install' returned a non-zero code: 6

参考になる記事一覧

今回の動画ではインストール完了済みなので、この記事は飛ばしています。
DockerをMacにインストールする(更新: 2019/7/13)

今回実施する記事は下記になります。
DockerでRailsの環境構築

Mysqlの設定方法は下記が参考になります。
丁寧すぎるDocker-composeによるrails5 + MySQL on Dockerの環境構築(Docker for Mac)

下記で $ docker-compose run web bundle installの方法が記載されてました。
DockerでRailsのプロジェクトを立ち上げるまで

下記のエラーが出た場合

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
ERROR: Service 'web' failed to build: The command '/bin/sh -c bundle install' returned a non-zero code: 6

bundle updateを実施します

ターミナル
$ docker-compose run web bundle update

docker-composeでよく使うコマンド(Ruby on Rails)

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