- 投稿日:2019-07-16T23:50:58+09:00
dockerでマイクラのポケモンサーバ簡単構築
はじめに
dockerでpixelmonサーバ立ち上げたことがあったので、備忘録として残します。
いやぁ、楽しいですよねマインクラフトあと、今回ネットワークと、サーバ設定周りは触れませんので、そこらへんはあしからず
(機会があったら家のサーバ環境とかも取り上げたいです!)構築環境
・centos7
うん、docker動けばどこでもいいよ
・minecraft version 1.12.2
・forge version 14.23.5.2768
(これwin側のバージョンは違うかもです)
・pixelmon version 2.4.2自分が構築した時期も少し前と言うこともあり
全体的に古いバージョンなのですが、そこは臨機応変におねです内容
ディレクトリ構造
centosのユーザで以下ディレクトリ作成してください。
また、mods直下にpixelmonのjarを配置してください。pokemon
|--docker-compose.yml
|--25565
| |--data
| |--mods
| |--PixelmonGenerations-1.12.2-2.4.2-universal.jardocker-compose
docker-composeversion: '3' services: minecraft-server: container_name: miutipokemon image: itzg/minecraft-server ports: - "25565:25565" tty: true stdin_open: true restart: always volumes: - ./25565/mods:/data/mods/ - ./25565/data:/data/ environment: EULA: "TRUE" VERSION: "1.12.2" TYPE: "FORGE" FORGEVERSION: "14.23.5.2768" SPAWN_MONSTERS: "false"(これどうやったら色つくようにできるんだろう・・・)
軽く中身を説明すると
volumesの/data/modsでjarファイルをコンテナ内に同期させ、/dataでデータを永続化してます。
なので、バックアップを取りたい場合は、ホスト側の25565/dataの中身
全部取っておけばおっけーです。environmentの中の設定詳細は以下URL
https://hub.docker.com/r/itzg/minecraft-server実行
docker-composeが配置されてるディレクトリにて
$ docker-compose up -dと実行するだけ!
あとは、ネットワーク環境によりますがサーバ指定して入ってもらえば
OKです!僕のサーバ公開しているので、遊びたいかたいたら一声かけてくださーい。
- 投稿日:2019-07-16T22:51:52+09:00
Sprokets::FileNotFound couldn't find 'spree/backend/all.js'
初めて
docker-compose up —build
を行い、ページに飛んだ際にこのエラーに出くわしました。all.jsがないと言われているから、検索していると、
rails g spree:install
をすると解決するといった記事を見つけたので、以下の方法1のように実行しました。(先に結論から言うと、自分の場合は、この方法でエラーを解決することはできませんでした。)方法1(失敗した方法)
$docker-compose up -d
で、コンテナを起動し、
$docker-compose exec potepanec bash
で、コンテナ内に入り(potepanecの部分は、各自のものに変えてください)、
$bundle exec rake db:migrate:reset
$bundle exec rails g spree:install
を実行しましたが、エラーは解決する事ができませんでした。
方法2(成功した方法)
$docker rm -f $(docker ps -aq) && docker rmi -f $(docker images -q) && docker volume rm -f $(docker volume ls -q)
を行い、一度全部削除しました。この時気をつけなければいけないのは、これだとdockerに入っている他のプロジェクトも削除することになります。自分の場合は、扱っているプロジェクトがエラーを出しているものだけだったので、このコードで、一度全部削除しました。次に、
rm -f app/tmp/pids/server.pid
で、pidを削除しました。このpidを削除しないと、同じエラーをはき出すので、dockerを削除した後、pidも削除することをお勧めします。docker,pidを削除した後、
docker-compose up --build
を行ったところ、無事立ち上がりました!
- 投稿日:2019-07-16T21:48:18+09:00
Debianのdockerイメージでmysql-clientが無くてハマった人へ
結論
mysql-client
パッケージじゃなくてdefault-mysql-client
パッケージを使いましょう経緯
Debian10 "buster"では
mysql-client
パッケージは存在しないため、ベースイメージにDebian10を使っているとDockerイメージでビルドなどしているとコケたりする。Debian9まではmysql-transition
ソースパッケージがmysql-client
バイナリパッケージを提供していたが、名前の通り「transition」なので新しいリリースでは落としたものと思われる。どうするのが良かったのか?
Debian9の時点で
default-mysql-client
パッケージを使うようにしておけばいちばん良かったし、Debian10がリリース前のフリーズ期間(半年ある)で洗い出しとけば良かった。何が変わるの?
mysql-client
パッケージもdefault-mysql-client
パッケージも、結局はmariadb-client
パッケージへの依存→最終的にmariadb-client-10.3
を引っ張るので何も変わらないですね。
- 投稿日:2019-07-16T17:27:36+09:00
Raspberry Pi (Raspbian Buster) にDockerをインストールする
0. 参考文献
正式手順書
https://docs.docker.com/install/linux/docker-ce/debian/ の「Install from a package」
その他参考: Proxy環境でのいろいろ
proxyを設定する
sudo でも効かせる
DockerfileのFROMに効かせる設定
Dockerfile内のコマンドに効かせる1. 環境
HW: Raspberry Pi 4
OS: Raspbian Buster Lite (2019-07-10)2. debファイル群のダウンロード
https://download.docker.com/linux/debian/dists/ を開き、
buster -> pool -> stable -> armhf とたどる最新版(リリース日: 2019-06-27 19:28:10)だとうまく動かない現象があったので、
リリース日: 2019-03-28 05:03:09で揃えてダウンロードしてみる以下をダウンロード
containerd.io_1.2.5-1_armhf.deb (2019-03-28 05:03:09)
docker-ce-cli_18.09.4~3-0~debian-buster_armhf.deb (2019-03-28 05:03:09)
docker-ce_18.09.4~3-0~debian-buster_armhf.deb (2019-03-28 05:03:09)3. インストール
以下の順番でインストール(最初と2番目は順番関係なし。最後は必ず最後)
$ sudo dpkg -i containerd.io_1.2.5-1_armhf.deb
↓
$ sudo dpkg -i docker-ce-cli_18.09.4~3-0~debian-buster_armhf.deb
↓
$ sudo dpkg -i docker-ce_18.09.4~3-0~debian-buster_armhf.deb
4. 確認
「"docker --version"は動いた」、「"docker ps"は動かない」なんてことがあるので、両方試す。
$ sudo docker --version Docker version 18.09.4, build d14af54 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES以上
- 投稿日:2019-07-16T15:32:27+09:00
オンプレConfluenceをDocker化した話
弊社はドキュメント管理にConfluence・ソースコード管理にGitLabを使用しています。
何点か問題あったり・開発にdockerを使用していて、多少なりとも扱えるようになったこともあってコンテナ化しました。
そこらへんをチラ裏感覚で書きます。モチベーション
- ページのPDFエクスポートが動かない問題
- Vagrantで起こしているVirtualBoxのストレージ問題(ストレージがらみの問題でLinux起動失敗する)
- Native Linux マシンがある!
- 今流行(?)のコンテナで運用したい
構成図
windowsマシン上に2つの仮想マシンがあり、それぞれGitLabとConfluenceが起動していました。
↓
1つのLinuxマシン上にGitLab ContainerとConfluence向けのContainersが起動するように変化しました。
(もともと通知とかやっているので、新規のみある図は増えたわけではない。)Docker化でのあれこれ
そもそもコンテナに突っ込まれたConfluenceがあるのか?って話になるんですが、
atlassian/confluence-server - Docker Hubに一応あります。
ただ、Oracle JDK の関係上、Open JDK で提供されており、not supported for running Confluence in production
なんです。なので今回は、publishしないDocker Imageを作成しました。
binファイルをDL後、非対話的にインストールができます。
atlassian-confluence-<ver>-<arch>.bin -q -varfile response.varfile
今回は移行なので、手動インストール時のresponse.varfileがあって流用しましたが、新規だと?ですね。
あとは、PlantUMLプラグイン向けに graphviz と 日本語フォントのインストールをおこないました。Dockerで管理するにあたって、コンテナ3つとVolume1つを作りました。
それぞれ、Confluence・DB・cronで動作するバックアップスクリプトとVolume(NASをsmbでマウント)です。当初、後ろ2つは考えていなかったのですが、
- cronの設定もコード化したい → コンテナ化
- スクリプトの参照ディレクトリを一般化したい・一応認証があるのでホストにマウントしたくない → Docker Volume
って感じで増えていきました。複数のコンテナを制御するのに docker-compose を使用します。
docker-composeを使うことで
- 複数コンテナ
- 環境変数
- Docker Volume
といったものが、コードで管理できていいですね。NASマウントする際のパスワードは、.envファイルに記載し
docker-compose.ymlに.envを記述するだけで取り込めます。services: foo: env_file: .env.envを参照することで、クレデンシャルな情報をgitから除外でき、
間違えてcommitしてしまうことが無くなります。まとめ
- docker-compose で複数コンテナ/環境変数/Volume 管理が便利
- volume を使うことで、アプリ側は、SMBとか意識しなくなる
(ほんとチラ裏で申し訳ない)
- 投稿日:2019-07-16T12:34:59+09:00
Docker+Nginx+PHP-FPMでユーザーをroot以外に設定する
Docker Composeでnginxとphp-fpmの環境を作るときの設定で少しハマりました。
実行ユーザーをrootのままにすればdocker-composeですんなり設定できるかもしれませんが、今後の運用も考えてセキュリティ面でroot以外に設定したほうが良いと思い、そのように設定を進めました。
php-fpmとDockerfileの設定を見直すことで実行ユーザーの設定ができましたのでその経緯を書いていきます。
今回想定している環境は下記になります。
- docker 18.09.2
- docker-compose 1.23.2
- image php:7.2-fpm
- image nginx:1.15
TL; DR
php-fpmのwww.confでuser, groupを削除しlisten.groupのみ設定。そしてDockerfileでphp-fpmのファイルにグループ権限付与することでroot以外のユーザーで実行できる。
Dockerfileの実行ユーザーはroot以外にする
NginxとMySQLはオフィシャルのイメージをビルドするだけで済みましたが、
PHPは設定する部分や必要な拡張子などが多かったのでDockerfileを個別に作りました。ベストなDockerfileを書きたかったのでDockleを用いてチェックしたところ、
WARN - CIS-DI-0001: Create a user for the container * Last user should not be rootという警告が。
こちらにも載っていました。
https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#cis-di-0001-create-a-user-for-the-containerセキュリティ的にも、Dockerfileでコンテナを実行するユーザーはroot以外の方が良いです。
それに
docker-compose exec
をroot権限で実行できてしまうのは危険ですからね。そこでphp-fpmのDockerfileにユーザーを追加してみます。
php-fpmのDockerfileに追記
php-fpm用のユーザーを追加します。今回は
www-user
としています。./docker/php/DockerfileFROM php:7.2-fpm # Install extensions RUN apt-get update \ && apt-get install -y libicu-dev zip unzip curl zlib1g-dev libpng-dev vim procps git \ && docker-php-ext-install intl opcache \ && docker-php-ext-enable intl opcache \ && docker-php-ext-install pdo pdo_mysql mysqli\ && docker-php-ext-install mbstring \ && docker-php-ext-install gd \ && apt-get clean && rm -rf /var/lib/apt/lists/* + RUN useradd -ms /bin/bash www-user \ + && echo "www-user:piyohoge" | chpasswd + USER www-user
これで再度ビルドしてみます。
ターミナル% docker-compose down % export $(cat .env | xargs) % docker-compose build --no-cache Creating network "myservice_app-network" with the default driver Building php Step 1/17 : FROM php:7.2-fpm ... ... Successfully built 8d4ff435a5d2 Successfully tagged myservice_php:latest % docker-compose up -d creating network "myservice_mynetwork" with the default driver Creating myservice_php_1 ... done Creating myservice_db_1 ... done Creating myservice_web_1 ... done上手くいったような気がします。
しかし、php-fpmのパーミッション周りでエラーが
ログを見てみるとエラーになっていました。
ターミナル% docker-compose logs php Attaching to myservice_php_1 php_1 | NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root php_1 | NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root php_1 | NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root php_1 | NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root php_1 | ERROR: unable to bind listening socket for address '/var/run/php-fpm.sock': Permission denied (13) php_1 | ERROR: unable to bind listening socket for address '/var/run/php-fpm.sock': Permission denied (13) php_1 | ERROR: FPM initialization failed php_1 | ERROR: FPM initialization failedmyservice_php_1がExitに。
エラー内容を見てみると、php-fpmの実行ユーザーが上手く設定されていないようです。
rootじゃないとphp-fpmのuser
、group
ディレクティブは無効になりますし、かといってrootにするわけにもいきませんし、ハマりました。Dockerfile、php-fpmの設定を修正する
調べていく中で、少し古い内容ですが、下記が参考になりました。
https://github.com/phpbrew/phpbrew/issues/459root以外のユーザーでphp-fpmを立ち上げたい場合、php-fpm用のグループを設定することで実行ができるようになるとのことです。
そこで、
www.conf
でグループを設定し、そのグループに権限を与えます。下記が
www.conf
の設定です。/usr/local/etc/php-fpm.d/www.conf[global] daemonize = no ; Start a new pool named 'www'. ; the variable $pool can be used in any directive and will be replaced by the ; pool name ('www' here) [www] - user = nginx - group = nginx listen = /var/run/php-fpm.sock - listen.owner = nginx listen.group = nginx + listen.mode = 0660Dockerfileの方でもグループへの権限を付与します。
php-fpmの実行ユーザー
www-user
を先ほど設定したグループに追加します。
ただ、上記で使用しているusermod
はグループを全て上書きしてしまい危険なので別の書き方にします。php-fpmに関係するファイルにも権限を付与します。
./docker/php/DockerfileFROM php:7.2-fpm # Install extensions RUN apt-get update \ && apt-get install -y libicu-dev zip unzip curl zlib1g-dev libpng-dev vim procps git \ && docker-php-ext-install intl opcache \ && docker-php-ext-enable intl opcache \ && docker-php-ext-install pdo pdo_mysql mysqli\ && docker-php-ext-install mbstring \ && docker-php-ext-install gd \ && apt-get clean && rm -rf /var/lib/apt/lists/* + RUN chown -R www-user:nginx /var/www/ \ + && chown -R www-user:nginx /var/run/ \ + && chown -R www-user:nginx /var/log/ - RUN useradd -ms /bin/bash www-user \ + RUN useradd -ms /bin/bash -g nginx www-user \ && echo "www-user:piyohoge" | chpasswd USER www-user
docker volume rm
でボリュームを削除して再ビルド。ターミナル% docker-compose build --no-cache && docker-compose up -d ... % docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------------------- myservice_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp myservice_php_1 docker-php-entrypoint php-fpm Up 9000/tcp, 9001/tcp myservice_web_1 /bin/sh -c nginx -g daemon ... Up 0.0.0.0:443->443/tcp, 0.0.0.0:8080->80/tcpこれで上手く立ち上がりました。
初歩的なところかもしれませんが、もしphp-fpm周りの設定で詰まっていたら試してみてください。
- 投稿日:2019-07-16T11:42:04+09:00
VSCodeのRemote Developmentを使ってDocker上のNode.js、Redis環境で作業する
2019年5月に公開された、Visual Studio Code でリモートマシン、コンテナ、Windows Subsystem for Linux (WSL) 上のワークスペースを開くことができるようになる拡張機能群「Remote Development Extension Pack」を使ってみました。
この拡張パックを導入すると、手元の「Visual Studio Code」からリモート環境へ接続し、そこでアプリ開発等を行うことが可能になります。
今回は、Microsoftのレポジトリ VSCode Remote Try Nodeを元に、Node.jsからRedisを扱うDockerコンテナに接続する設定をやってみます。
1 Visual Studio Codeのバージョン確認
Stable 版では (version 1.35) リリース以降で Remote Development 拡張が利用可能です。
バージョンが古い場合は、Visual Studio Code の [ヘルプ]->[更新の確認] または https://code.visualstudio.com/updates 等から最新版にアップデートしてください。2 拡張機能Remote Developmentのインストール
Visual Studio Codeで拡張機能"Remote Development"を検索し、インストールしてください。
3 プロジェクトの構成
Microsoftのレポジトリ VSCode Remote Try Nodeをクローンし、最低限のディレクトリ構成を揃えた後、必要なファイルを加除していきます。
[Project Home] |_ .devcontainer | |_ devcontainer.json | |_ ubuntu-bionic-core-cloudimg-amd64-root.tar.gz | |_ .vscode | |_ launch.json | |_ build | |_ server.js |_ src | |_ server | |_ main.ts |_ store | |_ redis | |_ .gitkeep | |_ Dockerfile |_ docker-compose.yml |_ package.json |_ tsconfig.json |_ tslint.json |_ webpack.config.js公式ではDockerfileを .devcontainer 以下に配置していますが、 ホームディレクトリ上のローカルフォルダ store/redis とDockerコンテナ上のディレクトリを同期してデータ永続化したいので、ホームディレクトリ直下に配置しています。
また、公式では、node:10イメージをベースを使っていますが、 今回は、Linuxイメージ上に npm, node.jsをインストールしたコンテナを作成し、redis コンテナとリンクする構成をやってみたいと思います。
当初、軽量Linuxの代表格alpineをベースにしようとしましたが、どうやら Stable版のVSCode上で動くRemote Developmentではalpineをサポートしていないようなので、やむなくMinimum Ubuntuを使うことにしました。
MInimum Ubuntuのイメージファイルは以下のレポジトリからダウンロードし、.devcontainer以下に配置しました。
4 Remote Development の設定
devcontainer.json
devcontainer.json{ "name": "node.js and redis sample ", "dockerComposeFile": [ "../docker-compose.yml" ], "service": "node", "appPort": 3000, "extensions": [ "VisualStudioExptTeam.vscodeintellicode", "dbaeumer.vscode-eslint", "eg2.tslint" ], "settings": { "terminal.integrated.shell.linux": "/bin/bash" }, "shutdownAction": "none" }主要な設定項目としては、
- service で node.jsを稼働するコンテナのサービス名を指定
- appPort で node.js上でlistenするportを指定
- dockerComposeFileでdocker-compose.ymlの相対パスを指定
- extensions でリモート上のVSCodeで使う拡張機能を追加
ちなみに、普段使っているVSCodeの拡張機能一覧は
code --list-extensions | xargs -L 1 echo code --install-extensionで取得できます。
5 Docker の設定
Dockerfile
DokerfileFROM scratch ADD .devcontainer/ubuntu-bionic-core-cloudimg-amd64-root.tar.gz / RUN set -xe \ \ && echo '#!/bin/sh' > /usr/sbin/policy-rc.d \ && echo 'exit 101' >> /usr/sbin/policy-rc.d \ && chmod +x /usr/sbin/policy-rc.d \ \ && dpkg-divert --local --rename --add /sbin/initctl \ && cp -a /usr/sbin/policy-rc.d /sbin/initctl \ && sed -i 's/^exit.*/exit 0/' /sbin/initctl \ \ && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \ \ && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \ && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \ && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \ \ && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \ \ && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \ \ && echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests RUN rm -rf /var/lib/apt/lists/* RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container # Configure apt and install packages RUN apt-get update && \ yes | apt-get install \ curl \ git \ npm \ nodejs WORKDIR /home SHELL ["/bin/bash", "-c"]基本的に、https://github.com/tianon/docker-brew-ubuntu-core/blob/59aa7dfef17153ecc812adbf26516675ce67e8aa/bionic/Dockerfile のままです。追加項目として、#Configure apt and install packages以下で、必要なモジュールをインストールするようにします。
docker-compose.yml
docker-compose.ymlversion: '3' services: node: build: context: . dockerfile: Dockerfile container_name: node-container volumes: - .:/home ports: - 3000:3000 command: sh -c 'npm install & node build/server.js' links: - "redis" redis: restart: always container_name: redis-container image: redis:latest volumes: - ./store/redis:/data ports: - "6379:6379" command: redis-server --appendonly yes上記のDockerfileを走らせて作成するnodeイメージと、Official Imageのredis:latestイメージをリンクします。
特記事項として、redis側でローカルのstore/redisとコンテナ側のdataフォルダを同期し、データの永続化を行っています。6 package.jsonの設定
今回は、Webpackを使ってTypeScriptをトランスパイルする例です。
2019年7月現在の、webpackの最新バージョン 4.29.0 では Maximum Call Stackのエラーが出てしまうため、旧バージョンを指定しています。
package.json{ "name": "node.js and redis sample", "version": "1.0.0", "devDependencies": { "@types/app-root-path": "", "@types/express": "", "@types/node": "", "@types/redis": "", "path": "", "ts-loader": "", "tslint": "", "tslint-loader": "", "typescript": "", "webpack": "4.17.1", "webpack-cli": "", "webpack-node-externals": "" }, "dependencies": { "app-root-path": "", "express": "", "redis": "" }, "private": true }7 Node.jsによるサーバ設定
expressでWebサーバを立ち上げ、redisでPOSTの回数をカウントするという例です。
main.ts'use strict'; import * as root from 'app-root-path'; import * as express from 'express'; import * as redis from 'redis'; /** * Configure Redis */ const client: redis.RedisClient = redis.createClient(6379, 'redis'); client.on('connect', () => console.log('Connected to Redis')); client.set('visit', '0'); /** * Configure Web Server */ const app: express.Application = express(); app.use(express.static('.')); app.post('/api', (_req: express.Request, res: express.Response) => { client.get('visit', (_err: Error|null , visit: string) => { res.send('POST request received. Number of Visits:' + visit); client.set('visit', String(parseInt(visit, 10) + 1)); }); }); // tslint:disable-next-line:typedef const port = process.env.PORT || 3000; app.listen(port, () => console.log(`Server running on ${port}`));8 実行
F1で拡張機能の一覧を表示するか、Visual Studioコードの左下の緑色のブラケットマークからRemoteデスクトップの機能一覧を表示します。
docker-compose up --build
を既に一度走らせている場合は、「Attach to Running Container(水色)」を選択し、まだの場合は「Open Folder in Container(赤色)」で現在のホームディレクトリを指定すればdocker-compose up --build
が自動的に走ります。ビルドに成功すると、Remote Development用のVSCodeのウィンドウが起動します。後は開いたウィンドウ上で「フォルダを開く」から任意のフォルダを開くと、コンテナ上のファイルをVS Codeで編集することができます。
9 Redisの動作確認
Remote Developmentとは直接関係ありませんが、Redisがきちんと動作しているか確認するには、
curl -X POST
(ローカル、コンテナ側のどちらからでも結構です) で以下のAPIを叩き、curl -X POST http://localhost:3000/api
以下のようにPOSTの通算回数が返ってくれば成功です。
POST request received. Number of Visits:[POSTの回数]10 参考にさせていただいたサイト
下記のページを参考にさせていただきました。
https://code.visualstudio.com/updates/v1_35
https://qiita.com/yoskeoka/items/01c52c069123e0298660
https://qiita.com/mizuhof/items/7bc20538c9fe1edcba40
https://katsu-tech.hatenablog.com/entry/2017/10/11/233024
https://blog.manabusakai.com/2018/08/minimal-ubuntu-dockerfile/なお、今回の構成はGithubで公開していますので、ご指摘などあればよろしくお願いいたします
https://github.com/snst-lab/vscode-remote-try-node-typescript-redis
- 投稿日:2019-07-16T09:37:04+09:00
「ModuleNotFoundError: No module named」の1つの解決方法
はじめに
こんにちは。
私は、大学4回生で、プログラミングを勉強しています。
現在、未来電子テクノロジーでプログラミング開発コースでインターンを行なっています。
今回は、Dockerの仮想環境の立ち上げ、djangoを使用した際に出たエラーについてお話しします。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。エラー内容
まず初めに、dockerの仮想環境を立ち上げ、djangoのインストール、接続も問題なく行えました。
djangoの設定に成功すると、ロケットが打ち上げの画面が出てきます。
この後に問題が起こりました。
それは、URLの設定時でした。
urls.pyに以下のようなコードを書きました。from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('blogs.urls')), ]このコード内で、「from django.urls import path, include」内にエラーが出ました。
ターミナル上では、「ModuleNotFoundError: No module named 'blogs'」のエラーです。解決方法
解決方法を求めるために、問題点を探しました。
それは、以下の2つでした。
1、dockerのバージョンが古い
2、古い使っていないimagesが誤作動を起こしている1は、docker compose の際に、違うサイトで探した方法で仮想環境を作っている際に、古いバージョンのdjangoをインストールをしてしまったからです。
確認方法は、以下です。>>> import django >>> django.get_version()2は、何回も失敗していたことが仇となっていました。
未使用イメージの削除は、以下です。$ docker rmi `docker images -q`まとめ
よくわからないエラーを解決するためには、問題点を見極めることを知りました。
これからに生かせればいいなと思います。
- 投稿日:2019-07-16T04:41:28+09:00
【MongoDB】MongoDBのDockerコンテナ起動時に認証用ユーザーを作成する
MongoDBのDockerコンテナを使って開発を行う際に本番環境での使用も考えて、アプリケーションやターミナルから接続する時に認証するように設定しました。
コンテナを起動してからコマンドでの設定やShell Scriptを自作してやるのはスマートでないと思い色々調べていると、公式のイメージが初期データを挿入できるように作られていました。その方法と裏で何をしているのかを調べたので備忘録として書いておきます。環境
- Docker Desktop for Mac ver 2.0.0.3
- Docker Engine ver 18.09.2
- MongoDB Docker Image tag 4.1-bionic
認証用ユーザーの作成方法
ユーザーを作成するJavaScript
createUser.jsconst user = { user: 'staff', pwd: 'staff_password', roles: [{ role: 'readWrite', db: 'test' }] }; db.createUser(user);このスクリプトによって、ユーザー名
staff
、パスワードstaff_password
、test
DBのreadWrite
権限が付与されたユーザーが作成されます。ちなみにロールは複数付与することができます。
MongoDBに接続にはmongo test -u staff -p staff_password
コマンドを実行します。認証の有効化
MongoDBは
MongoDB does not enable access control by default. You can enable authorization using the --auth or the security.authorization setting.
と書かれている通り、デフォルトでは認証・認可は有効化されていません。認証用のユーザーを作ったところで認証・認可を有効にしないと意味がありません。
有効にする方法は、引用文に書かれているように--auth
コマンドオプションを使用するか、コンフィグのsecurity.authorization
をenabled
にする2通りあります。Dockerfile
認証用ユーザーを起動時に作成するためには、createUser.jsを
/docker-entrypoint-initdb.d
下に配置する必要があります。
そして、認証・認可を有効化したDockerfileは以下のようになります。FROM mongo:4.1-bionic COPY createUser.js /docker-entrypoint-initdb.d/ EXPOSE 27017 CMD ["mongod", "--auth"]docker-entrypoint.shのカラクリ
MongoDBのDockerイメージではコンテナ起動時にdocker-entrypoint.shが実行されて初期データが挿入されます。そのShell Scriptが何をやっているのかを説明していこうと思います。
rootユーザーの生成
環境変数に
MONGO_INITDB_ROOT_USERNAME
とMONGO_INITDB_ROOT_PASSWORD
が設定されているとrootユーザーが作成されます。このrootユーザーはroleがrootとなっており、全てのリソースにアクセスできるようになっています。なので、rootユーザーが必要ない状況であれば作成しない方がいいです。以下がrootユーザーを生成している該当箇所です。
docker-entrypoint.shmongo=( mongo --host 127.0.0.1 --port 27017 --quiet ) if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then rootAuthDatabase='admin' "${mongo[@]}" "$rootAuthDatabase" <<-EOJS db.createUser({ user: $(_js_escape "$MONGO_INITDB_ROOT_USERNAME"), pwd: $(_js_escape "$MONGO_INITDB_ROOT_PASSWORD"), roles: [ { role: 'root', db: $(_js_escape "$rootAuthDatabase") } ] }) EOJS fi
変数 値 説明 $mongo mongo --host 127.0.0.1 --port 27017 --quiet localhostの27017でリッスンしているMongoDBに接続するためのコマンド $rootAuthDatabase admin adminというデータベース スクリプトでは、adminデータベースにユーザー名が
MONGO_INITDB_ROOT_USERNAME
、パスワードがMONGO_INITDB_ROOT_PASSWORD
、ロールがroot
であるユーザーを作成しています。初期データの挿入
初期データを挿入するためには、それ用のShell ScriptかJavaScriptを書く必要があります。この2つ以外のスクリプトであると無視されます。
挿入用スクリプトが/docker-entrypoint-initdb.d
に配置されていれば、スクリプトが実行されます。もちろん他のディレクトリに配置したら実行されません。←当たり前ですねw前置きはこの辺にしてdocker-entrypoint.shの中身を見ていきましょう。
注) 行番号は説明のため1から連番にしてありますが、本物のソースコードの行番号と違います。docker-entrypoint.sh1 export MONGO_INITDB_DATABASE="${MONGO_INITDB_DATABASE:-test}" 2 3 for f in /docker-entrypoint-initdb.d/*; do 4 case "$f" in 5 *.sh) echo "$0: running $f"; . "$f" ;; 6 *.js) echo "$0: running $f"; "${mongo[@]}" "$MONGO_INITDB_DATABASE" "$f"; echo ;; 8 *) echo "$0: ignoring $f" ;; 9 esac 10 echo 11 done1行目
操作対象となるDBを環境変数
MONGO_INITDB_DATABASE
に格納してエクスポートしています。デフォルトではtest
というDBが対象となっています。3行目
/docker-entrypoint-initdb.d
下にある全てのスクリプトを実行できるようにfor文で回しています。なので、実行内容ごとにスクリプトを分けて複数のスクリプトを/docker-entrypoint-initdb.d
に配置することも可能です。1つのスクリプトにごちゃごちゃいろんなことを書かずに済みますね。5行目
Shell Scriptを実行しています。
.
はスクリプトを読み込んで実行するという意味です。source
コマンドと同様の役割を果たします。6行目
JavaScriptを実行します。mongoコマンドには
You can specify a .js file to the mongo shell, and mongo will execute the JavaScript directly.
とあるようにJavaScriptを直接実行できる機能があります。わざわざ
node
コマンドとかで実行している訳ではありません。
${mongo[@]}
はrootユーザーの作成のところでも出てきましたが、mongo --host 127.0.0.1 --port 27017 --quiet
を指しています。最後に
これで、初期データを挿入する方法とそのからくりがわかったと思います。
開発の場面では接続用のユーザーを作成したり、テストデータを挿入する時などに役に立つと思います。初期データを挿入できるのはMongoDBだけでなく、MySQLやPostgreSQLなどでも可能です。
便利な機能を使って環境構築は楽に素早く行って、メインの開発に注力していきましょう!
それでは参考資料
- 投稿日:2019-07-16T01:02:46+09:00
コンテナイメージのセキュリティチェック&脆弱性診断を簡易的に実施する
どうも、若松です。
最近、コンテナイメージをビルドしまくっており、オレオレなコンテナイメージが増殖しています。
そんなおり、以下の記事が目に止まりました。DockerHubで公開されているコンテナが安全か確かめてみた結果【人気のコンテナ上位800個】
そりゃあ脆弱性あるわなぁと思いつつ、じゃあオレのコンテナイメージは大丈夫か?と思いました。
というわけで上記の記事で使用されていたdockle
とTrivy
を使って、オレオレコンテナイメージをチェックしていきたいと思います。使用ツール
dockle
CISベンチマークやDockerベストプラクティスに準拠したコンテナイメージかをチェックできます。
WARNやFATALの項目には、どのように改善すればよいかのヒントが添えられていて小憎いですそれぞれの基準は以下の通り
CISベンチマーク
DockerベストプラクティスTrivy
OSやアプリケーションに潜む脆弱性をチェックできます。
CVE番号と共に脆弱性の詳細を表示してくれるので、どのように改善するかの計画が立てやすいです。対象OSとアプリケーションは以下の通り
https://github.com/knqyf263/trivy#vulnerability-detectionインストール
今回はMacのローカルにコンテナイメージがあるため、
brew
でインストールしました。
手順はそれぞれのREADMEに記載があるため、省略します。実行結果
前回の記事で作成したLaravelコンテナを対象にしました。
https://qiita.com/t_wkm2/items/910b4d7079b8413895a6dockle
$ dockle laravel:latest WARN - CIS-DI-0001: Create a user for the container * Last user should not be root PASS - CIS-DI-0005: Enable Content trust for Docker WARN - CIS-DI-0006: Add HEALTHCHECK instruction to the container image * not found HEALTHCHECK statement PASS - CIS-DI-0007: Do not use update instructions alone in the Dockerfile PASS - CIS-DI-0008: Remove setuid and setgid permissions in the images PASS - CIS-DI-0009: Use COPY instead of ADD in Dockerfile PASS - CIS-DI-0010: Do not store secrets in ENVIRONMENT variables PASS - CIS-DI-0010: Do not store secret files PASS - DKL-DI-0001: Avoid sudo command PASS - DKL-DI-0002: Avoid sensitive directory mounting PASS - DKL-DI-0003: Avoid apt-get/apk/dist-upgrade PASS - DKL-DI-0004: Use apk add with --no-cache PASS - DKL-DI-0005: Clear apt-get caches WARN - DKL-DI-0006: Avoid latest tag * Avoid 'latest' tag PASS - DKL-LI-0001: Avoid empty password PASS - DKL-LI-0002: Be unique UID PASS - DKL-LI-0002: Be unique GROUP大きな問題はありませんでしたが、WARNが3件出て、改善に向けたアドバイスが表示されていることがわかります。
Trivy
$ trivy laravel:latest 2019-07-16T00:26:44.376+0900 INFO Updating vulnerability database... 2019-07-16T00:26:46.203+0900 WARN You should avoid using the :latest tag as it is cached. You need to specify '--clear-cache' option when :latest image is changed 2019-07-16T00:26:48.159+0900 INFO Detecting Alpine vulnerabilities... 2019-07-16T00:26:48.171+0900 INFO Updating composer Security DB... 2019-07-16T00:26:51.928+0900 INFO Detecting composer vulnerabilities... 2019-07-16T00:26:51.928+0900 INFO Updating composer Security DB... 2019-07-16T00:26:53.211+0900 INFO Detecting composer vulnerabilities... 2019-07-16T00:26:53.214+0900 INFO Updating composer Security DB... 2019-07-16T00:26:54.422+0900 INFO Detecting composer vulnerabilities... 2019-07-16T00:26:54.422+0900 INFO Updating composer Security DB... 2019-07-16T00:26:56.052+0900 INFO Detecting composer vulnerabilities... var/www/laravel/vendor/psy/psysh/vendor-bin/box/composer.lock ============================================================= Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) var/www/laravel/vendor/hamcrest/hamcrest-php/composer.lock ========================================================== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) laravel:latest (alpine 3.10.1) ============================== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) var/www/laravel/vendor/phar-io/manifest/composer.lock ===================================================== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) var/www/laravel/composer.lock ============================= Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)脆弱性は検出されませんでしたが、AlpineLinuxに加えてComposerも対象に診断を行ってくれることがわかります。
引っかかる場合の表示
上記でチェックしたコンテナイメージは最新のベースイメージであったため、引っかかる項目が少ない結果となりました。
しかしながら、これではチェックに引っかかった場合の表示がわからないため、ずいぶん前(docker images
で見ると9ヶ月前)にpullして手元にあったhttpd:2.4-alpine
をチェックしてみます。dockle
$ dockle httpd:2.4-alpine WARN - CIS-DI-0001: Create a user for the container * Last user should not be root PASS - CIS-DI-0005: Enable Content trust for Docker WARN - CIS-DI-0006: Add HEALTHCHECK instruction to the container image * not found HEALTHCHECK statement PASS - CIS-DI-0007: Do not use update instructions alone in the Dockerfile PASS - CIS-DI-0008: Remove setuid and setgid permissions in the images PASS - CIS-DI-0009: Use COPY instead of ADD in Dockerfile PASS - CIS-DI-0010: Do not store secrets in ENVIRONMENT variables PASS - CIS-DI-0010: Do not store secret files PASS - DKL-DI-0001: Avoid sudo command PASS - DKL-DI-0002: Avoid sensitive directory mounting PASS - DKL-DI-0003: Avoid apt-get/apk/dist-upgrade FATAL - DKL-DI-0004: Use apk add with --no-cache * Use --no-cache option if use 'apk add': /bin/sh -c set -eux; runDeps=' apr-dev apr-util-dev apr-util-ldap perl '; apk add --no-cache --virtual .build-deps $runDeps ca-certificates coreutils dpkg-dev dpkg gcc gnupg libc-dev libressl libressl-dev libxml2-dev lua-dev make nghttp2-dev pcre-dev tar zlib-dev ; ddist() { local f="$1"; shift; local distFile="$1"; shift; local success=; local distUrl=; for distUrl in $APACHE_DIST_URLS; do if wget -O "$f" "$distUrl$distFile" && [ -s "$f" ]; then success=1; break; fi; done; [ -n "$success" ]; }; ddist 'httpd.tar.bz2' "httpd/httpd-$HTTPD_VERSION.tar.bz2"; echo "$HTTPD_SHA256 *httpd.tar.bz2" | sha256sum -c -; ddist 'httpd.tar.bz2.asc' "httpd/httpd-$HTTPD_VERSION.tar.bz2.asc"; export GNUPGHOME="$(mktemp -d)"; for key in A93D62ECC3C8EA12DB220EC934EA76E6791485A8 B9E8213AEFB861AF35A41F2C995E35221AD84DFF ; do gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; done; gpg --batch --verify httpd.tar.bz2.asc httpd.tar.bz2; command -v gpgconf && gpgconf --kill all || :; rm -rf "$GNUPGHOME" httpd.tar.bz2.asc; mkdir -p src; tar -xf httpd.tar.bz2 -C src --strip-components=1; rm httpd.tar.bz2; cd src; patches() { while [ "$#" -gt 0 ]; do local patchFile="$1"; shift; local patchSha256="$1"; shift; ddist "$patchFile" "httpd/patches/apply_to_$HTTPD_VERSION/$patchFile"; echo "$patchSha256 *$patchFile" | sha256sum -c -; patch -p0 < "$patchFile"; rm -f "$patchFile"; done; }; patches $HTTPD_PATCHES; gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; ./configure --build="$gnuArch" --prefix="$HTTPD_PREFIX" --enable-mods-shared=reallyall --enable-mpms-shared=all ; make -j "$(nproc)"; make install; cd ..; rm -r src man manual; sed -ri -e 's!^(\s*CustomLog)\s+\S+!\1 /proc/self/fd/1!g' -e 's!^(\s*ErrorLog)\s+\S+!\1 /proc/self/fd/2!g' "$HTTPD_PREFIX/conf/httpd.conf"; runDeps="$runDeps $( scanelf --needed --nobanner --format '%n#p' --recursive /usr/local | tr ',' '\n' | sort -u | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' )"; apk add --virtual .httpd-rundeps $runDeps; apk del .build-deps PASS - DKL-DI-0005: Clear apt-get caches PASS - DKL-DI-0006: Avoid latest tag FATAL - DKL-LI-0001: Avoid empty password * No password user found! username : root PASS - DKL-LI-0002: Be unique UID PASS - DKL-LI-0002: Be unique GROUPFATALが出ているのが確認できます。
最新のAlpineLinuxでは出ないものなので、定期的にチェックは必要だなと思います。Trivy
$ trivy httpd:2.4-alpine 2019-07-16T00:48:09.514+0900 INFO Updating vulnerability database... 2019-07-16T00:48:13.096+0900 INFO Detecting Alpine vulnerabilities... httpd:2.4-alpine (alpine 3.7.1) =============================== Total: 13 (UNKNOWN: 0, LOW: 2, MEDIUM: 5, HIGH: 5, CRITICAL: 1) +------------+------------------+----------+-------------------+---------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +------------+------------------+----------+-------------------+---------------+--------------------------------+ | bzip2 | CVE-2019-12900 | HIGH | 1.0.6-r6 | 1.0.6-r7 | bzip2: out-of-bounds write in | | | | | | | function BZ2_decompress | +------------+------------------+ +-------------------+---------------+--------------------------------+ | expat | CVE-2018-20843 | | 2.2.5-r0 | 2.2.7-r0 | expat: large number of colons | | | | | | | in input makes parser consume | | | | | | | high amount... | +------------+------------------+----------+-------------------+---------------+--------------------------------+ | libxml2 | CVE-2018-14404 | MEDIUM | 2.9.7-r0 | 2.9.8-r1 | libxml2: NULL pointer | | | | | | | dereference in | | | | | | | xpath.c:xmlXPathCompOpEval() | | | | | | | can allow attackers to cause | | | | | | | a... | + +------------------+ + + +--------------------------------+ | | CVE-2018-14567 | | | | libxml2: Infinite loop when | | | | | | | --with-lzma is used allows for | | | | | | | denial of service... | + +------------------+----------+ + +--------------------------------+ | | CVE-2018-9251 | LOW | | | libxml2: infinite loop in | | | | | | | xz_decomp function in xzlib.c | +------------+------------------+----------+-------------------+---------------+--------------------------------+ | perl | CVE-2018-18311 | HIGH | 5.26.2-r1 | 5.26.3-r0 | perl: Integer overflow | | | | | | | leading to buffer overflow in | | | | | | | Perl_my_setenv() | + +------------------+ + + +--------------------------------+ | | CVE-2018-18314 | | | | perl: Heap-based buffer | | | | | | | overflow in S_regatom() | + +------------------+ + + +--------------------------------+ | | CVE-2018-18312 | | | | perl: Heap-based | | | | | | | buffer overflow in | | | | | | | S_handle_regex_sets() | + +------------------+----------+ + +--------------------------------+ | | CVE-2018-18313 | MEDIUM | | | perl: Heap-based buffer read | | | | | | | overflow in S_grok_bslash_N() | +------------+------------------+----------+-------------------+---------------+--------------------------------+ | postgresql | CVE-2019-10164 | CRITICAL | 10.5-r0 | 10.9-r0 | PostgreSQL: stack-based | | | | | | | buffer overflow via setting a | | | | | | | password | + +------------------+----------+ +---------------+--------------------------------+ | | CVE-2019-10129 | MEDIUM | | 10.8-r0 | postgresql: Memory disclosure | | | | | | | in partition routing | + +------------------+----------+ + +--------------------------------+ | | CVE-2019-10130 | LOW | | | postgresql: Selectivity | | | | | | | estimators bypass row security | | | | | | | policies | +------------+------------------+----------+-------------------+---------------+--------------------------------+ | sqlite | CVE-2018-20346 | MEDIUM | 3.21.0-r1 | 3.25.3-r0 | CVE-2018-20505 CVE-2018-20506 | | | | | | | sqlite: Multiple flaws in | | | | | | | sqlite which can be triggered | | | | | | | via... | +------------+------------------+----------+-------------------+---------------+--------------------------------+ライブラリ毎に表示されるので見やすいですね。
CRITICALが出ているので、ここは最低でも塞いで起きたいところです。まとめ
簡単にイメージスキャンができることがわかっていただけたと思います。
今回は素のままのコマンド実行でしたが、表示形式の変更やファイルへの出力などのオプションもあるので、うまく使って様々な箇所に応用していきましょう。
- 投稿日:2019-07-16T00:16:06+09:00
DockerHubにあるimageを使ってCakePHPを表示、少し中をみるまで…
はじめに
今回使うDockerHubのimageがあるところは、以下URLです。
https://hub.docker.com/r/quantumobject/docker-cakephp
$
はうつコマンドの前につけてあるだけなので$
部分は打たないでください。あと以下で行うのは本格的開発には向いていません。少しみて少し中いじいじしたいんだと言う方へ向けたものです(/ω\)
使ってみる
●まずはCakePHPの表示を行うまで
・はじめにDockerを使えるようにするまでの私のいつもの手順のcommand書いておきます。
Docker始めるまでの記事も書いたのでもしよかったらみてください。//defaultマシーン起動 $ docker-machine start default //環境変数の確認 $ docker-machine env default //環境変数の適応 $ eval "$(docker-machine env default)"・早速URL先のimageをとってきてbuild、Runまで行う。
$ docker run -d -p 80 quantumobject/docker-cakephpはい。たったの一行です。完了するまで環境にもよりますが15分ほどでしょうか?
終わったら現在Dockerで走っているのにこれがあるか見てみます。
$ docker psポート32769で動いているようです。
これで0.0.0.0:32769
で表示できる方もいるかもしれませんが私はここで表示されているipの確認をしないといけないので確認をします。$ docker-machine ip defaultあとは、表示されたipアドレスを使い、
http://<ここipアドレス>:32769/ な感じでアクセスすれば出来ます。
- 表示出来たのでだいぶ満足なのですが中も少しみてみます。 まずは今動いているものを表示。表示されたら一番左に表示されている
CONTAINER ID
を使います。 え~たくさんあるぞって方は一番右から2番目にIMAGE名
が表示されているのでそれがquantumobject/docker-cakephp
のものを$ docker ps
- 動いているコンテナに入る
$ docker exec -it <先ほどのCONTAINER ID> bash
- 本体色々と入っているところまで移動(
/var/www
以下)$ cd /var/www
- もう少し中身をみる。
$ cd srcちなみに抜けるのは、
$ exitで出来ます。
おまけ
っといっても本当これだけだと中身みるだけで終わってしまいます。
vim
コマンド使えない…。なので
vim
コマンド使えるようにするためだけにDockerfile
を作ります。
vim
コマンド使えるのに参考にさせていただいたのは以下の記事です。
https://qiita.com/YumaInaura/items/3432cc3f8a8553e05a6eDockerfileFROM quantumobject/docker-cakephp RUN ["apt-get", "update"] RUN ["apt-get", "install", "-y", "vim"]で、その
Dockerfile
がある場所までいき、以下コマンドをうちimageを作成します。タグ名をcakephpaddvi
としています。$ docker build -t cakephpaddvi .とりあえずimageが出来てるか確認
$ docker images次にここでRUNしたいのですが、先ほど入っているものがあるとRUN出来ないので一回とめます。
起動確認 $ docker ps 起動確認で得たコンテナIDを使い止める $ docker stop <コンテナID>準備出来たので早速RUNします。先ほど上で出てきたコマンドのimagem名が変わっただけです。
あとは上で行ったように中に入ったり、もう編集もできると思うので編集して中をいじいじしてみてください(✿´ ꒳ ` )$ docker run -d -p 80 cakephpaddvi最後に
以上!終わりです!