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

Windows10 HomeでLinuxに寄せた開発環境を整える

対象者

  • 世の中はMac or LinuxだけどWindows10 Homeで開発したい
  • Dockerが必要だけどWindowsで何とかしたい
  • Clojureが必要だけどWindowsで何とかしたい
  • spacemacsを使いたいけどWindowsで何とかしたい

Windows上のgitで改行コードが自動変換される罠を外す

参考 => @uggds - 気をつけて!Git for Windowsにおける改行コード

初期設定のままだとpullしてきた時に改行コードが自動変換されるため、*.shを動かした時'\r': command not foundのように怒られることがある。

罠を外したら思う存分pullしよう。

Docker Toolboxを入れてポートフォワーディングまでやる

Windowsで使えるDockerは大きく2種類

  • Docker for WindowsとDocker Toolboxがある。
  • Docker for Windowsは仮想化技術としてhyper-vを使うので、Windows10 ProやEducationなどでしか使えない(Homeにはhyper-vが無い)。
  • つまりWindows10 HomeにはDocker Toolboxしか残されてはいない。こちらは仮想化技術としてVirtualBoxを使う。

Docker Toolboxを入れる

docker-composeが使えるようにインストールする。

Docker Toolboxインストールとポートフォワーディングの参考:
- D-jiro.Y - WindowsでDocker Toolbox&docker-composeを動かす
- ラボラジアン - Windows 10 Home のための、Docker Toolbox をインストールして WSL から使う方法

手順通りにインストールすれば動く。
※VirtualBoxが既に入っている場合は、アンインストールしてDocker Toolboxでインストールすることを推奨。バージョンの壁なのかパスの壁なのか、動かないので…

ポートフォワーディングで繋げる

参考リンクは上記と同じ。
例えばdockerのコンテナで0.0.0.0:8080->80/tcpのようなポート設定をしている場合、VirtualBoxのポートフォワーディングでは以下のように設定する。

名前 プロトコル ホストIP ホストポート ゲストIP ゲストポート
okimochi TCP 127.0.0.1 8080 8080

WSL (Windows Subsystem for Linux)を入れてUbuntuのTerminalからdockerを動かせるようにする

まずWSLインストール

参考 => Windows Subsystem for Linuxをインストールしてみよう!

WSLでDockerを使えるようにする

ラボラジアン - Windows 10 Home のための、Docker Toolbox をインストールして WSL から使う方法」を参考にして、WSL上の~\.bashrcに以下を追記する。

.bashrc
export DOCKER_HOST=tcp://192.168.99.100:2376
export DOCKER_CERT_PATH=/mnt/c/Users/okimochi/.docker/machine/certs # ユーザ名がokimochiの場合
export DOCKER_TLS_VERIFY=1
export COMPOSE_TLS_VERSION=TLSv1_2

最後のCOMPOSE_TLS_VERSION=TLSv1_2は、SSL error: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol versionを回避するために指定する。参考 => https://github.com/docker/compose/issues/6473

同じ目に遭っている人がいた。
- @kodetto - DockerでのTLSV1エラー
- @atsu_kg - docker-compose up -d 実行したらSSL errorで起動しなかったのでTLS_VERSIONを指定した

Leiningenを入れてPowerShellからClojureを動かせるようにする

Leiningenをインストール

参考 => yohshiy - Clojure, Leiningen の Windows へのインストールと使い方

本稿でも補足をする。

  • まずJDKをProgram Files以外のディレクトリにインストールする
    • oracleがログイン必須みたいな状態なので、JDKはadoptopenjdkなどがおすすめ
    • スペースが含まれるディレクトリにインストールすると、Emacsからのrepl呼び出しが失敗するらしい
  • lein.bat推奨の予感
    • v2okimochiは参考リンクのleiningen-win-installerを使えなかった(JDKが認識されずインスコ止まる)
    • 予めWindowsの環境変数としてJAVA_HOME=C:\<jdkへのパス>\binを追加しておく
    • WindowsはWin32内のJavaなどを見に行く習性があるらしいので、環境変数の順番はWin32より上に置く
  • jenvは使えない…のでJDKへの環境変数pathを変えて疑似jenvっぽく頑張る

spacemacsを入れてcider-jack-inからlein replを使えるようにする

spacemacsインストール

公式にインストール方法がある => https://github.com/syl20bnr/spacemacs

Windows版は勝手が違うので補足する => v2okimochi - spacemacs.md: Windowsでのインストール

補足内容は以下のような感じ。
- 公式のインスコ方法だと日本語インライン変換(入力中の文字を表示してくれる機能)が詰むよね
- 環境変数を通す必要があるよね
- 初回起動は--insecureオプションが必要だよね

あとはspacemacsのいい感じの設定方法については「@lagenorhynque - Clojure/ClojureScript関連リンク集: Clojure開発全般」に全部載ってる。Clojure関連も全部載ってる。

cider-jack-inでreplを起動する

ayato-p - SpacemacsでClojureを書くために僕が行った設定」を参考にして、.spacemacs(コマンド操作Space f e dで開ける)にCider関連の設定を加える。

あとはClojureファイル(*.clj)を開いた状態でSpace , 'すればnrepl serverが動き出し、少し待てばcider replが起動する。

nvm経由でnpmを入れて複数のnodeを切り替えられるようにする

参考 => @rapando - nvm-windows 導入

以上。シンプル。はや~い

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

Optuna + MYSQL on Docker

目的: Optunaを分散環境で動かす

完成したコードはここにあります。

手順

  1. docker 及び docker-composeの準備
  2. optunaのsimple exampleを書く

注意:mysqlのパスワードを直書きしたりしてるのでセキュリティ的によくないです

Dockerで環境構築

FROM pytorch/pytorch:1.1.0-cuda10.0-cudnn7.5-runtime
ARG PYTHON_VERSION=3.6

RUN apt-get update
RUN apt-get install -y wget
RUN apt-get -y install language-pack-ja-base language-pack-ja ibus-mozc

RUN update-locale LANG=ja_JP.UTF-8 LANGUAGE=ja_JP:ja
ENV LANG ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
ENV LC_CTYPE ja_JP.UTF-8

RUN pip install -U pip
RUN pip install numpy matplotlib bokeh holoviews pandas tqdm sklearn joblib nose pandas tabulate xgboost lightgbm optuna nose coverage
RUN pip install torch torchvision
# install tensorboardX to /tmp for hparams in tensorboardX
RUN pip install -e git+https://github.com/eisenjulian/tensorboardX.git@add-hparam-support#egg=tensorboardX --src /tmp
RUN pip install tensorflow==1.14.0
RUN pip install future moviepy

# mysqlclient
RUN apt-get install -y libssl-dev
RUN apt-get update
RUN apt-get install -y python3-dev libmysqlclient-dev
RUN pip install mysqlclient

可視化のためにtensorboardもいれた

docker-compose.yml
version: '2.3'

services:
  optuna_pytorch:
    build: ./
    container_name: "optuna_pytorch"
    working_dir: "/workspace"
    ports:
    - "6006:6006"
    - "8888:8888"
    #runtime: nvidia
    volumes:
    - .:/workspace
    tty: true

  db:
    image: mysql:5.7
    container_name: 'db'
    ports:
        - "3306:3306"
    volumes:
        # 初期データを投入するSQLが格納されているdir
        - ./db/mysql_init:/docker-entrypoint-initdb.d
        # 永続化するときにマウントするdir
        - ./db/mysql_data:/var/lib/mysql
    environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_USER: root
        MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
        MYSQL_DATABASE: optuna

MYSQL_DATABASE: optuna を用意しておくのがポイント (optuna_pytorchからはmysqlはdbというドメインで参照可能になっている)

optunaのコード

main.py
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision import transforms
from torch.utils.data.dataset import Subset
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import optuna
from tensorboardX import SummaryWriter
#optuna.logging.disable_default_handler()

from tqdm import tqdm_notebook as tqdm

BATCHSIZE = 128

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5,), (0.5,))])

train_set = MNIST(root='./data', train=True,
                  download=True, transform=transform)
subset1_indices = list(range(0,6000))
train_set = Subset(train_set, subset1_indices)

train_loader = DataLoader(train_set, batch_size=BATCHSIZE,
                          shuffle=True, num_workers=2)
subset2_indices = list(range(0,1000))
test_set = MNIST(root='./data', train=False,
                 download=True, transform=transform)
test_set = Subset(test_set, subset2_indices)
test_loader = DataLoader(test_set, batch_size=BATCHSIZE,
                         shuffle=False, num_workers=2)

classes = tuple(np.linspace(0, 9, 10, dtype=np.uint8))
h_params = {}
print('finish data load')
EPOCH = 10
writer = SummaryWriter()

class Net(nn.Module):
    def __init__(self, trial):
        super(Net, self).__init__()
        self.activation = get_activation(trial)
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv1_drop = nn.Dropout2d(p=trial.suggest_uniform("dropout_prob", 0, 0.8))
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = self.activation(F.max_pool2d(self.conv1(x), 2))
        x = self.activation(F.max_pool2d(self.conv1_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = self.activation(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)


def train(model, device, train_loader, optimizer):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()


def test(model, device, test_loader):
    model.eval()
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            pred = output.max(1, keepdim=True)[1]
            correct += pred.eq(target.view_as(pred)).sum().item()

    return 1 - correct / len(test_loader.dataset)

def get_optimizer(trial, model):
    optimizer_names = ['Adam', 'MomentumSGD']
    optimizer_name = trial.suggest_categorical('optimizer', optimizer_names)
    h_params['opt_name'] = optimizer_name
    weight_decay = trial.suggest_loguniform('weight_decay', 1e-10, 1e-3)
    if optimizer_name == optimizer_names[0]:
        adam_lr = trial.suggest_loguniform('adam_lr', 1e-5, 1e-1)
        h_params['adam_lr'] = adam_lr
        optimizer = optim.Adam(model.parameters(), lr=adam_lr, weight_decay=weight_decay)
    else:
        momentum_sgd_lr = trial.suggest_loguniform('momentum_sgd_lr', 1e-5, 1e-1)
        h_params['momentum_sgd_lr'] = momentum_sgd_lr
        optimizer = optim.SGD(model.parameters(), lr=momentum_sgd_lr,
                              momentum=0.9, weight_decay=weight_decay)
    return optimizer


def get_activation(trial):
    activation_names = ['ReLU', 'ELU']
    activation_name = trial.suggest_categorical('activation', activation_names)
    h_params['activation'] = activation_name
    if activation_name == activation_names[0]:
        activation = F.relu
    else:
        activation = F.elu
    return activation


def objective_wrapper(pbar):
    def objective(trial):
        global writer
        writer = SummaryWriter()
        device = "cuda" if torch.cuda.is_available() else "cpu"

        model = Net(trial).to(device)
        optimizer = get_optimizer(trial, model)
        writer.add_hparams_start(h_params)
        for step in range(EPOCH):
            train(model, device, train_loader, optimizer)
            error_rate = test(model, device, test_loader)
            writer.add_scalar('test/loss', error_rate, step)
            trial.report(error_rate, step)
            if trial.should_prune(step):
                pbar.update()
                raise optuna.structs.TrialPruned()

        pbar.update()
        writer.add_hparams_end()  # save hyper parameter
        return error_rate
    return objective



TRIAL_SIZE = 50
with tqdm(total=TRIAL_SIZE) as pbar:
    study = optuna.create_study(pruner=optuna.pruners.MedianPruner(), study_name='distributed-mysql', storage='mysql://root:root@db/optuna', load_if_exists=True)
    study.optimize(objective_wrapper(pbar), n_trials=TRIAL_SIZE, n_jobs=2)

print(study.best_params)
print(study.best_value)

df = study.trials_dataframe()
print(df.head)
df.to_csv('result.csv')

本質は

  • optuna.create_study を作り
  • trial.suggest_loguniform, trial.suggest_categorical で探索の候補を決め
  • study.optimize で探索を実行する

あたりである。
とくにcreate_studyはDBの指定とpruningのルールも指定するところなので重要
documentをみるとよい

枝刈りのルールも確認しておくと良いここ

使い方

run

# create env
docker-compose up -d
docker exec -it optuna_pytorch /bin/bash
# run
python main.py

# remove env
exit
docker-compose down

最適化の過程はmysqlに記録されるのでmysqlが参照できる場所でmain.pyを動かせば分散環境での最適化になる!

結果をtensorboardで確認

# on host
docker exec -it optuna_pytorch /bin/bassh
tensorboard --logdir runs

# access to http://localhost:6006/#hparams on browser

image.png

枝刈りが行われてるのがわかる

image.png

image.png

結果をmysqlから確認

# on host
# install mysql
brew install mysql

# check tables on Optuna db
mysql -h 127.0.0.1 --port 3306 -uroot -proot -D optuna -e 'show tables'

# check results on Optuna db
mysql -h 127.0.0.1 --port 3306 -uroot -proot -D optuna -e 'select * from trials'

image.png

結果の削除

mysql -h 127.0.0.1 --port 3306 -uroot -proot -D optuna -e 'drop database optuna'
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker for MacでXilinx FPGA用の開発環境を作る

TL;DR

  • Xilinx ISEがインストールされたdockerイメージを作成しました。
  • Mac上から自動でビルドする環境を整備し、テンプレートとして公開しました。

はじめに

FPGAを販売するXilinx社では、ISE(最近のデバイス用にはVivado)と呼ばれる自社製の開発環境を用意しています。FPGAのコンフィグレーションに必要なBit stream file(*.bit)はこのISEを使って生成できますが、逆に言えばXilinx社謹製のISEを使わなければ生成できません。そして、ISEは対応OSがWindowsとLinuxのみなんですよね...見事にMacがハブれれてしまいました。メインで使っている端末がMacということもあり、MacからFPGAの開発ができると嬉しいな...と思いしばらくいじっていたので、備忘録を兼ねて記事にします。

以前の開発環境

一年ほど前にFPGAボードの開発をしていた際には、次のような環境で開発していました。

  • ターゲットデバイス
  • 開発&シミュレーション
    • Mac端末
    • 言語: VHDL
    • エディタ: Visual Studio Code
    • テスト用コンパイラ: ghdl
  • 実装
    • Windows端末
    • エディタ&コンパイラ: Xilinx ISE

状況としてはMacの方でVHDLコードを書き、ghdlでコンパイルして挙動を確認します。だいたいいい感じまでできたらソースコードをDropboxなりGithubなりにアップロードして、Windows端末にダウンロードし、Xilinx ISEで作成したプロジェクトにソースコードを加えて、実装用のBit stream fileを生成していました。
なぜこのような面倒な手順を踏んでいたかというと、Windows端末が研究室の端末で、自宅に持ち帰りが難しかったこと、加えてXilinx ISE上でのソースコードの編集がお世辞にもやりやすいとは言えなかった(補完やSyntax Highlightが貧弱だった)ため、ソースの編集はVS Code上でやりたかったという事情があります。Mac上でVMを使うことも考えたのですが、Mac上のストレージの容量が少なく、VMを立てたくもない状況でした。
そんなこんなで、このしち面倒臭い環境でしばらく開発をしており、そのときの目的が達成された後には、もう金輪際FPGAに関わることもないだろうと思っていたわけです。ただ、幸か不幸かまたFPGAに触る機会ができたので、この際Macで実装までできるようにしてやろうと思いまして、環境構築に取り組みました。

Mac上でのFPGA開発環境の構築

あらすじは次の通りです。

  1. Docker for MacでXilinx ISEインストール済みのdockerイメージを作成
  2. Pythonのinvokeパッケージを使ってコンパイル、テスト環境の構築

以下の手順では次のソフトウェアがインストールされていることを前提にしています。

  • Docker for Mac
  • Python 3.x
  • XQuartz
  • invoke (Python package)
  • ghdl

docker、XQuartz、Python3、ghdlはHomebrewから、invokeはAnaconda経由で入手しました。invokeはpipでも入手できるようです。

1. Docker for MacでXilinx ISEインストール済みのdockerイメージを作成

~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~
以下の手順でISE Webpack editionをインストールしたものはDocker Hub上でseekworser/ise_webpackで公開しているため、Webpack版であれば

docker pull seekworser/ise_webpack

で事足ります。容量が30 GB以上あるので注意してください。
~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~

dockerを使ってXilinx Vivadoをインストールしている方がいらっしゃったので、その記事を参考にしました。
Xilinx の開発ツールを Docker コンテナに閉じ込める

この方はVivado HLx 2018.2: All OS installer Single-File Downloadをダウンロードしてきて、インストールまで含めてDockerfileで自動化しているのですが、ISEではSingle file Downloadが存在しないため、泣く泣くインストールは手動で行います。
そこで、まずfull installer for Linuxをダウンロードしてきて、次のようなDockerfileを作成しました。

Dockerfile
FROM ubuntu

RUN \
  sed -i -e "s%http://[^ ]\+%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g" /etc/apt/sources.list && \
  apt update && \
  apt upgrade -y && \
  apt -y --no-install-recommends install \
  ca-certificates curl sudo xorg dbus dbus-x11 ubuntu-gnome-default-settings gtk2-engines \
  ttf-ubuntu-font-family fonts-ubuntu-font-family-console fonts-droid-fallback lxappearance && \
  apt-get autoclean && \
  apt-get autoremove && \
  rm -rf /var/lib/apt/lists/* && \
  echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

COPY Xilinx_ISE_DS_Lin_14.7_1015_1.tar /

RUN mkdir /ise-installer &&\
  tar --strip-components 1 -C /ise-installer \
  -xvf Xilinx_ISE_DS_Lin_14.7_1015_1.tar &&\
  rm /Xilinx_ISE_DS_Lin_14.7_1015_1.tar

前半は先のリンクの方から丸パクリで、X11環境のインストールその他です。後半でインストール用のフォルダを/ise_installer下に展開しておきます。(ファイル名はバージョンに合わせて変えてください)

ここからGUIインストーラを立ち上げ、ISEをインストールします。Docker for MacでX11 GUIを立ち上げる際には次を参考にしました。
Mac+dockerでx11アプリケーションを起動する

先ほどのDockerfile、ダウンロードしたインストーラを全て同じフォルダに入れ、さらにhost側でXQuartzを立ち上げた状態で以下のコマンドを実行します。

docker build --no-cache --rm -t ise-installer .
xhost + 127.0.0.1
docker run -e DISPLAY=docker.for.mac.localhost:0 --name ise-installed ise-installer /ise-installer/xsetup

その後XQuartzでインストーラが起動するため、指示にしたがってインストールを行います。インストール後に、

(host)$ docker commit ise-installed ise-installed
(host)$ docker run -i --name ise ise-installed /bin/bash
(container)$ rm -rf /ise-installer
(container)$ exit
(host)$ docker commit ise ise
(host)$ docker container rm ise-installer ise-installed ise
(host)$ docker image rm ise-installer ise-installed

を順に実行し、ISEのインストールされたイメージiseを作成します。

2. Pythonのinvokeパッケージを使ってコンパイル、テスト環境の構築

先ほど作成したimageと、Pythonのinvokeパッケージを使用して、コンフィギュレーション用のBit stream fileを作成する環境を作成します。seekworser/ise_project_templateでPapilio pro用に作成したものは公開しています。
ディレクトリ構成は次のようになっています。

ise_project_template
.
├── Readme.md
├── log/
├── out/
├── test/
├── src/
│   ├── project.yaml
│   ├── sample.vhd
│   ├── sample_ucf.ucf
│   └── test_sample.vhd
├── sample.bit
└── tasks.py

logファイルの出力、中間ファイルの出力、ソースコード保管、test用のファイルの出力用のディレクトリとinvoke用のPythonスクリプトが置いてあります。

sample.vhdがメインのVHDLファイルです。

sample.vhd
entity sample is
    -- write ports
end sample;
architecture behavior of sample is
    -- write behavior
end behavior;

また、sample_ucf.ucfはFPGAの制約ファイルです。
プロジェクトが変わるごとにMakefileもといtasks.pyをいじるのは嫌だったので、project.yamlにコンパイル用のパラメータを格納しておくようにします。ついでに使うFPGAの情報もpart:以下に書いておきます。

project.yaml
src_files:
  - file_name: sample.vhd
    language: vhdl
    library: work
    entity_names:
      - sample 

test_files:
  - file_name: test_sample.vhd
    entity_names:
      - test_sample
      - test_sample2

ucf_file: sample_ucf.ucf

top_module: sample

part:
  device: xc6slx9
  package: tqg144
  speed: -2

tasks.pyではこの情報を読み取って、ビルドやテストなどを行うようコードを書いておきます。例えば次のようなイメージです。

tasks.py(一部)
import yaml
import invoke

def get_project_parameter(*keys):
    param = yaml.load(open(PROJECT_YAML_FILE_NAME, "r+"))
    for item in keys:
        param = param[item]
    return param

@invoke.task
def bitgen(c):
    c.run(
        "docker run --rm -i -v $(PWD):/project seekworser/ise_webpack:latest sh <<_EOT_\n"
        "cd /project\n"
        "{ise_base:s}bitgen -w {outdir:s}{top_module:s}.ncd {top_module:s}.bit {outdir:s}{top_module:s}.pcf\n"
        "mv *.drc {logdir:s}{top_module:s}_drc.log\n"
        "mv *.bgn {logdir:s}{top_module:s}_bitgen.log\n"
        "rm -rf *.xwbt _xmsgs xilinx_device_details.xml *.xrpt\n"
        "_EOT_".format(
            ise_base=ISE_BASE,
            top_module=get_project_parameter(TOP_MODULE_KEY),
            outdir=OUTDIR,
            logdir=LOGDIR,
        )
    )
    return

# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
# some other tasks
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 

ISE_BASE = "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/"
OUTDIR = "./out/"
SRCDIR = "./src/"
LOGDIR = "./log/"
PROJECT_YAML_FILE_NAME = SRCDIR + "project.yaml"
TOP_MODULE_KEY = "top_module"

最終的にどうなったか

以上の結果として

invoke builde

のコマンド一発でMacからBit stream fileが生成できるようになりました。ISEの使いにくいエディタを使う必要もなくなったため、開発がよりスムーズに進むようになりました。

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

Vagrant上のLubuntuでVSCode+Docker環境を作りたい~VSCode+Docker~

前回までの記事

対象としている人

VisualStadio CodeのRemote-Containerを使いたいけど、Windows10 Homeな人。

経緯

Remote-Containerを使おうと思ったらDockerToolboxは対応していなかったし、
かといって、ProにしてもVirtualBoxが使えなくなるらしいので、じゃあ、もう開発用の環境作ろうかなと。

前提

  • VirtualBoxが入っている
  • Vagrantが入っている
  • OSがWindows10である

Dockerを入れる

公式のインストール手順があるのでそれを参考に。

前回のVagrantを立ち上げ

Powershellで立ち上げ
# 適当なディレクトリ作成しておく
# Vagrantfile作成
> vagrant init lubuntu-19.04-x86_64

# 立ち上げ
> vagrant up

#  SSHで入っておく
> vagrant ssh
...
vagrant@vagrant-pc:~$

公式の通りに

# 注意:めっちゃ文字化けするけど、テキストにコピペするとちゃんと出るので、
# ビビらず行こう。気になるようなら、表示を英語にするとか。

# アップデートしておく
$ 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 -
OK

# Ubuntuのコードネームを確認する
# Linux Mintだと公式?のものが出ないらしい
# その時は元になったUbuntuのものに変更する必要がある
$ lsb_release -cs
disco
# https://download.docker.com/linux/ubuntu/dists/
# ここにある名前ならOK。discoはちゃんとある。

# stable版を入れる
$ sudo add-apt-repository \
>    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
>    $(lsb_release -cs) \
>    stable"

# Dockerリポジトリを更新
$ sudo apt-get update

# インストール
$ sudo  apt-get install docker-ce docker-ce-cli containerd.io

# 起動確認
$  sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:6540fc08ee6e6b7b63468dc3317e3303aae178cb8a45ed3123180328bcc1d20f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

# そういえば勝手にService動いてるので、確認
$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2019-08-10 22:22:10 JST; 2min 2s ago
     Docs: https://docs.docker.com
 Main PID: 3622 (dockerd)
    Tasks: 10
   Memory: 50.9M
   CGroup: /system.slice/docker.service
           └─3622 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

# enabledになってるので、OS立ち上げ時に自動起動までしてくれる
# ついでにDockerのバージョンも見ておく。
$ sudo docker -v
Docker version 19.03.1, build 74b1e89

怖いからスナップショットを撮る

スナップショットを撮るよ
$ exit

# とりあえず、docker-installで。この先まずったらこれに戻す。
> vagrant snapshot save docker-install

VSCodeを入れる

Visual Stadio Codeのインストール

VirtualBoxの仮想デスクトップからインストールしていく。

ダウンロードページへ行き、.deb(真ん中のやつ)を選んでダウンロードする。
VirtualBox_docker_default_1565437459661_58898_11_08_2019_14_24_14.png

ダウンロードされたパッケージをダブルクリックして、インストール
VirtualBox_docker_default_1565437459661_58898_11_08_2019_14_25_10.png

メインメニューから「アクセサリ>Visual Studio Code」があることを確認。

image.png

日本語化

Extensionsで検索窓に「Japanese」を入力。
「Japanese Language Pack for Visual...」をインストール
image.png

Remote-Containers

dockerグループにvagrant追加

vagrantユーザがDockerコマンドを使えるようにするために以下のコマンドでDockerグループに追加する

dockerグループにvagrant追加
$ sudo usermod -aG docker vagrant

追加後、一旦ログアウトしてから入りなおす(重要)

dockerコマンドがsudoなしで打てることを確認
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Remote-Containersを入れる

Extensionsで検索窓に「remote container」を入力。
「Remote-Containers」をインストール

image.png

Sampleを試す

①のアイコンをクリックし、「Remote-Containers: Try a Sample...」を選択する
image.png

ここではGoを選択。
(勝手にgithubからコードが落ちてくると思ったらページに飛ばされてしまった。。)
仕方ないのでCloneしてくる

sampleを落とす
$ mkdir <なんか適当なディレクトリ>
$ cd $_
$ git clone https://github.com/microsoft/vscode-remote-try-go.git

落としてきた「vscode-remote-try-go」をVSCodeで開き、先ほどの①のアイコンをクリックし「Remote-Containers: Open Folder in Conatainer」を選択。
この時も「vscode-remote-try-go」を選択。

コンテナ落としてきたり、結構時間かかる

終わったら、F5キーでデバックモード起動。
http://localhost:9000でブラウザからアクセスすると、「Hello,」と表示されてるはず。

おしまい。

go環境がなくても動くし、必要なものがあればDockerfileに書けば反映される。
pythonのvirtualenv感覚で環境の作成が出来るのが良い。
(Goでも仮想環境とか作れるのかもしれないけど。。)

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

Dockerでrailsローカル開発環境構築

概要

  • Dockerを使用したRailsの開発環境を構築
  • DBはMySQLを使用
  • ローカル開発環境で構築(MySQLのユーザー名、パスワードは簡易なものを使用)

前提

  • Mac、Windows10のローカル開発環境で動作
  • 「Docker for Windows」か「Docker for Mac」がインストール済みであること

ディレクトリ構造

├─src
│  ├─Gemfile
│  └─Gemfile.lock
├─Dockerfile
└─docker-compose.yml

準備するファイル

ディレクトリ構造にある4つのファイルの内容は下記になります。

Dockerfile

Dockerfile
FROM ruby:2.5.3
ENV LANG C.UTF-8

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

RUN mkdir /app
RUN mkdir /app/src

ENV APP_ROOT /app/src
WORKDIR $APP_ROOT

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

RUN bundle install

ADD . $APP_ROOT

docker-compose.yml

docker-compose.yml
version: '2'
services:
  mysql:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    ports:
      - "3306:3306"
    volumes:
      - ./db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: 'root-pass'
    restart: always
    logging:
      options:
        max-size: 5m
        max-file: "10"
  app:
    build: .
    image: rails
    container_name: 'app'
    command: bundle exec rails s -p 80 -b '0.0.0.0'
    ports:
      - "80:80"
    environment:
      VIRTUAL_PORT: 80
    volumes:
      - ./src:/app/src
    depends_on:
      - mysql
    restart: always

Gemfile

src/Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.2'

Gemfile.lockは、ファイルの中身は空でOK

src/Gemfile.lock

手順

スケルトンアプリ作成

$ docker-compose run app rails new . --force --database=mysql --skip-bundle

database.ymlを修正

src/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: root-pass
  host: mysql

イメージ再ビルド

※処理完了までちょっと時間がかかることがあります。。。

$ docker-compose build

コンテナ立ち上げ

$ docker-cocmpose up -d

MySQLにRailsのDBを作成

$ docker-compose run app rails db:create

これで、http://localhostにブラウザでアクセスすると、Railsのインストール完了画面がでてきました。

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

Docker for Macを使ったローカルのKubernetesクラスタ上でSparkジョブを実行する

Docker for Macをインストールする

以下を参照ください。
https://docs.docker.com/docker-for-mac/install/

Kubernetesクラスタを有効にする

Preferences -> Kubernetes -> Enable Kubernetesをクリックします。
Screen Shot 2019-08-11 at 4.52.56 PM.png

SparkのDockerイメージを作成する

以下の記事を参照ください。
https://qiita.com/yohei1126@github/items/efcc906b8609d78274ff

Sparkジョブを実行する

サンプルとして提供されている spark-examples_2.11-2.4.3.jar を実行します。これはπを計算するプログラムです。
まずクラスタのURLを確認します。

 $ kubectl cluster-info
Kubernetes master is running at https://localhost:6443
KubeDNS is running at https://localhost:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

ジョブの実行にはSpark-submitコマンドが必要なため、リポジトリから取得して以下のコマンドを実行します。

$ wget https://www-us.apache.org/dist/spark/spark-2.4.3/spark-2.4.3-bin-hadoop2.7.tgz
$ tar zxvf spark-2.4.3-bin-hadoop2.7.tgz
$ cd spark-2.4.3-bin-hadoop2.7
$ bin/spark-submit \
  --master k8s://https://localhost:6443 \
  --deploy-mode cluster \
  --conf spark.executor.instances=3 \
  --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
  --conf spark.kubernetes.container.image=yohei1126/spark:v2.4.3 \
  --class org.apache.spark.examples.SparkPi \
  --name spark-pi \
  local:///opt/spark/examples/jars/spark-examples_2.11-2.4.3.jar

Sparkジョブの結果を確認する

  • Sparkジョブはpodのなかで実行されるため、podの一覧を取得します。
  • kubectl logs でpodの中のログを確認すると、πが計算されています。
$ kubectl get pods
NAME                                               READY     STATUS      RESTARTS   AGE
spark-pi-2e689dc329e934f38c1017d59635da59-driver   0/1       Completed   0          46m
$ kubectl logs spark-pi-2e689dc329e934f38c1017d59635da59-driver
...
Pi is roughly 3.1442157210786053
...
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Docker知識不要]ruby on railsの環境をDocker上に作る方法

ruby on railsの環境をDocker上に作る方法

こんにちは、ITエンジニアの田中です!
2019年8月11日時点動作することを確認しています!

この記事を読むと下記の事ができるようになります。

  • Docker上でRuby on Railsの環境を作れる。

下記のことが事前に完了していることが前提です。

  • Dockerがインストールされている

フォルダ構成

  • 任意フォルダ
    • src
      • Gemfile
      • Gemfile.lock
    • Dockerfile
    • docker-compose.yml

Gemfile

source 'https://rubygems.org'
gem 'rails', '5.0.0.1'

Gemfile.lock

空ファイル

Dockerfile

FROM ruby:2.6.1
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD src/Gemfile /myapp/Gemfile
ADD src/Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp

docker-complose.yml

version: '2'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./src:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

コマンド

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

config/database.ymlの編集

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

データベースの作成

docker-compose run web rake db:create

Dockerの起動

docker-compose up

下記のページが表示されれば成功

RubyOnRails.png

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

[Docker知識不要] Ruby on railsの環境をDocker上に作る方法

ruby on railsの環境をDocker上に作る方法

こんにちは、ITエンジニアの田中です!
2019年8月11日時点動作することを確認しています!

この記事を読むと下記の事ができるようになります。

  • Docker上でRuby on Railsの環境を作れる。

下記のことが事前に完了していることが前提です。

  • Dockerがインストールされている

フォルダ構成

  • 任意フォルダ
    • src
      • Gemfile
      • Gemfile.lock
    • Dockerfile
    • docker-compose.yml

Gemfile

source 'https://rubygems.org'
gem 'rails', '5.0.0.1'

Gemfile.lock

空ファイル

Dockerfile

FROM ruby:2.6.1
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD src/Gemfile /myapp/Gemfile
ADD src/Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp

docker-complose.yml

version: '2'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: /bin/sh -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"      
     volumes:
      - ./src:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

コマンド

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

config/database.ymlの編集

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

データベースの作成

docker-compose run web rake db:create

Dockerの起動

docker-compose up

下記のページが表示されれば成功

RubyOnRails.png

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

Spark 2.4.3 の Docker イメージを作成する

以下のコマンドでビルド済みSparkのコードを取得します。

$ wget https://www-us.apache.org/dist/spark/spark-2.4.3/spark-2.4.3-bin-hadoop2.7.tgz
$ tar zxvf spark-2.4.3-bin-hadoop2.7.tgz

以下のコマンドでDockerイメージをビルドし、DockerHubにpushします。

$ ./bin/docker-image-tool.sh -r yohei1126 -t v.2.4.3 build
$ ./bin/docker-image-tool.sh -r yohei1126 -t v.2.4.3 push

これでDockerイメージが3個あります。

$ docker images | grep spark
yohei1126/spark-r                                                           v2.4.3              3fe1391b05dc        23 minutes ago      741MB
yohei1126/spark-py                                                          v2.4.3              181ffe00ea8f        24 minutes ago      447MB
yohei1126/spark                                                             v2.4.3              4758132028fd        24 minutes ago      356MB
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker+flaskで「URL Opener」的なものを作った

はじめに

知らない人向けに説明すると、「URL Opener」とは下記のようなサイトです

http://www.url-opener.com/

使い方は

  1. textareaに開きたいURLを1行づつ入力する
  2. Open allをクリックすると、入力された複数のURLが別タブで開かれる

この時、ポップアップブロックを使用していると全て開かれないことがあるので、許可してから使用してください

Keywooとは

textareaに「URL」でなく「検索キーワード」を入力します
検索サイトはjson(後述)にあらかじめ記載するか、フォームより追加します

src: https://github.com/ymmmtym/keywoo

Keywooの特徴

  • urlでなく検索キーワードを入力するので、毎回URLを準備する必要がなくなる
  • タブを開きっぱなしにする必要がなくなる
  • flaskで実装したので、軽量に動作する(無料で使えるGCPでも快適に動作します)

flaskとは

  • pythonのwebフレームワークであり、軽量であることが主な特徴
  • 中小規模のサイトで利用され、Djangoに次ぐ2位の利用率

動作環境

$ docker --version
Docker version 18.09.2, build 6247962
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

ディレクトリ構成

.
├── Dockerfile
├── README.md
├── app
│   ├── data
│   │   └── sites.json
│   ├── run.py
│   ├── static
│   │   ├── favicon.ico
│   │   ├── layout.js
│   │   ├── main.js
│   │   └── stylesheet.css
│   └── templates
│       ├── index.html
│       ├── layout.html
│       └── result.html
├── docker-compose.yml
└── requirements.in

各ディレクトリ説明

各ファイル説明

flaskの動作に必要なライブラリをインストール
requirements.in
flake8
scipy
matplotlib
scikit-learn
requests
beautifulsoup4
Flask

Dockerfile

FROM python:3.6
MAINTAINER ymmmtym
USER root
WORKDIR /root
ENV HOSTNAME="keywoo-container" \
    PS1="[\u@\h \W]# "
ADD ["requirements.in", "/root/requirements.in"]
RUN apt-get -y update && \
    pip install --upgrade pip && \
    pip install --upgrade setuptools && \
    pip install pip-tools && \
    pip-compile /root/requirements.in && \
    pip-sync
ADD ["app", "/root/app"]
WORKDIR /root/app
EXPOSE 5000
CMD ["python", "/root/app/run.py"]

主にpipのインストールやreqiremets.inに記載されたpythonのライブラリの追加などを行なっています
(現在は、dockerhubにbuildしたimageをアップしたので、Dockerfile自体は使用しない)

docker-compose.yml

docker buildした後でもdocker restartで設定が反映されるように、
appディレクトリ配下は永続的にマウントされるようvolumesに記載しています。
デフォルトでportは80を使用しています

version: '3'
services:
  keywoo:
    image: yumemo/keywoo
    container_name: keywoo-container
    hostname: keywoo-container
    tty: true
    volumes:
      - ./app:/root/app
    ports:
      - "5000:5000"

app/run.py

python/app/run.py
#!/usr/bin/python

from flask import Flask, render_template, request, jsonify
import json

app = Flask(__name__)
def get_toppage(str):
    list = str.split('/')
    return list[0] + '//' + list[2]
app.jinja_env.globals['get_toppage'] = get_toppage
app.config['JSON_AS_ASCII'] = False

with open("./data/sites.json", "r", encoding="utf-8") as sites_json:
    search_dic = json.load(sites_json)

@app.route('/', methods=["GET","POST"])
def index():
    if request.method == "POST":
        if request.form["radio"]:
            global search_dic
            if request.form["radio"] == "delete":
                del_sites = request.form.getlist("check")
                for site in del_sites:
                    del search_dic[site]
            if request.form["radio"] == "default":
                with open("./data/sites.json", "r", encoding="utf-8") as sites_json:
                    search_dic = json.load(sites_json)
            if request.form["radio"] == "reset":
                search_dic.clear()
            if request.form["radio"] == "add":
                if request.form["site_name"] and request.form["url"]:
                    search_dic.update({str(request.form["site_name"]):str(request.form["url"])})
    return render_template("index.html", search_dic = search_dic)

@app.route('/result', methods=["GET", "POST"])
def result():
    if request.form["search"]:
        search_text = str(request.form["search"])
        search_list = search_text.splitlines()
        return render_template("result.html", search_list = search_list, search_dic = search_dic)
    else:
        return render_template("index.html", search_dic = search_dic)

if __name__ == '__main__':
  app.run(host='0.0.0.0',port=5000,threaded=True)

flaskを起動するためのpythonファイルです

app/data/json

data配下にはjsonファイルを格納しています。
検索サイトのデータを保持する目的で利用しています。
大量のデータを扱うわけではないので、DBではなくjsonファイルに記載することにしました

json/sites.json
{
    "Google": "https://www.google.com/search?q=",
    "Weblio English": "https://ejje.weblio.jp/content/",
    "Amazon": "https://www.amazon.co.jp/s?k=",
    "Rakuten": "https://search.rakuten.co.jp/search/mall/",
    "Yahoo Auctions": "https://auctions.yahoo.co.jp/search/search?p=",
    "Yahoo Auctions(record)": "https://auctions.yahoo.co.jp/search/search?auccat=22260&p=",
    "Spotify": "https://open.spotify.com/search/results/",
    "Discogs": "https://www.discogs.com/ja/search/?q="
}

app/static

css,jsや画像などの静的ファイルを格納しています。
(デザインを良くするために作成しました。無くても問題なく動作はします)

app/templates

htmlを格納しています。

操作方法

server側

pwd
# /root/keywoo
docker-compose up -d

その後、下記にアクセスすると使用できます
http://localhost:5000/

web側

keywoo_top.png

  1. searchの下のtextareaに検索したい複数キーワードを1行ずつ入力
  2. submitをクリックするとsearch sitesにあるそれぞれ検索結果へのリンクを表示するページを返す

search sitesの設定

対象の項目にチェックをつけてapplyをクリックすると下記のような処理が行われます

  • delete selected sites
    search sitesのテーブル内でチェックの付いているサイトを検索対象から削除する

  • load default sites from json
    jsonファイルから検索サイトを読み込む

  • reset all sites
    全ての検索サイトを検索対象から削除する

  • add site
    Name:検索サイトの名称(任意)
    URL:検索サイト(クエリ文字列までを記載する)

今後は

今後は以下のような機能をつけてみたいと思います

  • レイアウトの改修(レスポンシブデザインとか)
  • jsonをweb上で編集
  • login機能をつけてuser毎の検索サイトを保持(現在はpythonの変数に、検索サイトを辞書型で保存しているだけ)

以上です。

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

dockerコンテナ内でpermission errorが発生

dockerコンテナ内でpermission errorが発生

動作環境(VM)

  • CentOS Linux release 7.6.1810 (Core)
  • Docker version 1.13.1, build 7f2769b/1.13.1
  • docker-compose version 1.18.0, build 8dd22a9

コンテナ内の環境

  • Python 3.6.9 (FROM python:3.6)
  • Flask 1.1.1
  • Werkzeug 0.15.5

事象

docker-compose upを実行したところ、/root配下のファイルを操作した中でPermission deniedとなってしまいました

$ docker-compose up
Creating network "default" with the default driver
Creating container ... done
Attaching to container
container | python: can't open file '/root/app/run.py': [Errno 13] Permission denied
container exited with code 2

解析

dockerの再起動と、centosの再起動をしてみるが、どちらも解決せず、、
とりあえずググってみて、関連した記事を参考に解析してみる

1.SELinuxの無効化

https://qiita.com/koutwiring/items/10c3a67c1b58cf7d02c7

下記のファイルを編集して、SELinuxをオフにする

/usr/lib/systemd/system/docker.service
~ snip ~
# 下記の1行を追記
OPTIONS=--selinux-disabled
~ snip ~

その後dockerを再起動して、docker-compose upを実行しましたが解決せず、、

$ sudo systemctl restart docker

上記では解決できませんでした。

2.DockerでTCPポート80の使用をやめる

https://qiita.com/KEINOS/items/fba92ca0fb7662da0a00

flaskでコード(app.runの部分)を下記のように編集してポート5000を使用する

python/run.py
~ snip ~

if __name__ == '__main__':
  app.run(host='0.0.0.0',port=5000,threaded=True)

これも解決せず、、

3. rootユーザでコマンドを実行する

Dockerfileの内容に下記を追記して、rootユーザでコマンド実行するようにしました

~ snip ~
USER root ←これを追記
CMD ["python", "/root/app/run.py"]

これも解決せず、、

4. dockerの最新版をインストール

dockerのversionを最新版にしてみました。

$ docker-compose up
Creating network "default" with the default driver
Creating container ... done
Attaching to container
container |  * Serving Flask app "run" (lazy loading)
container |  * Environment: production
container |    WARNING: This is a development server. Do not use it in a production deployment.
container |    Use a production WSGI server instead.
container |  * Debug mode: off
container |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

解決しました!!

原因

dockerのversionが古かったのでエラーを吐いていたようです
下記にバージョンアップすることで解決しました

$ docker --version
Docker version 19.03.1, build 74b1e89

  1. Dockerコンテナ内でのpermission denied
  2. Python3 + Web 80 番ポートで PermissionError: [Errno 13] Permission denied on Docker
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む