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

RailsをAWS ECS(Fargate)でホストする環境構築のすべて【1. 前談、N/W+α】

本記事シリーズの構成(予定)

  1. 前談、N/W+α(これ)
  2. Docker定義、ECRの設定
  3. ECSの設定、デプロイ
  4. SSMの設定

構築環境全体像

こんな感じを目指します。
スクリーンショット 2020-08-11 17.39.58.png

実現したいポイント
* Docker環境で開発を行っているRailsプロジェクトを、Fargate起動のECSでホストします。
* ECSタスクは複数設け、負荷分散します。
* AWS System Manager セッションマネージャを使用してECSに「接続し、CUIで操作可能にします。

ネットワーク+ALB+RDSの環境構築

VPC

サンプルなのでシンプルに作ります。
スクリーンショット 2020-08-11 18.03.43.png

作成した後、VPC一覧右上のアクション>DNSホスト名の編集から有効化をしておきます。
スクリーンショット 2020-08-11 18.18.48.png

サブネット

下記の通り、わかりやすくサブネットを切っておきます。

subnet CIDR
public-subnet-a 10.0.10.0/24
public-subnet-c 10.0.20.0/24
public-subnet-d 10.0.30.0/24

スクリーンショット 2020-08-11 18.04.13.png

インターネットゲートウェイ

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3433303630332f62343233356531372d633765372d353266352d616636622d3963356164396331336638622e706e67.png

作成したら、右上のアクション>VPCにアタッチから、
sample-vpcにアタッチするのを忘れずに。

スクリーンショット 2020-08-11 18.07.34.png

エンドポイント

この後設定していくサービスを利用するために、4つのエンドポイントを設けます。

  • com.amazonaws.ap-northeast-1.ecr.api
  • com.amazonaws.ap-northeast-1.ecr.dkr
  • com.amazonaws.ap-northeast-1.s3
  • com.amazonaws.ap-northeast-1.ssm

エンドポイントを選択して、
アタッチしたいサブネットはpublic-subnet-a,public-subnet-cの2つのみ指定。
スクリーンショット 2020-08-11 18.08.57.png

Interfaceタイプのエンドポイントには、セキュリティグループを適用する。
スクリーンショット 2020-08-11 18.18.06.png

エンドポイント用のセキュリティグループとして、443ポートを開けたセキュリティグループを作っておきましょう。
スクリーンショット 2020-08-11 18.17.09.png

S3はGatewayタイプなのでセキュリティグループではなく、ルートテーブルに従います。
スクリーンショット 2020-08-11 18.20.17.png

ルートテーブル

VPC作成時に自動作成されているものを編集します。

ルート一覧に、先ほど追加したエンドポイントの設定が加わっています。
ルートの編集ボタンを押下します。
スクリーンショット 2020-08-11 19.37.07.png

ここにインターネットゲートウェイへのルーティングを加えます。
スクリーンショット 2020-08-11 19.37.37.png

編集したルートテーブルにサブネットを関連づけます。
インターネットゲートウェイのルーティングを設定したルートテーブルに、サブネットを関連づけることで、
いわゆるpublic subnetになります。
スクリーンショット 2020-08-11 18.06.37.png

public-subnet-a,cはSSMを利用した接続時にパブリックでないとうまくできなかったため、セキュリティグループでIP、ポート制限をかけつつパブリック化する判断にしました。

public-subnet-dはデータベース用に取っていますが、データベースに外部からクライアント接続したいのでパブリックにしています。ここをパブリックにするかどうかは任意です。


ALB

アプリケーションロードバランサーを選択して作成していきます。
スクリーンショット 2020-08-11 18.12.59.png

実用するときには、SSL証明書を適用して443ポート開けることになると思いますが、
今回は検証なので、80ポート開けておきます。
スクリーンショット 2020-08-11 18.13.22.png

ルーティング先はECSをおくサブネットに絞って設定しています。
スクリーンショット 2020-08-11 18.13.27.png

セキュリティグループはここでついでに新規作成しています。
80ポートのインバウンドを設定しています。検証なのでマイIPのみにしたほうがよかったかも。
スクリーンショット 2020-08-11 18.14.02.png

ターゲットグループをここで一緒に新規作成します。
ターゲットの種類はIPにします。
ヘルスチェックはアプリケーションに用意したヘルスチェック用のパスを指定してください。
スクリーンショット 2020-08-11 18.14.34.png

ここはそのままでOK。
スクリーンショット 2020-08-11 18.14.54.png


RDS

作成内容は完全に任意です。
MySQL 8.0.19でインスタンスをパブリックアクセスありで作成しました。
スクリーンショット 2020-08-11 19.58.23.png

このときに適用したセキュリティグループは以下の通りです。
3306ポートをマイIPからのみアクセス可能にしています。
スクリーンショット 2020-08-11 20.01.22.png

まとめ

ここまででこんな感じの大枠まで作りました。
次の記事で、Dockerの定義と、コンテナイメージをECRにプッシュするまでを記載したいと思います。
スクリーンショット 2020-08-11 20.10.14.png

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

docker buildするとextconf failedout of memoryエラーが発生した話

使用技術

  • amazon linux2
  • Docker 19.03.6

エラーが発生した状況

イメージをbuildしようとしてdocker buildコマンドを実行すると下記エラー

docker extconf failedout of memory

その下に赤字でnokogiriがインストール出来ないと書いてあり指定されたコマンドを走らせ再度buildしてもエラーが直らず...。
(目立つ方ばかり気にしていて上記エラーに気づくのが遅れてしまった)

上記エラー文で検索するとAWSの無料枠内のEC2インスタンスタイプ、t2.microでは容量が足りないため課金しなくてはいけないとの記事を見つけ驚き。しかも月2000円ですと...。
課金しなくて済む方法が知りたい!

調べて判明した原因

dockerのvolumeが膨れ上がっていました。

以前もEC2のメモリが足りなくなり増設したのにまた!?と思いつつディスクの空き容量を調査

$ df -h
devtmpfs         474M     0  474M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M  436K  492M    1% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1        32G   13G   20G   40% /
tmpfs             99M     0   99M    0% /run/user/1001

大丈夫そう。

お次はディスクの使用量を調査

$ du -hs /*
.
.
.
4.4G    /usr
6.9G    /var  

6.9Gも使っていました。
ここがdockerコンテナの居場所なので原因はdockerですね。
ここまで分かると使えるキーワードも増えて検索がしやすいです(嬉しい)

ついにvolumeを減量していきましょう

$ docker system prune -a --volumes

docker systemは後ろにオプションをつけて、未使用のコンテナ、イメージ、ネットワーク、ボリュームを削除するコマンドです。

--volumes オプションはdocker17.06.1から追加されたようですのでそれ以前のバージョンでは使用できません。

これで再度使用量を調べると

$ du -hs /*
.
.
.
4.4G    /usr
2.9G    /var

減りました。よし。

参考

https://qiita.com/shione/items/dfa956a47b6632d8b3b3

https://qiita.com/381704/items/5d526e34da95fd307480

https://docs.docker.com/engine/reference/commandline/system_prune/

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

VSCode Remote-Containers で Laravel7 開発環境 ( CentOS8+PHP7.4+MongoDB4.4 ) を爆速で準備する

はじめに

Docker で開発環境コンテナをサクッと準備。実際の開発は VSCode + Remote-Containers ( 拡張機能 ) を使ってコンテナ内で行うための手順をまとめています。記事内容に間違いなどありましたら、コメント欄にてご指摘お願いいたします。
まだ色々と制約はありますが、とりあえずコンテナを立ち上げるところまでは上手くいったので公開します。

前提条件

  • Docker ( Windows/MacOS の方は Docker Desktop ) が使用できること
  • VSCode が使用できること

ファイル構成

以下の構成でディレクトリとファイルを作成していきます。
とりあえず動かしてみたい方は GitHub から Clone してください。

Project/
  ├─ .devcontainer/
  │    ├─ devcontainer.json
  │    └─ Dockerfile
  └─ mongodb-org.repo

手順.1 : VSCode に Remote-Containers ( 拡張機能 ) をインストール

VSCode に Remote-Containers という拡張機能をインストールしてください。

手順.2 : devcontainer.json 作成

.devcontainer/devcontainer.json
{
    "name": "test",
    "context": "..",
    "dockerFile": "Dockerfile",
    "settings": {
        "terminal.integrated.shell.linux": null,
        "workbench.startupEditor": "newUntitledFile",
        "editor.minimap.enabled": true,
        "vsicons.dontShowNewVersionMessage": true,
        "explorer.confirmDelete": false,
        "files.autoSave": "afterDelay"
    },
    "appPort": [ 8000, 27017 ],
    "remoteUser": "vscode",
    "workspaceFolder": "/var/www/html",
    "extensions": [
        "alefragnani.bookmarks",
        "mikestead.dotenv",
        "mhutchie.git-graph",
        "eamodio.gitlens",
        "onecentlin.laravel-blade",
        "austenc.laravel-blade-spacer",
        "onecentlin.laravel5-snippets",
        "cjhowe7.laravel-blade",
        "felixfbecker.php-pack",
        "vscode-icons-team.vscode-icons"
    ]
}

手順.3 : Dockerfile 作成

.devcontainer/Dockerfile
FROM centos:8

LABEL maintainer="slangsoft"
LABEL version="1.0"
LABEL description="Laravel sample project for trying out the VS Code Remote - Containers extension."

ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ARG PATH_LARAVEL=/var/www/html

# Basic settings
RUN set -x \
    && dnf -y upgrade \
    && dnf -y install sudo dnf-utils wget git \
    && groupadd --gid $USER_GID $USERNAME \
    && useradd --shell /bin/bash --uid $USER_UID --gid $USER_GID --create-home $USERNAME \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

# Install nginx
RUN  dnf -y install nginx

# Install php
RUN set -x \
    && dnf module reset php \
    && dnf -y install epel-release glibc-locale-source glibc-langpack-en \
    && dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm \
    && dnf -y module install php:remi-7.4

# Install Laravel
EXPOSE 8000
RUN set -x \
    && dnf -y install php-mcrypt php-pdo php-bcmath php-tokenizer php-xml php-mysqlnd php-gd php-intl php-zip php-opcache php-pecl-xdebug \
    && wget https://getcomposer.org/installer -O composer-installer.php \
    && php composer-installer.php --filename=composer --install-dir=/usr/local/bin \
    && composer self-update \
    && composer create-project laravel/laravel $PATH_LARAVEL --prefer-dist \
    && groupadd laravel \
    && gpasswd -a $USERNAME laravel \
    && gpasswd -a nginx laravel \
    && find $PATH_LARAVEL -type d -exec chmod 775 \{\} \; \
    && find $PATH_LARAVEL -type f -exec chmod 664 \{\} \; \
    && chown -R :$USERNAME $PATH_LARAVEL \
    && find $PATH_LARAVEL -type d -exec chmod g+s \{\} \; \
    && setfacl -R -d -m g::rwx $PATH_LARAVEL

# Install MongoDB
EXPOSE 27017
COPY ./mongodb-org.repo /etc/yum.repos.d/
RUN dnf -y install mongodb-org

# Set locale
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8"
ENV LANGUAGE="ja_JP:ja"
ENV LC_ALL="ja_JP.UTF-8"

# Working directory setting
WORKDIR $PATH_LARAVEL

手順.4 : mongodb-org.repo 作成

mongodb-org.repo
[mongodb-org-4.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc

手順.5 : コンテナ起動

コマンドパレットを開いて [remote-containers: Open Folder in Container...] を実行するとコンテナのビルドが始まります。無事にビルドが完了すると、コンテナ内で VSCode が起動します。

参考リンク

改訂履歴

  • 2020/08/11
    初版公開 ( ほとんど説明も無い叩き台記事 )
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VSCode Remote-Containers で Laravel7 開発環境 ( Centos8+PHP7.4+MongoDB4.4 ) を爆速で準備する

はじめに

Docker で開発環境コンテナをサクッと準備。実際の開発は VSCode + Remote-Containers ( 拡張機能 ) を使ってコンテナ内で行うための手順をまとめています。記事内容に間違いなどありましたら、コメント欄にてご指摘お願いいたします。
まだ色々と制約はありますが、とりあえずコンテナを立ち上げるところまでは上手くいったので公開します。

前提条件

  • Docker ( Windows/MacOS の方は Docker Desktop ) が使用できること
  • VSCode が使用できること

ファイル構成

以下の構成でディレクトリとファイルを作成していきます。
とりあえず動かしてみたい方は GitHub から Clone してください。

Project/
  ├─ .devcontainer/
  │    ├─ devcontainer.json
  │    └─ Dockerfile
  └─ mongodb-org.repo

手順.1 : VSCode に Remote-Containers ( 拡張機能 ) をインストール

VSCode に Remote-Containers という拡張機能をインストールしてください。

手順.2 : devcontainer.json 作成

.devcontainer/devcontainer.json
{
    "name": "test",
    "context": "..",
    "dockerFile": "Dockerfile",
    "settings": {
        "terminal.integrated.shell.linux": null,
        "workbench.startupEditor": "newUntitledFile",
        "editor.minimap.enabled": true,
        "vsicons.dontShowNewVersionMessage": true,
        "explorer.confirmDelete": false,
        "files.autoSave": "afterDelay"
    },
    "appPort": [ 8000, 27017 ],
    "remoteUser": "vscode",
    "workspaceFolder": "/var/www/html",
    "extensions": [
        "alefragnani.bookmarks",
        "mikestead.dotenv",
        "mhutchie.git-graph",
        "eamodio.gitlens",
        "onecentlin.laravel-blade",
        "austenc.laravel-blade-spacer",
        "onecentlin.laravel5-snippets",
        "cjhowe7.laravel-blade",
        "felixfbecker.php-pack",
        "vscode-icons-team.vscode-icons"
    ]
}

手順.3 : Dockerfile 作成

.devcontainer/Dockerfile
FROM centos:8

LABEL maintainer="slangsoft"
LABEL version="1.0"
LABEL description="Laravel sample project for trying out the VS Code Remote - Containers extension."

ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ARG PATH_LARAVEL=/var/www/html

# Basic settings
RUN set -x \
    && dnf -y upgrade \
    && dnf -y install sudo dnf-utils wget git \
    && groupadd --gid $USER_GID $USERNAME \
    && useradd --shell /bin/bash --uid $USER_UID --gid $USER_GID --create-home $USERNAME \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

# Install nginx
RUN  dnf -y install nginx

# Install php
RUN set -x \
    && dnf module reset php \
    && dnf -y install epel-release glibc-locale-source glibc-langpack-en \
    && dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm \
    && dnf -y module install php:remi-7.4

# Install Laravel
EXPOSE 8000
RUN set -x \
    && dnf -y install php-mcrypt php-pdo php-bcmath php-tokenizer php-xml php-mysqlnd php-gd php-intl php-zip php-opcache php-pecl-xdebug \
    && wget https://getcomposer.org/installer -O composer-installer.php \
    && php composer-installer.php --filename=composer --install-dir=/usr/local/bin \
    && composer self-update \
    && composer create-project laravel/laravel $PATH_LARAVEL --prefer-dist \
    && groupadd laravel \
    && gpasswd -a $USERNAME laravel \
    && gpasswd -a nginx laravel \
    && find $PATH_LARAVEL -type d -exec chmod 775 \{\} \; \
    && find $PATH_LARAVEL -type f -exec chmod 664 \{\} \; \
    && chown -R :$USERNAME $PATH_LARAVEL \
    && find $PATH_LARAVEL -type d -exec chmod g+s \{\} \; \
    && setfacl -R -d -m g::rwx $PATH_LARAVEL

# Install MongoDB
EXPOSE 27017
COPY ./mongodb-org.repo /etc/yum.repos.d/
RUN dnf -y install mongodb-org

# Set locale
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8"
ENV LANGUAGE="ja_JP:ja"
ENV LC_ALL="ja_JP.UTF-8"

# Working directory setting
WORKDIR $PATH_LARAVEL

手順.4 : mongodb-org.repo 作成

mongodb-org.repo
[mongodb-org-4.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc

手順.5 : コンテナ起動

コマンドパレットを開いて [remote-containers: Open Folder in Container...] を実行するとコンテナのビルドが始まります。無事にビルドが完了すると、コンテナ内で VSCode が起動します。

参考リンク

改訂履歴

  • 2020/08/11
    初版公開 ( ほとんど説明も無い叩き台記事 )
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerの使い方 2日でDocker習得編 (udemy 米国AI開発者がゼロから教えるDocker講座)

660_bit202003301411424272.jpg

Docker マスコットのmobyくん

目標 

祝日丸一日 8/10   半日勤務日 8/11の合計2日(実質1.5日)でDockerを叩き込む

以下、学習のログ (1日目)

前提

Q 仮想化とは?
 仮想化は、PCの中に仮想的なコンピューターを作る技術です。一台のPC内に、MAC、Windowsなど別のPCが入っているイメージです。(そう見せかける技術)

Q 仮想化とコンテナの違い
 コンテナは仮想OSを立ち上げる必要がありません!ホスト(自分のPC)のOSのカーネルを共有することによって、
 独立した環境設定を作る技術です。

クラウドとのつながりが深いので、クラウドの勉強もするとより解像度が上がりそうです。(今度、深めます)

Qクラウドとは?
 サーバーの一部を貸し出すことです。
 ex)AWS
AWSの用意したマシンのリソース(容量)のうち、ある部分だけを仮想マシンを作ってもらい、使わせてもらうことです。

概念基本

bft_container_ojisan_03_08.jpg

基本操作

LINUXコマンド 内容

cd <path>|        pathに移動 (cd = change the directory)
pwd|              現在のディレクトリを表示
mkdir|             <new folder> 新しいフォルダを作成
touch <new file>| 新しいファイルを作成
ls |              cd のフォルダ一覧を表示
rm <file> |      fileを削除
rm-r <folder> |  folderを削除 

kernerlとShell

shell2.png

shellを起動するためのアプリがターミナル

1 Docker image 作成(hubを使う)

1 Docker hub へログイン
$docker login

2 hubからimageをpullする
$docker pull

3 docker image を起動(run) (コンテナを作る)
$docker run -it <image> bash

4 コンテナから出る 
$exit

5 ホストにあるコンテナ一覧表示
$docker ps -a

6ホストにあるイメージを表示
$docker images

7exit状態のコンテナに入る
$docker restart

8指定したプログラムを実行
$docker exec -it<container> bash

9コンテナから新しいimageを作る
$docker commit images

10新しい名前にをタグづけする
$docker tage <oldname><newname>

11 docker hub にあげる
$docker push

docker layer のイメージ 
(point) 新しく層(layer)を追加するだけで、コンテナに機能(プログラムex pythonなど)を追加できる。

sharing-layers (1).jpg

3 Docker コンテナ

Q runとは? 
A run = create+ start

コンテナの削除

$ docker rm  削除(1〜)  (※複数指定したい場合は、スペースあける)
$ docker system prune 全削除

コンテナの名前をつける
$docker run --name<name> image

コンテナの使い方 2つ
1 常に起動    
2 時々使い、すぐ捨てる

detatch mode (コンテナを起動後、deatchする)
$docker run -d <image>

foregraound mode (一回きりの起動で捨てる)
$docker run --rm <image>

4 Docker file

Docker file→Docker image を作る(ビルド)

dockerfileの作り方
INSTRUCTION (命令コマンド)  argument(引数) で作る
主な4つ
FROM
ADD
RUN
CMD

FROM image   元となるイメージ
FROM ubuntu:latest

RUN Linux コマンドの実行
RUN touch test (ファイルを作成)

(重要)Docker image layerの数は最小限にする
 (理由)runするたびにコンテナが作られ、開発現場において、容量が圧迫される
(layer を作るのはrun,copy,addの3つ)

CMD コンテナのデフォルトのコマンドを指定
CMD[executable(コマンド)]
最後に記述する
・1つのDockerfileに一つだけ

docker context と docker deamonの仕組み

architecture.png

Docker Context(状況・環境) =Docker fileのあるFolder のこと
Docker Context(★フォルダまるごと)をデーモンに渡し、デーモンが処理を行うことでコンテナが作られる。

COPYとADD

基本COPYでよい
ADDはホストに圧縮したファイルがあって、それを解凍してコンテナ落としたいときに使う。

ENV 環境変数を設定 (↓よくある書き方2選)
ENV 1
2 =

WORKDIR
デフォルトだとdcokerfileからdockerimageを作る際、コンテナ側のroot直下にフォルダを作成する。
それを避けるために、WORKDIRで作りたいフォルダを指定する。

ホストのファイルシステムをコンテナにマウントする

docker-v01-300x144.png

目的
・コンテナを軽くするため(共有するものであるため)
コンテナは解析をするための場所(実行環境)として使い、ホストにコードを置く。

<マウントのやり方>
docker run (-it) -v <hostのパス> <containerのパス> (bash)
 ★-vをつけてコンテナを実行する
 ★かなりの頻度で使う
 ★コンテナ操作側がroot権限で実行するため、セキュリティ上問題

root権限問題の解消 (ユーザーIDとグループIDを指定して、コンテナをRUNする)
run -u <ユーザーID>:<グループID>
        $(id -u):$(id -g) 

#Linuxコマンド
ユーザーIDの指定 
id -u
グループIDの指定
id -g

パーミッション(アクセス権限)見方

d   rwx    rwx        rwx       (実際 drwxrwxw-xwなどと書かれる)
 (所有者)  (所有グループ)  (その他)

"d"ディレクトリ  "-"ファイル   "l"シムリンク

ホストのポートをコンテナのポートにつなげる

※ポート・・アクセスできる入り口
ネットワーク通信で必要な「プロトコル」 「IPアドレス」と「ポート番号」が必要
ex)マンション 、「どのような方法」で「どこのマンション(コンピュータ)」の「何号室(何番ポート)」を使うか

20181118153602.png

重要     ホスト→コンテナへポートを繋げるやり方

-p <host-port>:<container-port>

コンテナをWEBサービスとして立てる

CPU・メモリの上限を設定する

*共同開発だと1台のホストサーバー(クラウド上など)に負荷がかかりすぎて、ダウンすることもある・・。

<やり方>

$docker run -it --rm --cpus 4 --memory 2g ubuntu bash
                      (CPU上限) (メモリ上限)

コンテナの情報を一覧表示

dockler inspect <container>
docker inspect <container> | grep -i cpu #特定の情報のみ表示 ここではCPU

補足 
・コンテナを実行するとroot権限(管理者権限=何でもできる権限)になる。
・環境変数
・OSが持っている変数(全てのプログラムに適用される) 変更可能
ex)HOME,PATH,USER
・プロンプト($) 意味 ここから入力しなさい
・CLI コマンドでのマシンとの対話
・Registory ソフトの情報が書いてあるところ

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

Docker Desktop for Windowsを使って、最新のodooを2コマンドで起動させる

docker/odoo

odooをご存じでしょうか。odooは、pythonで実装されたオープンソースのERPとして、有名ですが、実は、業務アプリケーションのノンコーディングツール(Odoo Studio)でもあります。

image.png
Odoo Studio: Build an App from Scratch with Zero Coding Experience 2019/11/13

これまで、odooを試すのに、Linuxのインストールから始まり、python環境の構築、データベースとなるpostgreSQLの設定やWebサーバーの設定など、いくつかの手順が必要でした。それが、Dockerの登場により、2コマンドで、odooをインストールし、起動することができるようになりました。もちろん、odooもDocker公式イメージとして、登録されています。

準備 - Dockerのインストール

ここでは、Windows10で、Docker Desktop for Windowsを使って、最新のodooを2コマンドで起動させます。
まずは、Docker Desktop for Windowsをインストールします。
https://docs.docker.jp/docker-for-windows/toc.html

dockerでodooを起動

odooは、Docker Hubに公式イメージとして登録されていますので、2つのコマンドで起動が可能です。

コマンド1 - データベースの起動

まずは、データベースであるPostgreSQLのコンテナをバックグラウンドで実行します。
初回の起動時に、必要なモジュールのインストールが自動的に行われます。

# 項目 内容
1 コマンド docker run
2 コンテナをバックグラウンドで実行 する (-d)
3 POSTGRES_USER (-e) odoo
4 POSTGRES_PASSWORD (-e) odoo
5 POSTGRES_DB (-e) postgres
6 コンテナの名前(--name) db
7 Dockerイメージ postgres:10
doccker.db.cmd
docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres:10

コマンド2 - odooの起動

先に起動したPostgreSQLのコンテナにリンクするようにして、odooのコンテナを起動します。

# 項目 内容
1 コマンド docker run
3 ホスト側に公開するコンテナのポート (-p) 8069:8069
4 コンテナの名前 (--name) odoo
5 他のコンテナへのリンク (--link) db:db
6 疑似ターミナルを割り当て する (-t)
7 Dockerイメージ odoo
docker.odoo.cmd
docker run -p 8069:8069 --name odoo --link db:db -t odoo

結果

コマンドプロンプト.cmd
Microsoft Windows [Version 10.0.18363.959]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Users\dev>docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres:10
Unable to find image 'postgres:10' locally
10: Pulling from library/postgres
75cb2ebf3b3c: Pull complete                                                                                             3ca6415d2bca: Pull complete                                                                                             ac08e6372a7b: Pull complete                                                                                             b4394fce95ce: Pull complete                                                                                             6edcd5da08e3: Pull complete                                                                                             3380dcb7db08: Pull complete                                                                                             c7c147d9c90d: Pull complete                                                                                             08ae47fef758: Pull complete                                                                                             3d807fd80688: Pull complete                                                                                             3f37a1ee389c: Pull complete                                                                                             cea1ff8f661e: Pull complete                                                                                             064c69d8ca75: Pull complete                                                                                             96c4055cb7f7: Pull complete                                                                                             4477915a4c1f: Pull complete                                                                                             Digest: sha256:e3a02efdce3ec64cfdb76a8ff93ae14d3294e47a0203d8230c8853a3890fe340
Status: Downloaded newer image for postgres:10
05ae7b08b1800ef560a3b6dca95c4071163b3d1582ffc224d87f2e77a29ab9a9

C:\Users\dev>docker run -p 8069:8069 --name odoo --link db:db -t odoo
Unable to find image 'odoo:latest' locally
latest: Pulling from library/odoo
bf5952930446: Already exists                                                                                            fa677b64d95a: Pull complete                                                                                             2dd4309767ba: Pull complete                                                                                             6ffbc48d26ec: Pull complete                                                                                             d6f4cbbe7cdf: Pull complete                                                                                             338ad56bea8c: Pull complete                                                                                             d6c8b0326958: Pull complete                                                                                             6fd5f5f6c87c: Pull complete                                                                                             24ccac123804: Pull complete                                                                                             Digest: sha256:a0a1f89921d66751b8f94042f4bd291d4761858ef4f4262a0b27de8cf70b74d6
Status: Downloaded newer image for odoo:latest
2020-08-11 03:43:19,685 1 INFO ? odoo: Odoo version 13.0-20200629
2020-08-11 03:43:19,685 1 INFO ? odoo: Using configuration file at /etc/odoo/odoo.conf
2020-08-11 03:43:19,686 1 INFO ? odoo: addons paths: ['/usr/lib/python3/dist-packages/odoo/addons', '/var/lib/odoo/addons/13.0', '/mnt/extra-addons']
2020-08-11 03:43:19,687 1 INFO ? odoo: database: odoo@172.17.0.2:5432
2020-08-11 03:43:19,935 1 INFO ? odoo.addons.base.models.ir_actions_report: Will use the Wkhtmltopdf binary at /usr/local/bin/wkhtmltopdf
2020-08-11 03:43:20,096 1 INFO ? odoo.service.server: HTTP service (werkzeug) running on 3dd0bcf7ca1d:8069

image.png

ログイン(初回)

次のURLで、odooにログインします。

http://localhost:8069/

image.png

コマンドプロンプトには、疑似ターミナルとして、次のように標準出力されます。

コマンドプロンプト.cmd
2020-08-11 06:12:57,654 1 INFO ? odoo.http: HTTP Configuring static files
2020-08-11 06:12:57,685 1 INFO ? odoo.http: Generating nondb routing
2020-08-11 06:12:57,709 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET / HTTP/1.1" 303 - 1 0.013 0.036
2020-08-11 06:12:57,732 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET /web HTTP/1.1" 303 - 2 0.005 0.010
2020-08-11 06:12:57,853 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET /web/database/selector HTTP/1.1" 200 - 2 0.004 0.098
2020-08-11 06:12:57,895 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET /web/static/lib/fontawesome/css/font-awesome.css HTTP/1.1" 200 - - - -
2020-08-11 06:12:57,896 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET /web/static/lib/bootstrap/css/bootstrap.css HTTP/1.1" 200 - - - -
2020-08-11 06:12:57,904 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET /web/static/lib/jquery/jquery.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:57,964 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET /web/static/lib/popper/popper.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:57,982 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:57] "GET /web/static/lib/bootstrap/js/index.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,005 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/util.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,033 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/alert.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,036 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/button.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,053 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/carousel.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,063 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/collapse.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,091 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/dropdown.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,094 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/tooltip.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,095 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/modal.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,112 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/popover.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,127 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/scrollspy.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,135 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/bootstrap/js/tab.js HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,152 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/src/img/logo2.png HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,360 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/lib/fontawesome/fonts/fontawesome-webfont.woff2?v=4.7.0 HTTP/1.1" 200 - - - -
2020-08-11 06:12:58,399 1 INFO ? werkzeug: 172.17.0.1 - - [11/Aug/2020 06:12:58] "GET /web/static/src/img/favicon.ico HTTP/1.1" 200 - - - -

おわりに

Windows 10 上で、Docker Desktop for Windows をインストールし、2つのコマンドで、最新のodooを起動できることを確認しました。
* 準備 - Docker Desktop for Windows のインストール
* コマンド1 - PostgreSQLのコンテナの起動
* コマンド2 - odooのコンテナの起動

odoo は、pythonで実装されたオープンソースのERPでもありますが、Odoo Studioを使って、ノンコーディングの高速開発が可能です。

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

dockerでvimをつかう

このコマンドを実行でインストール

apt-get update
apt-get install vim

以上。

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

Rails 画像投稿機能作成

概要

※自分用メモです。
carrierwave,miimagickを使って画像投稿機能を作成手順について説明します。

使用イメージ

Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    node.js \
    postgresql-client \
    yarn \
    vim \

【参考】
以下の記事を参考にしました。

Rails 画像アップロード機能の実装方法 メモ
  https://qiita.com/STHEXA/items/05a492bd9cf4cf31ba98

【Rails】CarrierwaveとMiniMagickを使って画像を投稿する方法
  https://techtechmedia.com/carrierwave-minimagick-image/

Gemの紹介

・Carrierwave

画像をアップロードするためのgem

・Minimagick

画像を加工してくれるgem

※MiniMagickを使うにはImageMagickというものをインストールする必要があるので注意しましょう。

ImageMagickは、画像処理ライブラリです。

・画像サイズ変更
・画像反転
・画像回転
・画像フォーマット変換
・色調整
・グラデーション

といった様々な画像処理を行うことができます。

1.Dockerfile編集

参考にした記事によるとCarrierwaveの導入には「ImageMagick」がインストールされている必要があるみたいでしたので
DockerfileにImageMagickをインストールする記述を追記します。

Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    node.js \
    postgresql-client \
    yarn \
    vim \
    imagemagick     #←追記

2.Gemfile編集

GemfileにCarrierwaveとMinimagickを追記します

gemfile
gem 'carrierwave'
gem 'mini_magick'

3.docker-compose build 及び bundle installを実行

※dockerfileにRUN bundle installを記述してあればdocker-compose buildを行えば
gemもインストールすることができます。

$ docker-compose build 

4.アップローダーの作成

carrierwaveを利用するためのアップローダーを作成します。
※carrierwaveを導入したことで以下のコマンドが使えるようになります。

$ docker-compose exec web rails g uploader image 

もしくは

$ docker-compose exec web bash
$ rails g uploader image

上記のどちらかのコマンドで作成できます。

出力結果
# rails g uploader image
      create  app/uploaders/image_uploader.rb

5.画像アップロードのフォームを作成(モデル,ビュー,コントローラー)

・モデル編集

app/models/post.rb
class Post < ApplicationRecord
    mount_uploader :image, ImageUploader
end

・コントローラー編集

app/controllers/posts_controller.rb
  def create
    @post = Post.new(post_params)
  end

  private

  def post_params
    params.require(:post).permit(:image)
  end

・ビュー編集

app/views/posts/new.html.erb
<%= form_with model: @post, local: true do |f| %>

    <div class="form-group">
        <%= f.label :image, '画像' %>
        <%= f.file_field :image, accept: 'image/jpeg,image/gif,image/png' %>
    </div>
<%end%>

スクリーンショット 2020-08-11 14.16.11.png

※ここで以下のようなエラーが出ました。
uninitialized constant Post::ImageUploader

コンテナを一旦落として再度コンテナを立ち上げ直すと解消されました。

いろいろ調べていると再起動すればうまくいく?
とのことが書かれていたので試してみたところうまくいきました。

6.アップロードされたときのサイズを設定

標準でアップロードされると大きいサイズの画像がアップロードされるのでサイズを変えるように設定します。

app/uploaders/image_uploader.rbに設定していきます。

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  # ↓コメントアウト外す。
  include CarrierWave::MiniMagick

  # アップロードできるファイルの種類を制限
  def extension_whitelist
    %w(jpg jpeg gif png)
  end

  # アップロードするサイズの制限
  process resize_to_fit: [700, 700]

  # サムネイルサイズの設定
  version :thumb do
    process resize_to_fill: [100, 100]
  end

補足

アップロードされた画像はどこへ保存されるの?

app/uploaders/image_uploader.rbに記述されています。

app/uploaders/image_uploader.rb
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

これはuploadeの中に保存されるという意味です

publicの中にuploadeのフォルダが作成されて保存されます。

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

Docker × Laravel テスト用のデータベースコンテナを構築する

Laravelでデータベースのテストを行う時、RefreshDatabasefactoryなど便利なメソッドやトレイトが用意されています。
これらを使ってテストを行いますが、Dockerでデータベースコンテナ一つでやると開発で使ってるデータがクリアされてしまってあまりよろしくないです。

今回はテストする時はテスト用のデータベースを使うように設定します。

前提

当記事は上記の記事の補足になる記事です。

Laravel環境構築

$ git clone git@github.com:ucan-lab/docker-laravel.git
$ cd docker-laravel/infrastructure
$ make create-project

手順

infrastructure/docker-compose.yml を編集する

$ cd infrastructure
$ docker-compose down

docker-compose.ymlDockerfile を変更する場合は予めコンテナを破棄しておくと良いです。

infrastructure/docker-compose.yml
  db-testing:
    build: ./docker/mysql
    tmpfs:
      - /var/lib/mysql

db-testing サービスの設定を services 配下に追記します。

tmpfsはLinux環境でのみ動作すると書いてありましたが、Docker for Macでも動作するっぽいので使ってみました。
動かない場合はnamed volumeを使うといいかもです。

$ docker-compose up -d

コンテナを作成して起動します。

$ docker-compose ps
           Name                          Command              State                 Ports              
-------------------------------------------------------------------------------------------------------
docker-laravel_app_1          docker-php-entrypoint php-fpm   Up      9000/tcp                         
docker-laravel_db-testing_1   docker-entrypoint.sh mysqld     Up      3306/tcp, 33060/tcp              
docker-laravel_db_1           docker-entrypoint.sh mysqld     Up      0.0.0.0:3306->3306/tcp, 33060/tcp
docker-laravel_web_1          nginx -g daemon off;            Up      0.0.0.0:80->80/tcp

db-testing のコンテナが起動していればokです。

backend/phpunit.xml

backend/phpunit.xml
    <php>
        <server name="APP_ENV" value="testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="DB_CONNECTION" value="sqlite"/>
        <server name="DB_DATABASE" value=":memory:"/>
        <server name="MAIL_MAILER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
        <server name="TELESCOPE_ENABLED" value="false"/>
    </php>
backend/phpunit.xml
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="DB_HOST" value="db-testing" force="true"/>
        <env name="MAIL_MAILER" value="array"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="TELESCOPE_ENABLED" value="false"/>
    </php>

serverではなくenvに変更してます。
DockerfileDB_HOST のサーバー環境変数を設定しているので、 force="true" オプションで上書きしてあげます。

サンプルのテストを作成

backend/tests/Feature/SampleTest.php
<?php declare(strict_types=1);

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\User;

class SampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testExample()
    {
        factory(User::class)->create(['name' => 'sample']);
        $this->assertEquals(1, User::where('name', 'sample')->count());
    }
}

テスト実行

$ php artisan test
   PASS  Tests\Unit\ExampleTest
  ✓ basic test

   PASS  Tests\Feature\ExampleTest
  ✓ basic test

   PASS  Tests\Feature\SampleTest
  ✓ example

  Tests:  3 passed
  Time:   3.74s

テストが通ったことを確認できればokです。
db データベースのデータも消えていないことを確認してください。

補足: backend/.env.testing

phpunit.xml ではなく .env.testing で環境変数を上書きする方法もあります。
その場合、 Dockerfile で設定したサーバー環境変数の方が優先されてしまうのでそちらは削除してください。

$ cp .env.example .env.testing
$ php artisan key:generate --env=testing
.env.testing
DB_CONNECTION=mysql
DB_HOST=db-testing
DB_PORT=3306
DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=secret
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ubuntu 16.04でAlibaba Cloud ECSインスタンスにRancherをインストールする方法

今回のブログでは、Ubuntu 16.04でインストールしたAlibaba Cloud ECSインスタンスにRancherをインストールする方法を紹介します。

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

前提条件

Alibaba Cloud Elastic Compute Service (ECS)インスタンスが有効化されており、有効な支払い方法を確認している必要があります。新規ユーザーの場合は、Alibaba Cloudアカウントで無料アカウントを取得することができます。ECSインスタンスのセットアップ方法がわからない場合は、このチュートリアルまたはクイックスタートガイドを参照してください。ECSインスタンスには、少なくとも1GBのRAMと1つのCoreプロセッサが必要です。

手順

以下の手順に従って、Alibaba Cloud ECSインスタンスにRancherをインストールする方法を説明します。

Dockerのインストール

Rancherをインストールして実行する前に、RancherにはDockerが必要なので、まずDockerをインストールする必要があります。まず、以下のコマンドで古いdockerファイルを削除します。

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

次に、利用可能なパッケージをすべてアップデートします。sudo apt-get updateコマンドを実行すると、それがあなたのために仕事をしてくれます。次に、以下のコマンドを使用して、aptがHTTPSでリポジトリを使用できるようにするためのパッケージをインストールします。

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

以下のコマンドでDockerの公式GPGキーを追加します。

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

ここで、キーの指紋の最後の 8 桁を検索して、キー 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 を持っていることを確認します。次のコマンドを使用できます。

sudo apt-key fingerprint 0EBFCD88

このような出力が表示されるはずです。

pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

ここで、以下のコマンドを使用して安定版リポジトリを設定します。

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

次に、sudo apt-get updateコマンドを使ってパッケージリストを再度更新し、以下のコマンドを使ってリポジトリ内のDockerの利用可能なバージョンを全てリストアップします。

apt-cache madison docker-ce

出力はこんな感じになるはずです。

docker-ce | 17.09.1~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 17.09.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 17.06.2~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 17.06.1~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 17.06.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 17.03.2~ce-0~ubuntu-xenial | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages

以下のコマンドで=の後に最新の安定版の2列目であるversion-stringを追加して、Docker CEの最新バージョンをインストールします。次に、以下のコマンドを使用して、お好みの特定のバージョンのDockerをインストールします。

sudo apt-get install docker-ce=17.09.1~ce-0~ubuntu

バージョン文字列を付けずにDockerをインストールすることもできますが、本番環境用に特定のバージョンのDockerをインストールすることをお勧めします。以下のコマンドでDockerが正しくインストールされていることを確認してください。

sudo docker run hello-world

このコマンドは、テストイメージをダウンロードし、コンテナ内で実行します。コンテナが実行されると、情報メッセージを表示して終了します。以下の出力のようなメッセージが表示されるはずです。

Hello from Docker!

このメッセージは、インストールが正しく動作しているように見えることを示しています。

このメッセージを生成するために、Dockerは以下の手順を実行しました。

1、DockerクライアントがDockerデーモンに連絡しました。
2、DockerデーモンがDocker Hubから「hello-world」イメージを引っ張ってきました。(amd64)
3、Dockerデーモンはそのイメージから新しいコンテナを作成しました。
4、Dockerデーモンはその出力をDockerクライアントにストリーム配信し、その出力をターミナルに送信しました。

もっと野心的なことに挑戦するには、Ubuntuのコンテナを使って実行してみましょう。

 $ docker run -it ubuntu bash

無料のDocker IDでイメージの共有や、ワークフローを自動化。
https://cloud.docker.com/

その他の例やアイデアについては、こちらをご覧ください。
https://docs.docker.com/engine/userguide/

Rancherのインストール

必要な依存関係をすべてインストールしたので、Rancherをインストールして実行する準備ができました。以下の Docker コマンドを実行してください。

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

Rancher サーバーの起動には 1 分もかかりません。その後、お気に入りのウェブブラウザを開き、お使いのサーバーの http://YourServerIP:8080 のポート 8080 にアクセスしてください。何も問題がなければ、Rancher のユーザーインターフェースが表示され、最初のクラスターを追加する際のガイドが表示されます。

image.png

Rancherのアクセス制御を設定する

Rancher をインストールした後は、アクセス制御の設定を行う必要があります。Rancher のアクセスコントロールを設定することで、Rancher サーバーへのアクセス権を持つユーザーを管理することができます。

ウェブページ上部のADMINメニューにカーソルを合わせ、アクセスコントロールをクリックします。ここではローカル認証を使用したいので、LOCAL をクリックし、ユーザー名とパスワードを入力します。最後に、ローカル認証を有効にするボタンをクリックします。ローカル認証が有効になった状態でRancherのダッシュボードにリダイレクトされます。

新しいホストを追加する

ホストは Rancher 内で最も基本的なリソースの単位であり、仮想または物理の Linux サーバーとして表現されます。Rancher に新しいホストを追加するには、新しい Alibaba Cloud ECS インスタンスを作成する必要があります。ここでは、Ubuntu オペレーティングシステムを搭載し、2GB 以上の RAM を持つ新しい Alibaba Cloud ECS インスタンスを使用しています。まず、この2つのサーバーを区別するために、新しいホスト名を設定します。以下のコマンドを実行し、任意のホスト名を設定します。

sudo hostnamectl set-hostname host01

ここで、次のように ssh を使ってホストサーバに接続します。

ssh sajid@IPAddress of host01  

次に、このスクリプトを使って最新のDockerをインストールします。

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

このスクリプトをsh get-docker.shコマンドを使って実行すると、仕事をしてくれます。Dockerをインストールしたら、以下のコマンドを使ってdockerサービスを起動し、起動時に起動できるようにする必要があります。

systemctl start docker
systemctl enable docker

次に、Rancherサーバーにrancher host01を追加する必要がありますが、そうするには、Rancherのダッシュボードを開き、INFRASTRUCTURメニューにカーソルを移動し、Hostsをクリックします。次の画面で、ホストの追加ボタンをクリックすると、ホストの登録URLを聞かれるので、ここではデフォルトを使用して保存ボタンをクリックします。

次の画面では、ホストの種類を選択します。RancherはAmazon EC2, Azure, DigitalOcean, Exoscaleなど多くのホストタイプをサポートしています。とりあえず、カスタムホストタイプを選択し、rancher host01サーバーのIPアドレスを入力し、ボックスにDockerコマンドをコピーします。

今度はrancher host01のターミナルシェルに行き、このようにdockerコマンドを貼り付けます。

sudo docker run -e CATTLE_AGENT_IP="192.168.33.11"  --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.9 http://192.168.33.10:8080/v1/scripts/C7871D15E9CE6FFA892F:1514678400000:T9qDygb2pHroTMBuqA9Jylol8tU

上記のコマンドを実行すると、rancher-host01 サーバー上に新しいコンテナ Rancher Agent がダウンロードされ、作成されます。最後に、Rancher ダッシュボードのホスト追加ページに戻り、閉じるボタンをクリックしてください。

最後に

このチュートリアルでは、Ubuntu 16.04でインストールしたAlibaba Cloud ECSインスタンスにDockerとRancherをインストールする方法を学びました。また、Alibaba Cloud ECSインスタンス上でDockerとRancherを設定しました。さらに、同様にRancherホストを追加しました。これで、より多くのホストをデプロイすることができ、他のコンテナやアプリケーションをデプロイする準備が整いました。

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

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

Docker 19.03でのルートレスコンテナ:コンテナのセキュリティと管理性の向上

このブログ記事では、Docker 19.03で導入されたルートレスコンテナについて、この機能がコンテナのセキュリティと管理性をどのようにさらに向上させているかを取り上げています。

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

なぜルートレスコンテナなのか

DockerやKubernetesが一般的になってきたことで、コンテナのセキュリティも大きな関心事になってきています。Dockerはアプリケーションの仮想化機能を提供し、ネームスペースやcgroupsを通じてリソースの分離やクォータの制約を実装しています。Docker Engineは以下のようなクライアント・サーバー構造を持っています。

Dockerクライアント(TCP/Unix Socket)→Dockerデーモン(親子プロセス)→コンテナ

Linuxのネームスペースの作成やファイルシステムのマウントには特権的な機能が必要なため、Docker Daemonは常にrootユーザーが起動する必要がありました。これにより、DockerにアクセスできるユーザーはDocker Engineに接続することでroot権限を取得し、システムの監査機能を迂回して攻撃を仕掛けることができます。これにより、一部のシナリオではコンテナの適用ができなくなっています。例えば、ハイパフォーマンスコンピューティングの分野では、従来のリソース管理やスケジューリングシステムではコンテナを非特権ユーザーが実行する必要があるため、コミュニティは別のコンテナランタイム-Singularityを実装しなければなりません。

MobyとBuildKitメンテナの須田昭宏氏の素晴らしい仕事により、Docker EngineとBuildKitにルートレスサポートが追加されました。このサポートにより、Docker Engineを非特権ユーザとして実行することが可能になり、Linuxセキュリティシステムのより良い再利用が可能になりました。

注意事項
1、現在、ルートレスコンテナは実験モードで利用可能です。cgroupsリソース制御、apparmorセキュリティプロファイル、チェックポイント/リストアなど、一部の機能はまだサポートされていません。
2、現在、Ubuntuのみがルートレスモードでのオーバーレイファイルシステムをサポートしています。セキュリティ上の理由から、このソリューションはアップストリームのサポートを受けていません。他のオペレーティングシステムでは、ルートレスモードはvfsストレージドライバを使用するため、パフォーマンスに影響を与える可能性があります。そのため、ルートレスモードはI/Oを多用するアプリケーションには適していません。

関連するコア技術

最初の鍵は、ユーザ名前空間を活用することです。ユーザー名前空間はユーザーIDの範囲をマッピングするので、内側の名前空間のルートユーザーが親名前空間の非特権範囲にマッピングされます。Docker Engineはすでに対応する機能をサポートするために--userns-remapフラグを提供しており、より優れたコンテナセキュリティを提供しています。ルートレスモードも同様に動作しますが、Dockerデーモンもリマップされた名前空間で実行されます。

image.png

非特権ユーザーはユーザーネームスペースにネットワークネームスペースを作成し、iptablesのルール管理やtcpdumpなどの操作を行うことはできますが、ホストとコンテナをまたいでvethペアを作成することはできず、コンテナにインターネット接続ができませんでした。この問題を解決するために、アキヒロでは、特権を持たないユーザーネームスペースにTAPデバイスを接続することで、コンテナにインターネット接続を提供するために、ユーザーモードネットワーク(SLiRP)を利用しています。次の図はそのアーキテクチャを示しています。

image.png

詳細については、slirp4netns プロジェクトをチェックしてください。

ルートレスコンテナ用の環境を設定する方法

以下の手順で、ルートレスコンテナ用の環境を設定することができます。検証の練習はCentOS 7.6のVM上で行うことに注意してください。

次に、ユーザーを作成したいと思います。以下のコマンドを実行することで行うことができます。

$ useradd moby
$ passwd moby

そして、新しいユーザーをsudoersグループに追加します。

usermod -aG wheel moby

次に、非特権ユーザに切り替えます。

$ su - moby
$ id
uid=1000(moby) gid=1000(moby) groups=1000(moby),10(wheel)

uid/gidマッピングを設定します。

$ echo "moby:100000:65536" | sudo tee /etc/subuid
$ echo "moby:100000:65536" | sudo tee /etc/subgid

ルートレスDockerのインストール

$ curl -sSL https://get.docker.com/rootless | sh

次に、初めてインストールする場合は、必要なパッケージをインストールする必要があります。

$ curl -sSL https://get.docker.com/rootless | sh
# Missing system requirements. Please run following commands to
# install the requirements and run this installer again.
# Alternatively iptables checks can be disabled with SKIP_IPTABLES=1

cat <<EOF | sudo sh -x
curl -o /etc/yum.repos.d/vbatts-shadow-utils-newxidmap-epel-7.repo https://copr.fedorainfracloud.org/coprs/vbatts/shadow-utils-newxidmap/repo/epel-7/vbatts-shadow-utils-newxidmap-epel-7.repo
yum install -y shadow-utils46-newxidmap
cat <<EOT > /etc/sysctl.d/51-rootless.conf
user.max_user_namespaces = 28633
EOT
sysctl --system
EOF

次に、必要に応じて usermode ネットワークプロトコルスタック (slirp4netns) をインストールします。このためには、yum でインストールされた slirp4netns のバージョンが古すぎて実行できないので、ソースコードから slirp4netns をビルドする必要があります。

$ sudo yum install glib2-devel
$ sudo yum group install "Development Tools"
$ git clone https://github.com/rootless-containers/slirp4netns
$ cd slirp4netns
$ ./autogen.sh
$ ./configure --prefix=/usr
$ make
$ sudo make install

Rootless Dockerをインストールすると、以下のようなプロンプトが表示されます。

$ curl -sSL https://get.docker.com/rootless | sh
# systemd not detected, dockerd daemon needs to be started manually

/home/moby/bin/dockerd-rootless.sh --experimental --storage-driver vfs

# Docker binaries are installed in /home/moby/bin
# Make sure the following environment variables are set (or add them to ~/.bashrc):\n
export XDG_RUNTIME_DIR=/tmp/docker-1000
export DOCKER_HOST=unix:///tmp/docker-1000/docker.sock

ルートレスコンテナを検証する

ルートレスコンテナを確認するには、以下の手順に従います。

まず、以下のコマンドを実行します。

$ export XDG_RUNTIME_DIR=/tmp/docker-1000
$ export DOCKER_HOST=unix:///tmp/docker-1000/docker.sock
$ /home/moby/bin/dockerd-rootless.sh --experimental --storage-driver vfs

次に、別ウィンドウで以下を実行します。

$ export XDG_RUNTIME_DIR=/tmp/docker-1000
$ export DOCKER_HOST=unix:///tmp/docker-1000/docker.sock
$ docker version
Client:
 Version:           master-dockerproject-2019-04-29
 API version:       1.40
 Go version:        go1.12.4
 Git commit:        3273c2e2
 Built:             Mon Apr 29 23:39:39 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          master-dockerproject-2019-04-29
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.4
  Git commit:       9a2c263
  Built:            Mon Apr 29 23:46:23 2019
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc7+dev
  GitCommit:        029124da7af7360afa781a0234d1b083550f797c
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
$ docker run -d -p 8080:80 nginx
$ curl localhost:8080

iperf3を使ってネットワークパフォーマンステストを行い、サーバーを起動します。

$ docker run  -it --rm --name=iperf3-server -p 5201:5201 networkstatic/iperf3 -s

コンテナ全体のネットワーク帯域幅をテストします。

$ SERVER_IP=$(docker inspect --format "{{ .NetworkSettings.IPAddress }}" iperf3-server)
$ echo $SERVER_IP
172.17.0.2
$ docker run -it --rm networkstatic/iperf3 -c $SERVER_IP
...    
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.03  sec  29.8 GBytes  25.5 Gbits/sec    0             sender
[  4]   0.00-10.03  sec  29.8 GBytes  25.5 Gbits/sec                  receiver

コンテナとホスト間のネットワーク帯域幅(インターネット接続)をテストします。

$ HOST_IP=$(hostname --ip-address)
$ echo $HOST_IP
192.168.1.162
$ docker run -it --rm networkstatic/iperf3 -c $HOST_IP
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec  1011 MBytes   848 Mbits/sec    0             sender
[  4]   0.00-10.00  sec  1008 MBytes   845 Mbits/sec                  receiver

コンテナ間の通信帯域幅が比較的高いことがわかります。しかし、コンテナとホスト間の異なるネットワークネームスペースの通信帯域幅は大幅に減少しました。

結論

dockerによるルートレスコンテナの導入は、Docker/Runcコンテナのセキュリティと管理性を向上させるための大きな一歩です。この全く新しい機能により、Linuxでのセキュリティシステムの完全な再利用が可能となり、seccompやSELinuxのようなセキュリティ構成を組み合わせることで攻撃面を減らすことができます。また、コミュニティでは、root権限を必要としないKubernetesの実験版も提供しています。この実験版は https://github.com/rootless-containers/usernetes から入手できます。

しかし、付与されたルートレスコンテナは、Linuxカーネルのリスクを防ぐことはできません。また、ルートレスコンテナのネットワークやストレージの性能を最適化する必要があり、ルートレスコンテナは特定のシナリオでしか使用できません。この種のコンテナがより幅広いシナリオで利用できるように、コミュニティがコンテナのセキュリティと効率を改善し続けてくれることを期待しています。

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

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

Golang 基礎 (環境構築など) part1

前準備や基本情報

パッケージ管理

ターミナルで実行。go.modファイルが作成される。

go mod init github.com/${GITHUB_USER}/${PROJECT_NAME}

あとは go get するだけ。

実行環境(docker)

main.goがあるディレクトリに以下を置く。(go.sumは1回でもgo getしてる場合のみCOPYする)

Dockerfile
FROM golang:alpine

WORKDIR /go/src/app

COPY go.mod .
# COPY go.sum . 
RUN go mod download

COPY . .
docker-compose.yml
version: "3.7"

services:
  goapp:
    build: .
    tty: true
    volumes:
    - .:/go/src/app

以下のコマンドでコンテナの中に入る。(goappはサービス名)

~% docker-compose up -d
~% docker-compose exec goapp /bin/ash

コンテナ内でmain.goを実行。

/go/src/app # go run main.go

publicとprivate

  • 命名規則で判別。(変数名、関数名など)そのため、基本的にキャピタルケースorパスカルケースで命名する。
    • public: 他のパッケージからでも呼び出せる。先頭を大文字にする!
    • private: パッケージ内でのみ呼び出せる。先頭は小文字。
var PublicVariable string = "Public" // 呼び出せる
var privateVariable string = "private" // 呼び出せない
  • ファイル名はスネークケース ex. line_api.go

基礎文法

strconv パッケージ

string型と基本的なデータ型との間の変換をするパッケージ

i, err := strconv.Atoi("-42") // stringからintへ
s := strconv.Itoa(-42)  // intからstringへ

スライスのmakeとcap

cap: メモリに確保してる分

m := make([]int, 5)
n := make([]int, 0, 5)
fmt.Printf("len=%d cap=%d value=%v\n", len(m), cap(m), m) // len=5 cap=5 value=[0 0 0 0 0]
fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) // len=0 cap=5 value=[]
s1 := make([]int, 0) // 空のスライスをメモリに確保する(mapも同様)
var s2 []int // nil(メモリに確保しない。mapも同様)

map(辞書型)

m := map[string]int{"apple": 100, "banana": 200}
fmt.Println(m["nothing"]) // 0

v, ok := m["apple"] // 2つ目の返り値は受け取らなくてもおっけい
fmt.Println(v, ok) // 100 true

可変長引数

func foo(params ...int) {
    fmt.Printf("len=%d params=%v\n" , len(params), params)
    for _, param := range params {
        fmt.Println(param)
    }
}
func main() {
    foo() // len=0 params=[]
    foo(1, 2) // len=2 params=[1 2]

    s := []int{1, 2, 3}
    foo(s...) // len=3 params=[1 2 3]
}

forとrange

// 条件のみ
sum := 1
for sum < 500 {
    sum += sum
}
fmt.Println(sum)

// 無限ループ
for {
    fmt.Println("hello")
}

// range
l := []string{"python", "go", "java"}
for index, value := range l{
    fmt.Println(index, value)
}

m := map[string]int{"apple": 100, "banan": 200}
for key, value := range m{
    fmt.Println(key, value)
}
for key := range m{
    fmt.Println(key)
}
for _, value := range m{
    fmt.Println(value)
}

swicth

// 通常
os := "mac"
switch os {
case "windows":
    fmt.Println("windows!!")
case "mac":
    fmt.Println("mac!!")
default:
    fmt.Println("linux!!")
}
// 条件省略
t := time.Now()
switch {
case t.Hour() < 12:
    fmt.Println("morning")
case t.Hour() < 17:
    fmt.Println("afternoon")
default:
    fmt.Println("foooo")
}

panicとrecover

panicで強制終了してしまう処理の前にdeferでrecover()すると強制終了しなくなる!

func thirdPartyConnectDB() {
    panic("Unable to connect database.")
}

func save() {
    defer func() {
        s := recover()
        fmt.Println(s)
    }()
    thirdPartyConnectDB()
}

func main() {
    save()
    fmt.Println("ok?")
}

参考

現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
https://xblood.hatenablog.com/entry/2019/01/28/213223

part2

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

dockerの起動中に起きたエラー

railsアプリを立ち上げるためにdocker-compose buildを実行しようとすると次のエラーが出た。

$ docker-compose build
Building db
Step 1/4 : FROM mysql:8.0.17
 ---> b8fd9553f1f0
Step 2/4 : RUN apt-get update &&  apt-get install -y apt-utils
:
:
Fetching spring 2.0.2
Installing spring 2.0.2
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
  current directory: /usr/local/bundle/gems/nokogiri-1.10.9/ext/nokogiri
/usr/local/bin/ruby -r ./siteconf20200529-6-18ba5hy.rb extconf.rb
Cannot allocate memory - /usr/local/bin/ruby -r ./siteconf20200529-6-18ba5hy.rb
extconf.rb 2>&1
:
:
An error occurred while installing nokogiri (1.10.9), and Bundler cannot
continue.
Make sure that `gem install nokogiri -v '1.10.9' --source
'https://rubygems.org/'` succeeds before bundling.
:

nokogiri?
gemファイルに記述した覚えは無いが、、

エラー分にあるとおりnokogiriのインストールを試みたが、同様のエラーがでた。
$ gem install nokogiri -v '1.10.9'

調べると次の記事にあるように、容量不足によるエラーの可能性があるかもしれない。
https://qiita.com/HrsUed/items/c156ed69e927b6165717
記事通り容量を増加させたが、違うエラーが発生した。

$ docker-compose up -d
:
ERROR: Service 'web' failed to build: failed to register layer: Error processing tar file(exit status 1): write /usr/lib/x86_64-linux-gnu/libx265.so.165: no space left on device

エラーメッセージで調べると以下の記事が参考なった。
https://scrapbox.io/tsuchinaga/Docker%E3%81%A7%E5%AE%B9%E9%87%8F%E4%B8%8D%E8%B6%B3%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B
$ docker volume rm $(docker volume ls -qf dangling=true)

説明通りコマンドを実行するとbuildが成功した。

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