- 投稿日:2020-10-13T22:55:48+09:00
Rustの開発環境を整えるまでにやったことメモ
環境
version 備考 windows10 Pro 1903 (OSビルド) 18362.1082 Docker Desktop 2.4.0.0(48506) wsl2で動作 vscode 1.49.3 コンテナで開発・ビルドできるようにする。
しばらく離れていた&環境が変わったので自分用備忘録
wsl2+Docker Desktopに関してはこことこことここを参考にした。hyper-vからの乗り換えの場合、
wsl2を使えるようにしてからhyper-vを無効化したらエラーが出たので、
- (Docker Desktopアンインストール)
- hyper-v 無効化
- wsl2有効化
- (Docker Desktop再インストール)
とすると確実かもしれない。
本編
1. コンテナイメージの取得・確認
PowerShellにて
PS:> docker pull rust:latest (結果略) PS:> docker images REPOSITORY TAG IMAGE ID CREATED SIZE rust latest c69fb046b993 3 days ago 1.28GB2. composeファイルの作成
vscodeで開発用コンテナを立ち上げるために、docker-composeファイルを作成します。
vscodeの機能で作成することもできますが、追加で少しやりたいことがあるため自作します。docker-compose.local.ymlversion: '3.7' services: rust-dev: image: rust:latest container_name: rust_dev working_dir: /app volumes: - ./:/app - rust_dev_target:/app/target tty: true environment: USER: xxxxx # cargo で必要になる CARGO_BUILD_TARGET_DIR: /app/target volumes: rust_dev_target: external: true基本的な部分の解説はdocker-composeのリファレンスとか、その他の解説記事に任せるとして、
やりたかったことに関わる2点だけ
- environmentの
CARGO_BUILD_TARGET_DIR
この環境変数で指定したディレクトリに、targetが吐き出される- volumes
node_modulesを隔離するための方法から着想を得たやり方。
CARGO_BUILD_TARGET_DIR
でtargetフォルダをプロジェクトの外に出し、1
そこにrust_dev_targetという外部ボリュームをマウントしなおしている。
これによってコンテナを削除してもtargetの中身を維持することができる。
小技とか
composeファイル内で変数を使う
composeファイルと同じ階層に.envファイルを置いておくと、環境変数として自動で読み込んでくれる。2
これを使って一部置き換えておくことで、例えばマウント先のフォルダ変えたいなーってなったときに少しだけ便利。
composeファイル内での環境変数の参照は${~~}で出来る.envmnt=/appdocker-compose.local.ymlversion: '3.7' services: rust-dev: image: rust:latest container_name: rust_dev working_dir: ${mnt} volumes: - ./:${mnt} - rust_dev_target:${mnt}/target tty: true environment: USER: xxxxx CARGO_BUILD_TARGET_DIR: ${mnt}/target volumes: rust_dev_target: external: true3. vscodeでコンテナを立ち上げる
- 適当なフォルダを作って上記のcomposeファイルを置き、codeで開く
- vscodeに拡張機能Remote - Containersを追加する。
- 左下に追加される緑のボタンを押し、
Remote-Containers: Add Development Container Configuration Files...
を選択する
From 'docker-compose.local.yml'
を選択する。
すると、.devcontainerというフォルダにdevcontainer.json、docker-compose.yml が作成されるのでそれぞれ編集するdocker-compose.ymlversion: '3.7' services: rust-dev: # volumes: # この行コメントアウトした # Update this to wherever you want VS Code to mount the folder of your project # - .:/workspace:cached # この行もコメントアウト # Overrides default command so things don't shut down after the process ends. command: /bin/sh -c "while sleep 1000; do :; done"こちらはvolumesをコメントアウトするだけ。
見やすさのために省略しているが、コメントに説明が書いてあるので、読んで適宜変更。devcontainer.json{ "name": "rust?", "dockerComposeFile": [ "..\\docker-compose.local.yml", "docker-compose.yml" ], "service": "rust-dev", "workspaceFolder": "/app", "settings": { "terminal.integrated.shell.linux": null, "editor.formatOnSave": true }, "extensions": [ "rust-lang.rust", "vadimcn.vscode-lldb" ] }
分かる範囲で詳細
- name
これだけコメントがない。vscodeでの表示上の名前、だけだと思う。- dockerComposeFile
composeファイルを読み込む順に書く。composeファイルをさらに分割している場合はここに書けばよい。
基本的には変更する必要はない。- service
composeファイルのservicesに定義した名前。複数定義している場合はメインとなるものを。
基本的には変更する必要はない- workspaceFolder
composeファイルで定義した、working_dirと同じ値を設定する。
コメントアウトすると/
を開くのでdocker-compose.local.ymlで定義した値が上書きされるっぽい
じゃあworking_dir要らなかったじゃん。ソダネー- settings
vscodeのsetting.jsonに書いている内容をそのまま書ける。
コンテナ内部にだけ適用されるので、下記extensionsで追加する拡張機能に対する設定はここに書いておけば間違いない。- extensions
コンテナに導入したい拡張機能のIDを書く。IDは拡張機能の名前の横に表示されている。
例)図の灰色ががっている部分がID
とりあえずRust拡張機能とCodeLLDB。他にいいものがあれば知りたい。- forwardPorts
コンテナのポート開放する際にはアンコメントする。composeファイルにportsで書いても同じ。volume作成
PS:> docker volume create rust_dev_target PS:> docker volume ls DRIVER VOLUME NAME local rust_dev_targetcomposeファイルで
external:true
しているので先に作っておかないとエラーになる左下の緑のボタンを押し、
Remote-Containers: Reopen in Container
を選択する。準備編終わり。4. プロジェクトの作成
開発はThe Rust Programming Languageを参考にすれば問題ないと思う。
著者とコミュニティに感謝。
Cargoでプロジェクトを作成すればHello worldが出来る。TERMINALroot@02080d70998d:/app# cargo --version cargo 1.47.0 (f3c7e066a 2020-08-28) root@02080d70998d:/app# cargo new hello --bin Created binary (application) `hello` package root@02080d70998d:/app# cd hello root@02080d70998d:/app/hello# cargo run (略) Hello, world!5. オートフォーマット
右下のベルマークのところに
Some Rust components not installed. Install?
と出るのでYesでインストール。
終わると保存したときに整形されるようになる。
コンテナを削除(orリビルド)した場合はもう一度やる必要がある。6. マルチステージビルド
リリースビルドと同時にコンテナ化したいので専用のDockerfileとcomposeファイルを作る。
ついでにパッケージインストールはキャッシュさせて高速化したいのでそのあたりも対応。 3DockerfileFROM rust:latest AS builder WORKDIR /app ENV USER=root # RUN rustup target add x86_64-unknown-linux-musl RUN cargo new my_prj WORKDIR /app/my_prj COPY ./hello/Cargo.toml ./hello/Cargo.lock ./ RUN cargo build --release COPY ./hello/src ./src RUN cargo build --release FROM debian:stretch-slim AS prod ENV TZ=Asia/Tokyo COPY --from=builder /app/my_prj/target/release/ /usr/local/bin WORKDIR /app CMD ["hello"]空プロジェクトを一度ビルドしてからsrcを入れ替えて再ビルドしている。
alpine向けにビルドしようとしてうまくいかなかったので調査中。
続いてcomposedocker-compose.build.ymlversion: '3.7' services: builder: build: context: . dockerfile: DockerFile target: builder image: rust-test:builder rust_test: build: context: . dockerfile: DockerFile target: prod image: rust-test:latestbuilderサービスをtarget: builder4として定義してあげることで、マルチステージビルドにおけるビルドステージにあたるコンテナにタグをつけておくことができる。
こうすることでdanglingイメージ(<none>:<none>
のこと)にならないので、ビルド途中の状態がキャッシュ出来る。7. 実行用compose作成
rust-test:latestに必要な環境変数とか与えて実行できるようにする。
目新しいことがないので割愛おわりに
開発用のDBも同時に立ち上がるようにしたり、他にもやったことがあるけど今回はここまで
- 投稿日:2020-10-13T22:32:36+09:00
コンテナ同士の通信について
概要
docker-compose.ymlで定義したコンテナは同じネットワーク下に置かれる。コンテナは互いにその名前でアクセスできる。
/var/www/container1# ping container2 64 bytes from ...省略docker-compose.yml
こんなときコンテナ1から2にアクセスしたい。
docker-compose.ymlversion: "3" services: container1: build: context: ./docker/container1 ports: - "3000:3000" container2: build: context: ./docker/container2 ports: - "8080:80"なぜか
ネットワーク内のDNSサーバーが立っていて名前解決をしている。
通常コンテナからホストマシンのローカルipにはアクセスできないが、DNSサーバーがコンテナごとに割り当てられたポートで名前解決してくれる✨
(digコマンドで動いているDNSサーバーがわかる)おまけ
直接コンテナ内のhostsにipとドメインを書いて名前解決する方法。
ホストマシンのipアドレスはwifiの設定でip4・ip6で動的に変わったりするので意図せず開発環境が動かなくなる可能性あり。docker-compose.yml# ports: # - "8080:80" extra_hosts: - "localhost-dev:${ホストマシンのipアドレス}"
- 投稿日:2020-10-13T21:16:34+09:00
docker を用いてlaravel6+nuxt.js+mysql+nginx構築
laravel6+nuxt.js+mysqlの構築
laravel,mysql,nginxの構築は@simotarooさんの記事が優秀なのでこちらを参考にしてください
https://qiita.com/shimotaroo/items/29f7878b01ee4b99b951本題に関係ないんですけどngixってエンジンエックスって読むんですね,,,(笑
nuxt.jsの構築
@simotarooさんの記事で作成したdocker-compose.ymlに PORT:3000, HOST: 0.0.0.0を追加
理由としてコンテナで設定されているポート番号とnode.jsのポート番号が違うままだと繋がらないためですdocker-compose.yml#docker-compose.ymlのバージョン version: '3.8' #docker volumeの設定 volumes: docker-volume: #services以下に各コンテナの設定を書く services: #Webサーバーのコンテナ web: image: nginx:1.18 ports: - '8000:80' depends_on: - app volumes: - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf - .:/var/www/html #アプリケーションのコンテナ app: build: ./docker/php volumes: - .:/var/www/html environment: PORT: 3000 #追加 HOST: 0.0.0.0 #追加 ports: - 3000:3000 #データベースのコンテナ db: image: mysql:5.7 ports: - '3306:3306' environment: MYSQL_DATABASE: ###### MYSQL_USER: ##### MYSQL_PASSWORD: ####### MYSQL_ROOT_PASSWORD: ########## TZ: 'Asia/Tokyo' volumes: - docker-volume:/var/lib/mysqldockerfileに RUN npm install -g create-nuxt-app を追加
dockerfileFROM php:7.2-fpm #composerのインストール COPY --from=composer:1.10 /usr/bin/composer /usr/bin/composer #npmのインストール COPY --from=node:10.22 /usr/local/bin /usr/local/bin COPY --from=node:10.22 /usr/local/lib /usr/local/lib #パッケージ管理ツールapt-getの更新と必要パッケージのインストール RUN apt-get update \ && apt-get install -y \ git \ zip \ unzip \ && docker-php-ext-install pdo_mysql bcmath RUN npm install -g create-nuxt-app #追加 #コンテナ内に入った時のディレクトリを指定 WORKDIR /var/www/html追加後はdocker-compose buildし変更を反映
反映できたらdocker内で
tarminalroot@########:/var/www/html npx create-nuxt-app ディレクトリ名で実行
tarminal? Successfully created project ディレクトリ名 To get started: cd ディレクトリ名 npm run dev To build & start for production: cd ディレクトリ名 npm run build npm run start成功したらこんな画面になります。
作成したディレクトリ内に入り,npm run devを実行後動作確認で以下のURLに入ってnode.jsの画面が出れば成功です
http://localhost:3000/
お疲れ様でした?
- 投稿日:2020-10-13T20:47:17+09:00
開発環境でのメール確認用にMailHogを利用する(Docker利用)
開発環境でメールの確認方法が面倒だったり、配信先に気を使う場合がありますが、MailHogというツールを使うとローカル内に閉じたメールの確認ができる環境を簡単に立ち上げることができます。
MailHogはGo言語でできているらしいです。
以前はMailCatcherという別の類似ツールを利用していましたが、MailHogの方が構築が容易だったので乗り換えました。
docker-composeで以下の構成で立ち上げます。
ファイル構成
. ├── docker-compose.yml └── php ├── docker │ ├── Dockerfile │ └── php.ini └── mail_test.php
docker-compose.yml
8025番ポートでwebインターフェースを利用するのでポートを設定します
version: '3' services: php: build: context: ./ dockerfile: php/docker/Dockerfile volumes: - ./php/:/var/www/html/ mailhog: image: mailhog/mailhog ports: - "8025:8025" #webインターフェース用ポートDockerfile
phpからのメール送信に
mhsendmail
が必要なので、Dockerfileでインストールします。FROM php:5.6-apache WORKDIR /var/www/html RUN curl -sSL https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 -o mhsendmail \ && chmod +x mhsendmail \ && mv mhsendmail /usr/local/bin/mhsendmail COPY ./php/docker/php.ini /usr/local/etc/php/php.ini
[mail function]
を書き換えておきます。[mail function] ; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). ; http://php.net/sendmail-path ; sendmail_path = /usr/sbin/sendmail -t -i ; 以下に書き換え sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"mail_test.php
<?php $to = "hoge@localhost.local"; $subject = "TEST"; $message = "メールテスト"; $headers = "From: from@example.com"; mb_send_mail($to, $subject, $message, $headers);docker-compose で up
$ docker-compose up -d Building php Step 1/4 : FROM php:5.6-apache ---> 24c791995c1e Step 2/4 : WORKDIR /var/www/html ---> Using cache ---> 1294d05c5c03 Step 3/4 : RUN curl -sSL https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 -o mhsendmail && chmod +x mhsendmail && mv mhsendmail /usr/local/bin/mhsendmail ---> Using cache ---> db0719944c4e Step 4/4 : COPY ./php/docker/php.ini /usr/local/etc/php/ ---> 264eb166413a Successfully built 264eb166413a Successfully tagged mailhog_php:latest WARNING: Image for service php was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Pulling mailhog (mailhog/mailhog:)... latest: Pulling from mailhog/mailhog df20fa9351a1: Already exists ed8968b2872e: Pull complete a92cc7c5fd73: Pull complete f17c8f1adafb: Pull complete 03954754c53a: Pull complete 60493946972a: Pull complete 368ee3bc1dbb: Pull complete Digest: sha256:8d76a3d4ffa32a3661311944007a415332c4bb855657f4f6c57996405c009bea Status: Downloaded newer image for mailhog/mailhog:latest Creating mailhog_php_1 ... done Creating mailhog_mailhog_1 ... donemailhogのWEBインターフェース
phpのコンテナ内からメール送信スクリプトを実行
$ docker exec -it mailhog_php_1 /bin/bash root@9c4b6a5df613:/var/www/html# php mail_test.php
- 投稿日:2020-10-13T20:22:40+09:00
Dockerでのエラー解消に繋がったコマンド
はじめに
Docker環境構築において、役に立ったコマンドを備忘録として残します。
作成したものの、エラーが解決出来なかったときにおすすめです。コンテナの停止、削除
コンテナの停止
コンテナ確認$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 797b4265f3d2 try_web "/bin/sh -c 'rm -f t…" 24 minutes ago Up 23 minutes 0.0.0.0:3000->3000/tcp try_web_1CONTAINER IDを指定します。
コンテナ停止$ sudo docker stop 797b4265f3d2 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESコンテナの削除
あくまで停止しただけなので、削除も行います。
コンテナ確認$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 797b4265f3d2 try_web "/bin/sh -c 'rm -f t…" 24 minutes ago Up 23 minutes 0.0.0.0:3000->3000/tcp try_web_1CONTAINER IDを指定します。
コンテナ削除$ sudo docker rm 797b4265f3d2 $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESimageの削除
コンテナは削除しましたが、imageは残っています。
imageの確認$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE try_web latest c0ee642ca6bd About an hour ago 1.01GBIMAGE IDを指定します。
imageの削除$ sudo docker rmi c0ee642ca6bd $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZEdocker-compose exec app rails db:createのエラー
私の場合ですが、Access denied for user のエラーが出ていたため、
mysqlを確認しました。
#
の後にmysql -u root -pと記述し、mysqlにログインします。ターミナル$ docker-compose up -d $ docker-compose exec db bash root@e5504121a08b:/# mysql -u root -p終了する場合はexitと記述してください。
ここでパスワードが間違っていたため、
docker-compose exec app rails db:create
のエラーが出ていました。まとめ
あくまでも一例のため、まだまだ便利なコマンドはあると思います。
私と同じ状況になった方の助けになれば幸いです。またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork
- 投稿日:2020-10-13T13:11:27+09:00
dockerにDjango(python)環境を構築する方法
dockerにDjango(python)環境を構築する方法
docker上にDjangoを使ったプロジェクトとアプリを作成して、開発サーバーを使ってブラウザに表示する手順のまとめ。
手順
- PJディレクトリの作成
- requirements.txtファイルの作成
- dockerfileの作成
- docker-compose.ymlの作成
- 設定ファイルからコンテナを作成する
- settigs.pyの編集
- コンテナの起動
- appの作成
- views.pyの編集
- urls.pyの作成と編集
参考にしたサイト
・Docker公式 Django作成
・Django公式 初めてのApp作成PJディレクトリの作成
mkdir django cd djangorequirements.txtファイルの作成
インストールするパッケージを指定したファイルを作成する。
touch requirements.txtrequirements.txtDjango>=3.0,<4.0 psycopg2-binary>=2.8DjangoとPsycopgをインストールする。
Psycopgは、PostgreSQLを効率的に使うためのツール。
-binaryはOS専用言語版のためコンパイル不要。dockerfileの作成
python3のイメージを作成するためのdockerfileを作成する。
touch dockerfiledockerfileFROM python:3 ENV PYTHONUNBUFFERED=1 RUN mkdir /code WORKDIR /code COPY requirements.txt /code/ RUN pip install -r requirements.txt COPY . /code/・
From イメージ名
指定したイメージをdockerhubからpullする。(dockerhubにない場合はローカルを探す)・
ENV 変数名
環境変数の設定。PYTHONUNBUFFEREDという変数に1をいれる。
コンソールの標準出力(stdout)と標準エラー出力(stderr)がエラー発生時にすぐに出力されるようにする(バッファを無効にする。pythonの-uオプションと同じ)
・RUN コマンド
コンテナ内に /code というディレクトリを作成する・
WORKDIR ディレクトリ
指定したディレクトリ(/code)をルートディレクトリにする・
COPY ホスト コンテナ
ホストのrequirements.txtを、コンテナの/code/配下にコピーする・
pip install -r ファイルパス
指定ファイルに書かれたパッケージをインストールする。ファイルはrequirements.txtを使用することが一般的。
「-r」 = 「--requirement」
docker-compose.ymlの作成
イメージを作成するためのdocker-composeファイルを作成する。複数のコンテナを含んだイメージを作成するためのファイル。(dockerfileは1つのコンテナのみ)
touch docker-compose.ymldocker-compose.ymlversion: "3.8" services: db: image: postgres environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres web: build: . command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - "8100:8000" depends_on: - dbイメージの中に2つのコンテナを用意する。
・
version: "3.8"
docker-compose.ymlの記述方法のバージョンを指定。
バージョンにより書き方が異なるため指定が必要。・
services
作成するコンテナ。dbとwebの2つを作成する。・
images
使用するイメージを指定。docker hubからpostgresをpullしてコンテナを作成する。・
environment
環境変数を設定。DBをpostgresに設定。user名とPWは任意で。・
build ディレクトリパス
指定したディレクトリ内のdockerfileからコンテナを作成する。ファイル名の指定がない場合はdockerfileを選択。異なる名前をつけている場合はファイル名も指定する。
・
commnad
コンテナ内で実行するコマンド。localhost:8000のサーバーを起動。manage.pyのrunserverを実行。
manage.pyはコマンドラインユーティリティ。便利なコマンドをインポートしてくる。・
volumes: -ホスト:コンテナ
ホストのディレクトリをコンテナ内の指定したディレクトリと連動させる(マウントする)。ホストのプロジェクトフォルダとコンテナ内の/codeを同期している。
同期したくないファイルは.dockerignoreを作成しファイル/フォルダ名を記述する。
・ports: -"ホスト:コンテナ"
ホスト側のポートを、コンテナ側の指定したポートに繋ぐ。localhost:8100にアクセスすると、コンテナ内の8000ポートに繋がる。
・
depends_on
webコンテナをdbコンテナと接続する。以前はlinkが使われていたが、v2.0以上は特に記述しなくとも、docker-compose.yml内のコンテナがネットワークで繋がる。(depends_onも不要?)
設定ファイルからコンテナを作成する
docker-compose run web django-admin startproject mysite・
docker-compose run [サービス名] [コマンド]
指定したサービス名のコンテナを作成し、コマンドを実行する。実行したフォルダ内にあるdocker-comopse.ymlファイルを元にイメージ作成、コンテナ作成・起動までを一気に行う。
ここではwebサービスを起動。
・
django-admin startporject PJ名
PJを作成する。指定したPJ名(mysite)でディレクトリが作成される。
作成されるファイルmysite/ manage.py mysite/ __init__.py settings.py urls.py asgi.py wsgi.py
settigs.pyの編集
mysite/settings.pyにDBの設定を書き込む。
初期設定はsqlite3が指定されているので上書きする。mysite/settings.pyDATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'postgres', 'USER': 'postgres', 'PASSWORD': 'postgres', 'HOST': 'db', 'PORT': 5432, } }(参考)デフォルトの記述# Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
コンテナの起動
docker-compose up 省略 web_1 | Django version 3.1.2, using settings 'mysite.settings' web_1 | Starting development server at http://0.0.0.0:8100/ web_1 | Quit the server with CONTROL-C.作成したコンテナを起動する。
指定したサーバーが立ち上がる。状態を見るには別のbash windowを開いて
docker ps
を実行する。$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9615ecd4098f django_web "python manage.py ru…" 16 minutes ago Up About a minute 0.0.0.0:8100->8000/tcp django_web_1バックグラウンドで起動させたい場合は、
up -d
にする。localhost:8100にアクセスするとページが開ける(コンテナ内のloaclhost:8000にアクセスできる)
appの作成
コンテナの中に入ってアプリを作成する。
##起動中のコンテナでbashを立ち上げる $ docker exec -it django_web_1 bash root@faef5f41e1c7 ##django appの作成 root@faef5f41e1c7:/code# python manage.py startapp polls ##フォルダの確認 root@faef5f41e1c7:/code# ls Dockerfile docker-compose.yml manage.py mysite polls requirements.txtコンテナ内でpollsの作成に成功。
ホスト側にもディレクトリが作成作成される。(volumeを指定して、同期しているため)プロジェクトとappの違い
djangoのコマンドで、startprojectとstartappという似たコマンドを実行している。
django-admin startproject mysite
python manage.py startapp polls
projectは1つだけ存在するもので、appは複数存在することができる。
mysiteというプロジェクトの中にpollsというappを一つだけ作成した状態。
views.pyの編集
画面の表示を操作するため、先ほど作成したpollsフォルダ内のviews.pyを編集する。
コンテナ内にエディタはインストールしてないので、一旦コンテナから抜ける。
root@faef5f41e1c7:/code# exit
▼画面上に「Hello, This is Django Polls」と表示されるプログラムを記述。polls/views.pyfrom django.http import HttpResponse def index(request): return HttpResponse("Hello, This is Django Polls")
urls.pyの作成と編集
polls内のURLの設定と、プロジェクトとしてのurlの設定をする必要がある。
polls/urls.pyfrom django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ]mysite/urls.pyfrom django.contrib import admin from django.urls import include, path urlpatterns = [ path('polls/', include('polls.urls')), path('admin/', admin.site.urls), ]pollsのurls.pyをpathとして認識させ、polls/でアクセスできるようにする。
記述したら、
localhost:8100/polls
でページをロード。無事表示完了。
- 投稿日:2020-10-13T11:34:18+09:00
docker-compose run, up, build, createの違い。それぞれの役割を知る。
docker-composeコマンドにrun, up, build, createなど、似たようなのがたくさんある。それぞれの役割を理解することで混乱を防ぐ。
コマンド 対象 備考 run イメージ&コンテナ作成 1つのサービスを指定。upは全サービス(コンテナ)を一括起動 up イメージ&コンテナ作成&起動 全コンテナを一括起動。起動まで行う build イメージの作成 - create コンテナの作成 - up コンテナの起動 -
▼流れでコマンドを分類
イメージ作成 コンテナ作成 コンテナ起動 build create start run → up → →
▼コマンドで見るとこんな感じ
docker-compose run/up
=docker-compose build && docker-compose create && docker-compose start
・docker-compose run
・docker-compose up
・docker-compose build
・docker-compose create
・docker-compose start基本的に使うコマンドは
docker up
になるはず。runやupを実行する際に、イメージが既存の場合は再度作成しないため、dockerfileやdocker-compose.ymlに変更がある場合は、再ビルドでイメージを上書きする。
- 投稿日:2020-10-13T10:20:00+09:00
DockerでRailsアプリの開発環境構築【Docker, Rails, Puma, Nginx, MySQL】
こんにちは.
今回もRailsアプリの開発環境をDockerで構築する手順をまとめてみました.
前回はRails用とデータベース用の2つのコンテナを起動しましたが,今回は,WebサーバーとしてNginxのコンテナも起動してみました.事前準備
環境
Ruby: 2.5.8
Rails: 5.2.4.4
MySQL: 5.7.31
Nginx: 1.19.2
Docker: 19.03.12
Docker Compose: 1.26.2手順
1. ディレクトリ,ファイルの作成
全体の構成は以下の通りです.
それではこの構成図の通り,ディレクトリとファイルを作成していきます.全体の構成/test-app ├── Dockerfile ├── Dockerfile.nginx ├── docker-compose.yml ├── nginx.conf ├── Gemfile └── Gemfile.lockまずは, プロジェクトのルートディレクトリを作成します.
terminal$ mkdir test-appそして, ルートディレクトリの直下に
Dockerfile
Dockerfile.nginx
docker-compose.yml
nginx.conf
Gemfile
Gemfile.lock
これらを作成します.
terminal$ cd test-app $ touch Dockerfile Dockerfile.nginx docker-compose.yml nginx.conf Gemfile Gemfile.lock2. ファイルの編集
上記で作成したそれぞれのファイルの中身は以下のようになります.
(Gemfile.lockは空のままにします.)DockerfileFROM ruby:2.5 RUN apt-get update && apt-get install -y \ build-essential \ node.js WORKDIR /test-app COPY . /test-app RUN bundle installDockerfile.nginxFROM nginx RUN rm -f /etc/nginx/conf.d/* COPY nginx.conf /etc/nginx/conf.d/test-app.conf CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.confcontainers/nginx/nginx.conf# プロキシ先の指定 # Nginxが受け取ったリクエストをバックエンドのpumaに送信 upstream test-app { # ソケット通信したいのでpuma.sockを指定 server unix:///test-app/tmp/sockets/puma.sock; } server { listen 80; # ドメインもしくはIPを指定 server_name _; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # ドキュメントルートの指定 root /test-app/public; client_max_body_size 100m; error_page 404 /404.html; error_page 505 502 503 504 /500.html; try_files $uri/index.html $uri @test-app; keepalive_timeout 5; # リバースプロキシ関連の設定 location @test-app { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://test-app; } location /favicon { empty_gif; access_log off; log_not_found off; } }Gemfilesource 'https://rubygems.org' gem 'rails', '~>5.2'docker-compose.ymlversion: '3' services: app: build: context: . dockerfile: Dockerfile command: bundle exec puma -C config/puma.rb volumes: - .:/test-app tty: true stdin_open: true depends_on: - db db: image: mysql:5.7 environment: - 'MYSQL_ROOT_PASSWORD=password' volumes: - 'db-data:/var/lib/mysql' web: build: context: . dockerfile: Dockerfile.nginx volumes: - ./public:/test-app/public - ./tmp:/test-app/tmp ports: - 80:80 depends_on: - app volumes: db-data:3. Appのコンテナ内にRailsのセットアップを行う
terminal$ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle4. tmp/socketsフォルダ作成,作成されたファイルを編集
まず,tmpフォルダ内に
sockets
フォルダを作成します.そして,Railsのセットアップにより作成されたファイルのうち以下の3つを編集します.
-config/database.yml
-config/puma.rb
-config/environments/production.rb
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password #docker-compose.ymlのMYSQL_ROOT_PASSWORDの値を設定する host: db #docker-compose.ymlのservice名と合わせる development: <<: *default database: test-app_developmentconfig/puma.rbthreads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } threads threads_count, threads_count port ENV.fetch("PORT") { 3000 } environment ENV.fetch("RAILS_ENV") { "development" } pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } plugin :tmp_restart app_root = File.expand_path("../..", __FILE__) bind "unix://#{app_root}/tmp/sockets/puma.sock" stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", trueconfig/environments/production.rb# Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = true #デフォルトではfalseなので,trueにかえるこの
config/environments/production.rb
の変更はしなくても開発環境の構築については問題はないが,あとあと本番環境にデプロイした際にアセットプリコンパイルのエラーが出たので,ここで変更しています.5. コンテナの起動, DBの作成
terminal$ docker-compose up -d --build $ docker-compose exec app rails db:createこれで http://localhost にアクセスすると, Railsのホーム画面が表示されるはずです.
参考
- 投稿日:2020-10-13T03:01:27+09:00
マルチステージビルドなDockerfileのARGについて
TL;DR
マルチステージビルドな Dockerfile で ARG を使う場合は、ちゃんと各ステージごとに使う ARG を宣言しましょう!
また、複数のステージで使う ARG にデフォルト値があるのなら、グローバルな ARG を定義してそこにデフォルト値を記載しましょう!こんな感じで作ればオッケーです!
Dockerfile# 各ステージで共通して利用する ARG にデフォルト値があるのなら、最初の FROM より前に定義する。 ARG YOUR_ARG="Default value" FROM alpine:latest as first_stage # ARG は、利用する各ステージごとに宣言する必要がある。 ARG YOUR_ARG RUN echo "1st stage: ${YOUR_ARG}" FROM alpine:latest as second_stage # ARG は、利用する各ステージごとに宣言する必要がある。 ARG YOUR_ARG RUN echo "2nd stage: ${YOUR_ARG}"マルチステージビルドと ARG の関係性について
マルチステージビルドでは、 ARG や ENV のスコープはステージごとに制限されているらしいです。
皆さんご存知でしたか?わたくしはステージ内で ARG の値を参照できていないことに気づいて初めて知りました。こちらのコメントによれば、
Correct, Dockerfile instructions, including ENV vars and ARG are scoped per build-stage, and will not be preserved in the next stage; this is by design.
You can, however, set a global ARG (set before the first build-stage), and use that value in each build-stage;
(意訳)ENV や ARG を含む Dockerfile の命令はビルドステージごとのスコープになっており、次のステージに持ち越されません。これは設計上そのようになっています。しかしながら、グローバルな ARG(最初のビルドステージより前で定義する)を使えば、ビルドステージごとにその値を利用することができます。とのことです。マジか。
公式ドキュメントにもしっかり載ってましたわ。
ARG 命令の変数スコープは、それが定義されたビルドステージが終了するときまでです。 複数のビルドステージにおいて ARG を利用する場合は、個々に ARG 命令を指定する必要があります。
最初にドキュメント読んだときは、ビルドステージの意味も分からないまま「あーそーゆーことね完全に理解した」と思ったような気が。。。
ARG の動きを見てみる
では実際にマルチステージビルドでの ARG の動きを見ていきましょう。
本稿の動作確認環境
本稿の執筆にあたっては、下記のバージョンで動作を確認しています。
# docker --version Docker version 18.09.1, build 4c52b90Dockerfile
今回の検証で使う Dockerfile は次の通りです。
Dockerfile# ARG1 は、グローバルに宣言し、グローバルなデフォルト値を設定する。 ARG ARG1="arg1 global default value" # ARG2 は、グローバルに宣言するが、グローバルなデフォルト値は設定しない。 ARG ARG2 # ARG3 は、グローバルに宣言しない。 # ARG ARG3 FROM alpine:latest as first_stage # first_stage では、各 ARG を宣言し、スコープ内のデフォルト値を設定する。 ARG ARG1="arg1 first stage value" ARG ARG2="arg2 first stage value" ARG ARG3="arg3 first stage value" RUN echo -e "first_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" FROM alpine:latest as second_stage # second_stage では、各 ARG を宣言するが、スコープ内のデフォルト値は設定しない。 ARG ARG1 ARG ARG2 ARG ARG3 RUN echo -e "second_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" FROM alpine:latest as third_stage # third_stage では、すべての ARG を宣言しない。 # ARG ARG1 # ARG ARG2 # ARG ARG3 RUN echo -e "third_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"各 ARG は下記のように設定しています。
ARG 名 設定内容 ARG1 グローバルな ARG として設定。デフォルト値も指定。 ARG2 グローバルな ARG として設定。デフォルト値は指定しない。 ARG3 グローバルな ARG として設定しない。 また、各ステージは次のように設定しています。
Stage 名 設定内容 first_stage 各 ARG を宣言。ステージ内のデフォルト値を設定。 second_stage 各 ARG を宣言。ステージ内のデフォルト値は設定しない。 third_stage ARG を宣言しない。
--build-arg
指定なしでビルドDocker Image のビルド時に、
--build-arg
による値の指定を行わずにビルドしてみます。# docker build . --no-cache Sending build context to Docker daemon 14.85kB ...snip... Step 7/14 : RUN echo -e "1st stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in 2bbe78634ee8 first_stage: ARG1=arg1 first stage value ARG2=arg2 first stage value ARG3=arg3 first stage value ...snip... Step 12/14 : RUN echo -e "2nd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in 0c28af93ea9b second_stage: ARG1=arg1 global default value ARG2= ARG3= ...snip... Step 14/14 : RUN echo -e "3rd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in cbca9ed88691 third_stage: ARG1= ARG2= ARG3= ...snip...
- first_stage では、いずれもステージ内のデフォルト値となりました。 ARG1 を見ると、グローバルなデフォルト値よりもステージ内のデフォルト値が優先されていることがわかります。これは、よりスコープが狭い方の値を優先的に使う動きになっており、理にかなっている動きと言えるでしょう。
- second_stage では、 ARG1 のみグローバルなデフォルト値が表示されています。ステージ内で ARG を宣言はしたものの、何も値を指定しなければグローバルなデフォルト値を利用するということですね。 ARG2, ARG3 には何も表示されていませんが、これはその値を指定している場所がどこにもないからですね。
- third_stage ではすべての値が表示されていません。 ARG1 のグローバルなデフォルト値すら表示されていないということは、 ARG を利用するためにはそのステージごとに宣言する必要があるということでしょう。
--build-arg
指定ありでビルド今度は
--build-arg
による値の指定ありでビルドしてみます。# docker build --build-arg ARG1="build arg1 value" --build-arg ARG2="build arg2 value" --build-arg ARG3="build arg3 value" . --no-cache Sending build context to Docker daemon 14.85kB ...snip... Step 7/14 : RUN echo -e "1st stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in 10b37c5a524b first_stage: ARG1=build arg1 value ARG2=build arg2 value ARG3=build arg3 value ...snip... Step 12/14 : RUN echo -e "2nd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in e70e3ff9fe9b second_stage: ARG1=build arg1 value ARG2=build arg2 value ARG3=build arg3 value ...snip... Step 14/14 : RUN echo -e "3rd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in e675e8f648e8 third_stage: ARG1= ARG2= ARG3= ...snip...
- first_stage, second_stage ともにすべての値が
--build-arg
で指定した値になりました。これは公式ドキュメントの ARG のデフォルト値で説明されている内容と一致しますね。--build-arg
で指定された値はグローバルなデフォルト値及びステージ内のデフォルト値のどちらよりも優先されます。- third_stage ではまたもやすべての値が表示されていません。
--build-arg
で値が指定されていても、そのステージ内で宣言されていなければやはり利用できないようです。まとめ
- マルチステージビルドな Dockerfile で ARG を利用する際には、すべてのステージでそれぞれ利用する ARG を宣言する必要がある。
- 複数のステージで利用している ARG のデフォルト値を定義したければ、グローバルな ARG を定義(最初の FROM よりも前に定義)してそこにデフォルト値を記載すると良い。
- ARG の値の優先度は
--build-arg
での指定値 [優先度高]- ステージ内のデフォルト値
- グローバルなデフォルト値 [優先度低]
おしまい。
宣伝
マルチステージビルドの ARG の挙動に気づくきっかけとなったプロジェクトの宣伝です。
Minecraft の Bedrock Server を楽に運用しようぜ!という趣旨のプロジェクトです。
Minecraft ってたまーにアップデートが入るのですが、クライアントは大体勝手にアップデートされるものの、 Bedrock Server は自動的にアップデートされず、手動で新しいバージョンをダウンロードして Zip ファイルを展開してバイナリファイルを置き換えてサービスを再起動して・・・とかやる必要がありました。
このプロジェクトは、一度セットアップだけやってしまえば、あとは全自動で Bedrock Server をアップデートしてくれます!ついでに Docker を使って Bedrock Server を構築するので環境を汚しません!よろしくお願いします!
本当におしまい。
- 投稿日:2020-10-13T03:01:27+09:00
マルチステージビルドなDockerfileのARGでやらかしがちな件について
TL;DR
マルチステージビルドな Dockerfile で ARG を使う場合は、スコープがステージ内に閉じていることに注意が必要です!ちゃんと各ステージごとに使う ARG を宣言しましょう!
また、複数のステージで使う ARG にデフォルト値があるのなら、グローバルな ARG を定義してそこにデフォルト値を記載しましょう!こんな感じで作ればオッケーです!
Dockerfile# 各ステージで共通して利用する ARG にデフォルト値があるのなら、最初の FROM より前に定義する。 ARG YOUR_ARG="Default value" FROM alpine:latest as first_stage # ARG は、利用する各ステージごとに宣言する必要がある。 ARG YOUR_ARG RUN echo "1st stage: ${YOUR_ARG}" FROM alpine:latest as second_stage # ARG は、利用する各ステージごとに宣言する必要がある。 ARG YOUR_ARG RUN echo "2nd stage: ${YOUR_ARG}"マルチステージビルドと ARG の関係性について
マルチステージビルドでは、 ARG や ENV のスコープはステージごとに制限されているらしいです。
皆さんご存知でしたか?わたくしは作った Dockerfile のステージ内で ARG の値を参照できていないことに気づいて初めて知りました。こちらのコメントによれば、
Correct, Dockerfile instructions, including ENV vars and ARG are scoped per build-stage, and will not be preserved in the next stage; this is by design.
You can, however, set a global ARG (set before the first build-stage), and use that value in each build-stage;
(意訳)ENV や ARG を含む Dockerfile の命令はビルドステージごとのスコープになっており、次のステージに持ち越されません。これは設計上そのようになっています。しかしながら、グローバルな ARG(最初のビルドステージより前で定義する)を使えば、ビルドステージごとにその値を利用することができます。とのことです。マジか。
公式ドキュメントにもしっかり載ってましたわ。
ARG 命令の変数スコープは、それが定義されたビルドステージが終了するときまでです。 複数のビルドステージにおいて ARG を利用する場合は、個々に ARG 命令を指定する必要があります。
最初にドキュメント読んだときは、ビルドステージの意味も分からないまま「あーそーゆーことね完全に理解した」と思ったような気が。。。
ARG の動きを見てみる
では実際にマルチステージビルドでの ARG の動きを見ていきましょう。
本稿の動作確認環境
本稿の執筆にあたっては、下記のバージョンで動作を確認しています。
# docker --version Docker version 18.09.1, build 4c52b90Dockerfile
今回の検証で使う Dockerfile は次の通りです。
Dockerfile# ARG1 は、グローバルに宣言し、グローバルなデフォルト値を設定する。 ARG ARG1="arg1 global default value" # ARG2 は、グローバルに宣言するが、グローバルなデフォルト値は設定しない。 ARG ARG2 # ARG3 は、グローバルに宣言しない。 # ARG ARG3 FROM alpine:latest as first_stage # first_stage では、各 ARG を宣言し、スコープ内のデフォルト値を設定する。 ARG ARG1="arg1 first stage value" ARG ARG2="arg2 first stage value" ARG ARG3="arg3 first stage value" RUN echo -e "first_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" FROM alpine:latest as second_stage # second_stage では、各 ARG を宣言するが、スコープ内のデフォルト値は設定しない。 ARG ARG1 ARG ARG2 ARG ARG3 RUN echo -e "second_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" FROM alpine:latest as third_stage # third_stage では、すべての ARG を宣言しない。 # ARG ARG1 # ARG ARG2 # ARG ARG3 RUN echo -e "third_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"各 ARG は下記のように設定しています。
ARG 名 設定内容 ARG1 グローバルな ARG として設定。デフォルト値も指定。 ARG2 グローバルな ARG として設定。デフォルト値は指定しない。 ARG3 グローバルな ARG として設定しない。 また、各ステージは次のように設定しています。
Stage 名 設定内容 first_stage 各 ARG を宣言。ステージ内のデフォルト値を設定。 second_stage 各 ARG を宣言。ステージ内のデフォルト値は設定しない。 third_stage ARG を宣言しない。
--build-arg
指定なしでビルドDocker Image のビルド時に、
--build-arg
による値の指定を行わずにビルドしてみます。# docker build . --no-cache Sending build context to Docker daemon 14.85kB ...snip... Step 7/14 : RUN echo -e "1st stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in 2bbe78634ee8 first_stage: ARG1=arg1 first stage value ARG2=arg2 first stage value ARG3=arg3 first stage value ...snip... Step 12/14 : RUN echo -e "2nd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in 0c28af93ea9b second_stage: ARG1=arg1 global default value ARG2= ARG3= ...snip... Step 14/14 : RUN echo -e "3rd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in cbca9ed88691 third_stage: ARG1= ARG2= ARG3= ...snip...
- first_stage では、いずれもステージ内のデフォルト値となりました。 ARG1 を見ると、グローバルなデフォルト値よりもステージ内のデフォルト値が優先されていることがわかります。これは、よりスコープが狭い方の値を優先的に使う動きになっており、理にかなっている動きと言えるでしょう。
- second_stage では、 ARG1 のみグローバルなデフォルト値が表示されています。ステージ内で ARG を宣言はしたものの、何も値を指定しなければグローバルなデフォルト値を利用するということですね。 ARG2, ARG3 には何も表示されていませんが、これはその値を指定している場所がどこにもないからですね。
- third_stage ではすべての値が表示されていません。 ARG1 のグローバルなデフォルト値すら表示されていないということは、 ARG を利用するためにはそのステージごとに宣言する必要があるということでしょう。
--build-arg
指定ありでビルド今度は
--build-arg
による値の指定ありでビルドしてみます。# docker build --build-arg ARG1="build arg1 value" --build-arg ARG2="build arg2 value" --build-arg ARG3="build arg3 value" . --no-cache Sending build context to Docker daemon 14.85kB ...snip... Step 7/14 : RUN echo -e "1st stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in 10b37c5a524b first_stage: ARG1=build arg1 value ARG2=build arg2 value ARG3=build arg3 value ...snip... Step 12/14 : RUN echo -e "2nd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in e70e3ff9fe9b second_stage: ARG1=build arg1 value ARG2=build arg2 value ARG3=build arg3 value ...snip... Step 14/14 : RUN echo -e "3rd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}" ---> Running in e675e8f648e8 third_stage: ARG1= ARG2= ARG3= ...snip...
- first_stage, second_stage ともにすべての値が
--build-arg
で指定した値になりました。これは公式ドキュメントの ARG のデフォルト値で説明されている内容と一致しますね。--build-arg
で指定された値はグローバルなデフォルト値及びステージ内のデフォルト値のどちらよりも優先されます。- third_stage ではまたもやすべての値が表示されていません。
--build-arg
で値が指定されていても、そのステージ内で宣言されていなければやはり利用できないようです。まとめ
- マルチステージビルドな Dockerfile で ARG を利用する際には、すべてのステージでそれぞれ利用する ARG を宣言する必要がある。
- 複数のステージで利用している ARG のデフォルト値を定義したければ、グローバルな ARG を定義(最初の FROM よりも前に定義)してそこにデフォルト値を記載すると良い。
- ARG の値の優先度は
--build-arg
での指定値 [優先度高]- ステージ内のデフォルト値
- グローバルなデフォルト値 [優先度低]
おしまい。
宣伝
マルチステージビルドの ARG の挙動に気づくきっかけとなったプロジェクトの宣伝です。
Minecraft の Bedrock Server を楽に運用しようぜ!という趣旨のプロジェクトです。
Minecraft ってたまーにアップデートが入るのですが、クライアントは大体勝手にアップデートされるものの、 Bedrock Server は自動的にアップデートされず、手動で新しいバージョンをダウンロードして Zip ファイルを展開してバイナリファイルを置き換えてサービスを再起動して・・・とかやる必要がありました。
このプロジェクトは、一度セットアップだけやってしまえば、あとは全自動で Bedrock Server をアップデートしてくれます!ついでに Docker を使って Bedrock Server を構築するので環境を汚しません!よろしくお願いします!
本当におしまい。
- 投稿日:2020-10-13T02:47:31+09:00
CentOS6へのDockerインストール
古い情報がかなり多くはまらされた。。。
yum install docker
だと全く関係ない紛らわしいのが入っちゃう
(service docker start
でエラー発生)epelインストールして
yum install docker-io --enablerepo=epel
でいけるという情報多いが
リポジトリ消えてるみたいで今度はrpmで
wget https://yum.dockerproject.org/repo/main/centos/6/Packages/docker-engine-1.7.1-1.el6.x86_64.rpm
でいけるという情報もあったが
これもyum.dockerproject.org
のリンク切れてるっぽいこれならいけた
yum install https://get.docker.com/rpm/1.7.1/centos-6/RPMS/x86_64/docker-engine-1.7.1-1.el6.x86_64.rpm
- 投稿日:2020-10-13T02:47:31+09:00
CentOS 6へのDockerインストール
古い情報がかなり多くはまらされた。。。
yum install docker
だと全く関係ない紛らわしいのが入っちゃう
(service docker start
でエラー発生)epelインストールして
yum install docker-io --enablerepo=epel
でいけるという情報多いが
リポジトリ消えてるみたいで今度はrpmで
wget https://yum.dockerproject.org/repo/main/centos/6/Packages/docker-engine-1.7.1-1.el6.x86_64.rpm
でいけるという情報もあったが
これもyum.dockerproject.org
のリンク切れてるっぽいこれならいけた
yum install https://get.docker.com/rpm/1.7.1/centos-6/RPMS/x86_64/docker-engine-1.7.1-1.el6.x86_64.rpm
- 投稿日:2020-10-13T00:36:34+09:00
Docker で始める PySpark 生活
はじめに
「Spark?雷属性でかっこいい!」という煩悩のもと,Docker + Spark + Jupyter Notebook で簡単な機械学習を回して見ました.
お馴染みのタイタニックデータを使い,線形回帰による予測を行いました.そもそも Spark とは
Spark とは分散処理ライブラリの一つです.
分散処理といえば Hadoop という方も多いと思いますが,自分の理解だと Spark は Hadoop の欠点を補ったライブラリになります.Hadoop が登場したのが 2006 年,その後,2014 年に Hadoop が登場しました.Hadoop VS Spark
上記,Spark は Hadoop の欠点を補ったとありますが,双方にメリット・デメリットがあるため簡単に表にまとめます.
メリット デメリット Hadoop 大量のデータを扱うことができる ストレージアクセスがあるためリアルタイムの処理が苦手 Spark オンメモリでの処理によりリアルタイムでの処理が得意 Hadoopほど大規模なデータは扱えない つまり,大きすぎるデータはHadoop,リアルタイムでの処理がしたかったらSparkを用いると良いでしょう.
また,Hadoopのクエリエンジンは Presto,Hive ですが,Spark には多彩な API が用意されていて Python や Scala などの言語から簡単に呼び出すことができます.
Docker Setup
まず,下記のイメージをダウンロードして,ビルドを行います.
$ docker pull jupyter/pyspark-notebook $ docker run --name spark_test -it -p 8888:8888 -v $PWD:/home/jovyan/work jupyter/pyspark-notebook上記,表示される URL にアクセスすればノートを開くことができます.
※ イメージのサイズが 3GB あるので一応気をつけてください
Python
ライブラリ
import pandas as pd import pyspark from pyspark.sql import SparkSession spark = SparkSession.builder.appName('pandasToSparkDF').getOrCreate() from pyspark.sql.functions import mean, col, split, regexp_extract, when, lit from pyspark.ml import Pipeline from pyspark.ml.feature import StringIndexer, VectorAssembler, QuantileDiscretizer from pyspark.ml.classification import LogisticRegression from pyspark.ml.evaluation import MulticlassClassificationEvaluatorデータ読み込み
# データ読み込み titanic_df = spark.read.csv('./titanic/train.csv', header='True', inferSchema='True')基本的なデータ処理
# 欠損値対応 titanic_df = titanic_df.na.fill({"Embarked" : 'S'}) # 不要のカラムを落とす titanic_df = titanic_df.drop("Cabin") # 定数による列追加 titanic_df = titanic_df.withColumn('Alone', lit(0)) # 条件による値の挿入 titanic_df = titanic_df.withColumn("Alone", when(titanic_df["Family_Size"] == 0, 1).otherwise(titanic_df["Alone"])) # ラベルエンコード indexers = [StringIndexer(inputCol=column, outputCol=column+"_index").fit(titanic_df) for column in ["Sex", "Embarked", "Initial"]] pipeline = Pipeline(stages=indexers) titanic_df = pipeline.fit(titanic_df).transform(titanic_df) # テストスプリット trainingData, testData = feature_vector.randomSplit([0.8, 0.2], seed=9)他にもいろいろな処理が有りますが,いったんめぼしいものだけ置いておきます.
より詳しいデータ処理に関しては下記をご覧ください.
https://databricks-prod-cloudfront.cloud.databricks.com/public/4027ec902e239c93eaaa8714f173bcfc/5722190290795989/3865595167034368/8175309257345795/latest.html学習
# 学習 lr = LogisticRegression(labelCol="Survived", featuresCol="features") lrModel = lr.fit(trainingData) # 推論 lr_prediction = lrModel.transform(testData) lr_prediction.select("prediction", "Survived", "features").show() # 評価 evaluator = MulticlassClassificationEvaluator(labelCol="Survived", predictionCol="prediction", metricName="accuracy") lr_accuracy = evaluator.evaluate(lr_prediction) print("Accuracy of LogisticRegression is = %g"% (lr_accuracy)) print("Test Error of LogisticRegression = %g " % (1.0 - lr_accuracy))他にも下記のモデルをライブラリとして使用できます.
- LogisticRegression
- DecisionTreeClassifier
- RandomForestClassifier
- Gradient-boosted tree classifier
- NaiveBayes
- Support Vector Machine
感想
ローカルだと遅い!
当たり前ですけど,大規模データを処理してこその分散処理のため,この程度のデータでは恩恵は全くありませんでした.
大きすぎるデータに出会った時に速度や精度の比較を行って行けたらと思います.今回の学び
- Docker は便利
- 分散フレームワーク体系の整理
- PySpark ってこう動かんだ…