- 投稿日:2019-08-11T22:42:12+09:00
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
に以下を追記する。.bashrcexport 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 導入
以上。シンプル。はや~い
- 投稿日:2019-08-11T20:21:20+09:00
Optuna + MYSQL on Docker
目的: Optunaを分散環境で動かす
完成したコードはここにあります。
手順
- docker 及び docker-composeの準備
- 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.ymlversion: '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: optunaMYSQL_DATABASE: optuna を用意しておくのがポイント (optuna_pytorchからはmysqlはdbというドメインで参照可能になっている)
optunaのコード
main.pyfrom 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枝刈りが行われてるのがわかる
結果を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'結果の削除
mysql -h 127.0.0.1 --port 3306 -uroot -proot -D optuna -e 'drop database optuna'
- 投稿日:2019-08-11T19:44:12+09:00
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開発環境の構築
あらすじは次の通りです。
- Docker for MacでXilinx ISEインストール済みのdockerイメージを作成
- 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を作成しました。DockerfileFROM 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.pylogファイルの出力、中間ファイルの出力、ソースコード保管、test用のファイルの出力用のディレクトリとinvoke用のPythonスクリプトが置いてあります。
sample.vhd
がメインのVHDLファイルです。sample.vhdentity 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.yamlsrc_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の使いにくいエディタを使う必要もなくなったため、開発がよりスムーズに進むようになりました。
- 投稿日:2019-08-11T18:14:52+09:00
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-installVSCodeを入れる
Visual Stadio Codeのインストール
VirtualBoxの仮想デスクトップからインストールしていく。
ダウンロードページへ行き、.deb(真ん中のやつ)を選んでダウンロードする。
ダウンロードされたパッケージをダブルクリックして、インストール
メインメニューから「アクセサリ>Visual Studio Code」があることを確認。
日本語化
Extensionsで検索窓に「Japanese」を入力。
「Japanese Language Pack for Visual...」をインストール
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」をインストールSampleを試す
①のアイコンをクリックし、「Remote-Containers: Try a Sample...」を選択する
ここでは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でも仮想環境とか作れるのかもしれないけど。。)
- 投稿日:2019-08-11T18:06:25+09:00
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
DockerfileFROM 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_ROOTdocker-compose.yml
docker-compose.ymlversion: '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: alwaysGemfile
src/Gemfilesource 'https://rubygems.org' gem 'rails', '5.2.2'Gemfile.lockは、ファイルの中身は空でOK
src/Gemfile.lock手順
スケルトンアプリ作成
$ docker-compose run app rails new . --force --database=mysql --skip-bundledatabase.ymlを修正
src/config/database.ymldefault: &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 -dMySQLにRailsのDBを作成
$ docker-compose run app rails db:create
これで、http://localhostにブラウザでアクセスすると、Railsのインストール完了画面がでてきました。
- 投稿日:2019-08-11T18:00:00+09:00
Docker for Macを使ったローカルのKubernetesクラスタ上でSparkジョブを実行する
Docker for Macをインストールする
以下を参照ください。
https://docs.docker.com/docker-for-mac/install/Kubernetesクラスタを有効にする
Preferences -> Kubernetes -> Enable Kubernetesをクリックします。
SparkのDockerイメージを作成する
以下の記事を参照ください。
https://qiita.com/yohei1126@github/items/efcc906b8609d78274ffSparkジョブを実行する
サンプルとして提供されている
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.jarSparkジョブの結果を確認する
- 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 ...
- 投稿日:2019-08-11T17:44:57+09:00
[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 . /myappdocker-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=postgresqldocker-compose buildconfig/database.ymlの編集
default: &default adapter: postgresql encoding: unicode host: db username: postgres password: pool: 5データベースの作成
docker-compose run web rake db:createDockerの起動
docker-compose up下記のページが表示されれば成功
- 投稿日:2019-08-11T17:44:57+09:00
[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 . /myappdocker-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=postgresqldocker-compose buildconfig/database.ymlの編集
default: &default adapter: postgresql encoding: unicode host: db username: postgres password: pool: 5データベースの作成
docker-compose run web rake db:createDockerの起動
docker-compose up下記のページが表示されれば成功
- 投稿日:2019-08-11T17:22:20+09:00
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
- 投稿日:2019-08-11T13:32:30+09:00
Docker+flaskで「URL Opener」的なものを作った
はじめに
知らない人向けに説明すると、「URL Opener」とは下記のようなサイトです
使い方は
- textareaに開きたいURLを1行づつ入力する
- 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側
- searchの下のtextareaに検索したい複数キーワードを1行ずつ入力
- 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の変数に、検索サイトを辞書型で保存しているだけ)
以上です。
- 投稿日:2019-08-11T01:09:28+09:00
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