20200123のdockerに関する記事は10件です。

Node.jsからFBX SDK Pythonを呼べるDockerイメージ作った

Node.jsからFBX SDK Pythonを呼べるDockerイメージ作った

とある事情により、Node.jsからFBX SDK Pythonを呼ぶ必要があったので、Dockerイメージを作りました。

作ったDockerイメージは以下に公開しました。
https://hub.docker.com/r/seguropus/fbx-sdk-python-nodejs

サンプルコード

サンプルコードを以下に置きます。
https://github.com/segurvita/docker-fbx-sdk-python-nodejs

サンプルコードの使い方

# Dockerイメージをビルド
docker-compose build

# Dockerコンテナを起動
docker-compose up

これで、以下のような表示が出れば成功です。

fbx-sdk-python-nodejs    | # FBX SDK can read the following formats.
fbx-sdk-python-nodejs    | 00 FBX (*.fbx)
fbx-sdk-python-nodejs    | 01 AutoCAD DXF (*.dxf)
fbx-sdk-python-nodejs    | 02 Alias OBJ (*.obj)
fbx-sdk-python-nodejs    | 03 3D Studio 3DS (*.3ds)
fbx-sdk-python-nodejs    | 04 Collada DAE (*.dae)
fbx-sdk-python-nodejs    | 05 Alembic ABC (*.abc)
fbx-sdk-python-nodejs    | 06 Biovision BVH (*.bvh)
fbx-sdk-python-nodejs    | 07 Motion Analysis HTR (*.htr)      
fbx-sdk-python-nodejs    | 08 Motion Analysis TRC (*.trc)      
fbx-sdk-python-nodejs    | 09 Acclaim ASF (*.asf)
fbx-sdk-python-nodejs    | 10 Acclaim AMC (*.amc)
fbx-sdk-python-nodejs    | 11 Vicon C3D (*.c3d)
fbx-sdk-python-nodejs    | 12 Adaptive Optics AOA (*.aoa)      
fbx-sdk-python-nodejs    | 13 Superfluo MCD (*.mcd)
fbx-sdk-python-nodejs    | 14 (*.zip)
fbx-sdk-python-nodejs exited with code 0

表示されているのは、FBX SDKが読み込み可能なファイル形式の一覧です。

これが表示されたということは、無事にFBX SDK Pythonにアクセスできているということになります。

何が起きてるのか?

まず、 docker-compose up でDockerコンテナーが起動します。

Dockerコンテナーは、起動したらNode.jsのコード index.js を実行します。

index.js はPythonのコード main.py を呼びます。

main.py はFBX SDK Pythonから対応フォーマット一覧を取得して、表示します。

Dockerfile

PythonとNode.jsが同居したDockerイメージを公開している方がいたので、そちらをもとに Dockerfile を作成してみました。

Dockerfile
# Python 2.7とNode.js 12が入ったAlpine
FROM nikolaik/python-nodejs:python2.7-nodejs12-alpine

# apkでライブラリ更新
RUN apk update && \
    apk add \
    curl \
    libxml2 \
    libstdc++

# FBX SDKをダウンロード
RUN curl -L \
    https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/20195/fbx20195_fbxpythonsdk_linux.tar.gz \
    -o /tmp/fbx20195_fbxpythonsdk_linux.tar.gz

# インストール先フォルダ作成
RUN mkdir -p /python-fbx/install

# FBX SDKを解凍
RUN tar -zxvf \
    /tmp/fbx20195_fbxpythonsdk_linux.tar.gz \
    -C /python-fbx && \
    printf "yes\nn" | \
    /python-fbx/fbx20195_fbxpythonsdk_linux \
    /python-fbx/install

# FBX SDKをインストール
RUN cp /python-fbx/install/lib/Python27_ucs4_x64/* \
    /usr/local/lib/python2.7/site-packages/

# python-shellをインストール
RUN npm install -g python-shell

# 一時ファイルを削除
RUN rm -r /python-fbx
RUN rm /tmp/fbx20195_fbxpythonsdk_linux.tar.gz

# 環境変数NODE_PATHを設定
ENV NODE_PATH /usr/local/lib/node_modules

python-shell というのは、Node.jsからPythonを呼ぶためのライブラリです。

グローバル領域にインストールしたので、index.jsが require で取得できるように、環境変数 NODE_PATH を設定しています。

docker-compose.yml

docker-compose.yml はこんな感じです。

docker-compose.yml
version: '3'
services:
  fbx-sdk-python-nodejs:
    image: 'seguropus/fbx-sdk-python-nodejs'
    container_name: 'fbx-sdk-python-nodejs'
    build:
      context: ./
      dockerfile: ./Dockerfile
    volumes:
      - .:/src
    working_dir: /src
    command: node index.js

Dockerコンテナー起動時に index.js が実行されます。

index.js

index.jsはこんな感じです。

index.js
const pythonShell = require('python-shell');

// python-shellのオプション
const pyOption = {
    mode: 'text',
    pythonPath: '/usr/local/bin/python',
    pythonOptions: ['-u'],
    scriptPath: '/src',
}

// main.pyを実行
const pyShell = new pythonShell.PythonShell('main.py', pyOption);

// Pythonの標準出力を表示
pyShell.on('message', (message) => {
    console.log(message);
});

// 終了処理
pyShell.end(function (err, code, signal) {
    if (err) {
        console.error(err);
    }
    console.log('The exit code was: ' + code);
});

python-shellmain.py を呼んでいます。

main.py

main.py はこんな感じです。

main.py
from fbx import *


def list_reader_format(manager):
    print('# FBX SDK can read the following formats.')
    for formatIndex in range(manager.GetIOPluginRegistry().GetReaderFormatCount()):
        description = manager.GetIOPluginRegistry().GetReaderFormatDescription(formatIndex)
        print(formatIndex, description)


def main():
    # Create
    manager = FbxManager.Create()
    scene = FbxScene.Create(manager, "fbxScene")

    # List
    list_reader_format(manager)

    # Destroy
    scene.Destroy()
    manager.Destroy()


if __name__ == '__main__':
    main()

from fbx import * でFBX SDK Pythonを読み込んでいます。
list_reader_format() という関数で、FBX SDK Pythonが読み込み可能なファイル形式の一覧を標準出力に表示しています。

無事にNode.jsからFBX SDK Pythonを呼べるDockerイメージを作ることができました!

Docker Hubに公開してみる

せっかくなので、Docker Hubに公開してみます。

# ログインする
docker login

# Dockerイメージをプッシュする
docker push seguropus/fbx-sdk-python-nodejs

以下に公開されました。
https://hub.docker.com/r/seguropus/fbx-sdk-python-nodejs

さいごに

本記事作成にあたり、以下のページを参考にしました。ありがとうございました。

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

【初学者向け】セキュリティ対策入門[番外編①]〜OSコマンドインジェクション編〜

前提

確認環境

以下と同様です。
【初学者向け】セキュリティ対策入門⓪〜環境構築編〜

本シリーズの目的

以下と同様です。
【初学者向け】セキュリティ対策入門⓪〜環境構築編〜

本記事の目標

OSコマンドインジェクションの概要、原因、対策について理解することです。

本記事を読み進める上での必要事項

以下の内容を終えていることです。
【初学者向け】セキュリティ対策入門⓪〜環境構築編〜

どうでもいいお話

あまり主要ではない脆弱性についてはこちらの番外編で扱っていきます。主要ではないというのは被害ケースをあまり耳にしないという意味で、脆弱性をつかれたときの被害が少ないというわけではないので悪しからず。

概要

OSコマンドについて不正な命令を入れ込むことです。こちらのSQLインジェクションがSQL文について不正な命令を入れ込むことならば、こちらはOSコマンドというわけです。

実際に見てみましょう。とはいえ、番外編なのでGitHubにソースはないので本記事上で紹介します。

実際に見てみよう

<?php

$file_list = shell_exec("ls {$_GET['param']}");
echo $file_list;

PHPファイルでOSコマンドを実行したい場合、shell_execという関数を使う必要があります。

では、実際にどういった場合に被害が発生するかというと、| {任意のOSコマンド}のような文字列をクエリストリングスのparamに与えられたときです。OSコマンドについて学んだことがある方なら、これのやばさが伝わると思います。自由なOSコマンドが使えれば任意のファイルを書き換えたり削除したり様々な被害をもたらすことが可能です。

めちゃくちゃ恐ろしいですね。

原因

入力値をそのままOSコマンドの一部に渡していることです。

対策

そもそも使わない

OSコマンドをユーザの入力で行わなければいけないケースというのはなかなかないはずです。あったとしてもライブラリを使用するなどの選択肢を検討する必要があります。

そもそも使わない観点では、php.iniで特定の関数を実行不可にできるので本対策を行う場合はそれも合わせて行った方がいいでしょう。

エスケープする

上述の通り、こういった処理は実装しないのが一番です。とはいえ、どうしても実装したい場合はエスケープする関数もあります。escapeshellargという関数です。具体的にすると以下のような感じです。

<?php

$param = escapeshellarg($_GET['param']);

$file_list = shell_exec("ls {$param}");
echo $file_list;

参考文献

独習PHP 第3版

今回の内容は以上です。最後までご覧いただきありがとうございました。

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

【初学者向け】セキュリティ対策入門[番外編]①〜OSコマンドインジェクション編〜

前提

確認環境

以下と同様です。
【初学者向け】セキュリティ対策入門⓪〜環境構築編〜

本シリーズの目的

以下と同様です。
【初学者向け】セキュリティ対策入門⓪〜環境構築編〜

本記事の目標

OSコマンドインジェクションの概要、原因、対策について理解することです。

本記事を読み進める上での必要事項

以下の内容を終えていることです。
【初学者向け】セキュリティ対策入門⓪〜環境構築編〜

どうでもいいお話

あまり主要ではない脆弱性についてはこちらの番外編で扱っていきます。主要ではないというのは被害ケースをあまり耳にしないという意味で、脆弱性をつかれたときの被害が少ないというわけではないので悪しからず。

概要

OSコマンドについて不正な命令を入れ込むことです。こちらのSQLインジェクションがSQL文について不正な命令を入れ込むことならば、こちらはOSコマンドというわけです。

実際に見てみましょう。とはいえ、番外編なのでGitHubにソースはないので本記事上で紹介します。

実際に見てみよう

<?php

$file_list = shell_exec("ls {$_GET['param']}");
echo $file_list;

PHPファイルでOSコマンドを実行したい場合、shell_execという関数を使う必要があります。

では、実際にどういった場合に被害が発生するかというと、| {任意のOSコマンド}のような文字列をクエリストリングスのparamに与えられたときです。OSコマンドについて学んだことがある方なら、これのやばさが伝わると思います。自由なOSコマンドが使えれば任意のファイルを書き換えたり削除したり様々な被害をもたらすことが可能です。

めちゃくちゃ恐ろしいですね。

原因

入力値をそのままOSコマンドの一部に渡していることです。

対策

そもそも使わない

OSコマンドをユーザの入力で行わなければいけないケースというのはなかなかないはずです。あったとしてもライブラリを使用するなどの選択肢を検討する必要があります。

そもそも使わない観点では、php.iniで特定の関数を実行不可にできるので本対策を行う場合はそれも合わせて行った方がいいでしょう。

エスケープする

上述の通り、こういった処理は実装しないのが一番です。とはいえ、どうしても実装したい場合はエスケープする関数もあります。escapeshellargという関数です。具体的にすると以下のような感じです。

<?php

$param = escapeshellarg($_GET['param']);

$file_list = shell_exec("ls {$param}");
echo $file_list;

参考文献

独習PHP 第3版

今回の内容は以上です。最後までご覧いただきありがとうございました。

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

DjangoアプリをDocker上に構築しAWS Fargateにデプロイする

はじめに

AI、機械学習やビッグデータ解析などでPythonが注目されています。
Pythonを用いたウェブアプリケーションが今後増加することが予測される中、PythonのフレームワークであるDjangoを用いてアプリを作成し、AWS Fargateにコンテナでデプロイをするまでの一連の流れを毎日投稿していきます。

所属しているFintechスタートアップでの開発経験からDjango+Docker+AWS Fargateの構成は
1)学習コストが低い
2)共同開発しやすい
3)スケールしやすい
という特徴があり、個人やスタートアップによるwebアプリケーション開発のベストプラクティスであると考えています。

項目毎に細切れに投稿していくので詳細については各投稿を参照してください。
日々記事を投稿しそのリンクを本ページに追加していくので、本ページは目次として使ってください。

目次

1.なぜ今、Pythonなのか
2.Djangoについて
3.Dockerについて
 (1)DockerでHello,World
4.Docker上でDjangoアプリケーションを動かす
 (1)Pipenvを用いた仮想環境上でDjangoを起動する
5.PostgresSQL
6.アプリケーションの作成
 (1)Custom User
 (2)URLs
 (3)Views
 (4)認証機能
 (5)環境変数
7.Emailの設定
8.ファイルのアップロード
9.権限
10.検索
11.Perfomance
12.セキュリティ
13.デプロイ

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

DockerでHello,World

はじめに

DockerをインストールしてHello,Worldを表示させます。
OSはMacを使用します。

Docker for Macのインストール

DockerをインストールするためにDocker Hubで無料のアカウントを作成します。アカウントを作成後した後、下記リンクからDocker for Macをダウンロード、その後インストールします。

・Docker for Mac

インストール後 --versionでバーションが表示されればインストール成功。

$ docker --version

DockerでHello,World

“Hello, World” image を使用します。Dockerのテストrunに便利なイメージです。ターミナルでdocker run hello-wordを実行すると公式のDocker imageがコンテナにダウンロードされ、イメージが実行されます。

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:9572f7cdcc2963463447a53466950bc15a2d1917ca215a2f
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/

コンテナの情報を確認する

docker infoコマンドでDockerの情報が確認できます。

$ docker info
...
Server:
 Containers: 1
  Running: 0
  Paused: 0
  Stopped: 1
 Images: 1
...

これでDockerがインストールされ無事に起動したことが確認できました。

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

Alpineベースのimageにruby2.2.3を入れる

本当はalpine-rubyをベースにするべきなんだろうけど諸事情でJava系のベースにする必要があったので、rbenvを自力で入れて構築することにしました。

出来上がったDockerfileはこちら。

FROM openjdk:8-jdk-alpine

RUN apk update && \
    apk upgrade && \
    apk add --update --no-cache \
    bash \
    vim \
    curl \
    tzdata

RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apk del tzdata

RUN echo "http://dl-cdn.alpinelinux.org/alpine/v3.8/main" >> /etc/apk/repositories
RUN apk update && \
    apk upgrade && \
    apk add --update --no-cache --virtual=.build-dependencies \
    build-base \
    git \
    gcc \
    readline-dev \
    openssl-dev=1.0.2u-r0   \
    zlib-dev \
    libffi-dev

ENV PATH /usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH
ENV RBENV_ROOT /usr/local/rbenv
ENV CONFIGURE_OPTS "--disable-install-doc"

RUN git clone https://github.com/sstephenson/rbenv.git ${RBENV_ROOT} && \
    git clone https://github.com/sstephenson/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \
    ${RBENV_ROOT}/plugins/ruby-build/install.sh
RUN echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> /etc/profile.d/rbenv.sh && \
    echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh

RUN rbenv install 2.2.3 && \
    rbenv global 2.2.3

COPY Gemfile .
COPY Gemfile.lock .

RUN gem install -N bundler -v 1.16.2
RUN bundle install -j4 && \
    rm -rf /usr/local/bundle/cache/*.gem

RUN apk del .build-dependencies

大きな障害はは以下のようにopensslの1.0を取得することでした。

v3.8から1.0系のopensslを取得する

素直にapk add opensslでライブラリを入れるとrbenv install時に以下のようなエラーが発生する。

BUILD FAILED (Alpine Linux 3.9.4 using ruby-build 20200115-8-g73b926b)

Inspect or clean up the working tree at /tmp/ruby-build.20200123165940.26.gjbJCo
Results logged to /tmp/ruby-build.20200123165940.26.log

Last 10 log lines:
                              power_assert-0.2.2.gem
                              minitest-5.4.3.gem
installing rdoc:              /usr/local/rbenv/versions/2.2.3/share/ri/2.2.0/system
installing capi-docs:         /usr/local/rbenv/versions/2.2.3/share/doc/ruby
The Ruby openssl extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Configure options used:
  --prefix=/usr/local/rbenv/versions/2.2.3
  LDFLAGS=-L/usr/local/rbenv/versions/2.2.3/lib 
  CPPFLAGS=-I/usr/local/rbenv/versions/2.2.3/include 

エラーの原因としては、ruby2.4以下の場合はopenssl1.1系に対応していないため、openssl1.0を入れる必要があるからでした。
rbenv/ruby-build

The openssl extension of Ruby version before 2.4 is not compatible with OpenSSL 1.1.x.

ubuntuベースのimageで構築するならこちらの記事で言及されているように有志が開発したパッチを当てれば動きますが、alpineの場合は自力で1.0系を入れる必要があります。

現在openjdk:8-jdk-alpineではデフォルトでv3.9のリポジトリを参照しているが、v3.9ではopensslは1.1系の提供になっています。
こちらで調べると1.0系の取得には1つ前のv3.8のリポジトリから取得が必要のようです。
https://pkgs.alpinelinux.org/packages?name=openssl&branch=v3.8&repo=main

そこでapkから取得する前に参照先にv3.8のリポジトリを追加して上げる必要があります。

RUN echo "http://dl-cdn.alpinelinux.org/alpine/v3.8/main" >> /etc/apk/repositories

追加後にopenssl-dev=1.0.2u-r0とバージョンを指定することで1.0系のopensslを取得することができます。

また当初はgem install時にThe Ruby openssl extension was not compiled. Missing the OpenSSL lib?エラーが発生していたが、修正前のDockerfikeでlibssl1.0を入れていたことが原因でした。
おそらくssl系のライブラリ同士でバッティングしていたっぽい?

rbenvの前はruby-installを使用して軽量化を図っていましたが、上と同じOpenSSLのエラーがどうしても解消できなかったので諦めることに…
ruby-installで上手く行けば多分もう少し軽くできそう。

RUN wget -O - https://github.com/postmodern/ruby-install/archive/v0.7.0.tar.gz | tar xzvf - && \
    ( cd ruby-install-0.7.0 && \
      make install ) && \
    rm -rf ruby-install-*
RUN ruby-install --system --cleanup ruby 2.2.3

その他細かいポイントなど

docker軽量化系の記事では散々言及されているようなことですが、軽くまとめると
- ビルドに必要のないパッケージは残したくないので.build-dependenciesでまとめて最後の行で一括で削除しています。
- ENV CONFIGURE_OPTS "--disable-install-doc"を指定することで不要なドキュメントをインストールしないようにしています
- bundle install時にrm -rf /usr/local/bundle/cache/*.gemでgemのキャッシュを消すようにしています

今どき2.2.3を使うことはあまりないと思いますが、備忘録として残しておこうと思います。

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

Dockerでよく使うコマンド

Dockerでよく使うコマンド

下記サイトを参考に自分が見やすいように表にしました。(内容はほぼそのままです。ごめん)
Dockerでよく使うコマンド12個のメモ | Simple is Beautiful.

機能 コマンド 備考
イメージ一覧 docker images
コンテナの稼働状況確認 docker ps 停止中のコンテナも表示するには-aオプション
コンテナを起動する docker run イメージID 例)docker run 0f9d87ea4bbb
ポートを指定して起動 docker run -p 8888:5000 イメージID 5000番を8888番としている
コンテナを停止 docker stop コンテナID 例)docker stop 6572058effff
docker内に入ってコマンドを打つ docker exec -it コンテナID /bin/bash ※/bin/shの方がよいかも?
起動中のコンテナの情報を見る docker inspect コンテナID 例)docker inspect 6572058effff
例)渡されている環境変数を調べる docker inspect 6572058effff | jq '.[].Config.Env'
例)どのイメージ起動したか調べる docker inspect 6572058effff | jq '.[].Image'
コンテナのステータス docker stats コンテナID コンテナは複数指定可
コンテナなどの容量を調べる docker system df
ログ(最終100行を表示 docker logs コンテナ名 例)docker logs –tail 100 コンテナ名
Dockerfileでイメージ作成 docker build -t kozakana/test .
使われていないイメージを削除 docker system prune

docker system dfの出力例

TYPE            TOTAL           ACTIVE          SIZE           RECLAIMABLE
Images          17              1               5.884GB        4.311GB (73%)
Containers      1               1               90.82MB        0B (0%)
Local Volumes   11              0               1.038GB        1.038GB (100%)
Build Cache     0               0               0B             0B

docker statsの出力例

# docker stats 23f89c33eeee d7efc910b555
CONTAINER ID   NAME          CPU %   MEM USAGE / LIMIT     MEM %    NET I/O           BLOCK I/O       PIDS
23f89c33eeee   container00   0.00%   672KiB / 1.954GiB     0.03%    30.2kB / 25.4kB   4.63MB / 0B     0
d7efc910b555   container01   0.01%   344.2MiB / 1.954GiB   17.20%   134MB / 1.87MB    468MB / 5.62GB  0
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerで入れたPostgreSQLへのPDO接続でエラーが出て悩んだ。

出たエラー

こんにちは、Docker初心者です。
なんならMySQLばっかりだったのでPostgreSQLも初です(汗)

タイトルのままです。
docker-compose.ymlで入れたPostgreSQLへのPDO接続をしようとしたら、
下のようなエラーが出てしまったンゴです。

error.
 SQLSTATE[08006] [7] could not translate host name "postgres" to address: Name or service not known 

ちなみに書いていたPDOはこんな感じです。

property.php
try {
    $pdo_connect = new PDO( 'pgsql:host=postgres; dbname={name};', '{user}', '{dbname}' );  
} catch(PDOException $e) {
    var_dump($e->getMessage());
}

解決

問題はdocker-compose.ymlとPDOの両方にありました。ymlファイルはこちら。
コメントアウトで間違ってる点書いてます。

docker-compose.yml
  postgres-db:
  #なんと、この postgres-db がHOST名になるらしい。知らなかった。PDOほhostを変える必要あり。
   image: postgres:8.4
   environment:
    POSTGRES_ROOT_PASSWORD: root
    POSTGRES_USER: user
    POSTGRES_PASSWORD: dbname
    POSTGRES_DATABASE: db #これ、本当は POSTGRES_DB: db と書かないといけない。
    TZ: Asia/Tokyo
   hostname: postgres #HOSTがおかしいのかと思ってあとから付け加えたもの。いらない。
   ports:
    - 6001:5432

修正後

property.php
try {
    $pdo_connect = new PDO( 'pgsql:host=postgres-db; dbname={name};', '{user}', '{dbname}' );   
} catch(PDOException $e) {
    var_dump($e->getMessage());
}
docker-compose.yml
  postgres-db:
   image: postgres:8.4
   environment:
    POSTGRES_ROOT_PASSWORD: root
    POSTGRES_USER: user
    POSTGRES_PASSWORD: dbname
    POSTGRES_DB: db
    TZ: Asia/Tokyo
   ports:
    - 6001:5432

接続完了!
パイセンに感謝です。

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

WSL1でDocker使いたい

WSL1でDocker使いたい

理由?
WSLでDocker for windowsを使うッ!!! - Qiita
この記事に触発されたから。俺もやってみようと思った。

あと、うまくいったらテスト環境でLinuxベースのやつさくさく切り替えられそうだしね。

Windows側の操作

WindowsにDockerインストール

普通にインストール

WSLからWindowsのDockerを呼び出す設定

  1. タスクバーのdockerアイコン右クリックして、Settingクリック
  2. Generalの見出しの「Expose deamon on~~」のチェックを入れてOK。

これで、tcp://localhost:2375/でDockerが待ち受けしてくれるようになる。

画面は閉じないで、次の手順へ!!

DockerがCドライブをマウントする設定

  1. 同じ画面のResources>FileSharingをクリック
  2. 画面右にドライブレターが表示されるので、CにへっくいれてOK

画面はもう少しそのまま。閉じないで!!

DockerのProxyとDNS設定

DockerはWindows標準とは別に独自のProxyとDNSの設定を持っている。
なので、クローズドな環境の場合はこちらも設定する。

  1. 同じ画面のProxiesをクリックすると、右側に設定画面が表示される。環境にあわせて変更。
  2. 同様にNetworkをクリックすると右側にDNSの切り替えスイッチとアドレス設定がでてくる。
  3. いっそ、ONにしてIPを「8.8.8.8」にした方が軽快に使える場合もあるが、まぁ、環境とご相談で。

WSL側の操作

dockerのインストール

dockerインストール
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install docker
$ sudo apt install docker-compose

Cドライブのマウント場所の変更

標準だと/mnt/cになって使いにくいので変更する。

/etc/wsl.conf
[automount]
root = "/"  

動作確認

いったん、DockerもWSLも一度再起動しとく(なんか不具合よく起きたのでお文じない)
再起動したのを確認したら、動作確認。

バージョン確認
$ docker version
Client:
 Version:           18.09.7
~~ 略 ~~
Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
~~ 略 ~~

エンジンバージョンがWindowsと一致している。

hello-run
$ docker run hello-world

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

~~ 略 ~~

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

今日はここまでできたので満足!!

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

SpringBootでグループウェアの開発③〜DB接続の続き〜

DB接続の続き

前回でDB接続をして、新規登録まで作ろうとしたのですが、そこまでいかなかったので続きをやっていきます!

とりあえずここまでビルド&実行できるか確認

build.gradleを編集した際に自動でクラスパスの読み込みをするかのダイアログが右下に出てきたので、自動で読み込む設定にしました。
虫マークのデバッグメニューを開くと、初めてのデバッグの場合はlaunch.jsonを作るボタンがあるので、launch.jsonを作成する。
デバッグメニューでDemoAppcationから始められるので、デバッグをスタートします!
image.png
image.png
とりあえず実行は出来た。

MyBatisでマッピング

jpaとかの選択肢もあるけど、SQLを書く現場の方が多そうだからMyBatisでマッピングすることにした。

build.gradle

build.gradleのdependencies内に以下を追加。mybatisはバージョン指定しないと読み込んでくれないので、mvnrepositoryで希望するバージョンを調べて指定する。今回は2.1.1。

implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.1'

マッパー作成

UserMapper.java
package パッケージ名.プロジェクト名.domain.repository;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import rsrepo.groupware.mygroupware.domain.model.User;

@Mapper
public interface UserMapper {
    // 登録用メソッド
    @Insert("INSERT INTO users ( name, password, role ) VALUES ( #{name}, #{password}, #{role} )")
    public boolean insert(User user);

    // 1件検索用メソッド
    @Select("SELECT id, name, password, role, updated_at FROM users WHERE name = #{name} AND password = #{password}")
    public User selectOne(String userId);

    // 全件検索用メソッド
    @Select("SELECT id, name, password, role, updated_at FROM users")
    public List<User> selectMany();

    // 1件更新用メソッド
    @Update("UPDATE users SET name = #{name}, password = #{password}, role = #{role} WHERE id = #{id}")
    public boolean updateOne(User user);

    // 1件削除用メソッド
    @Delete("DELETE FROM users WHERE id = #{id}")
    public boolean deleteOne(String userId);
}

サービスの作成

UserService.java
package パッケージ名.プロジェクト名.domain.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import rsrepo.groupware.mygroupware.domain.model.User;
import rsrepo.groupware.mygroupware.domain.repository.UserMapper;

@Transactional
@Service
public class UserService {
    @Autowired
    UserMapper userMapper;

    // 登録用メソッド
    public boolean insert(User user) {
        return userMapper.insert(user);
    }

    // 1件検索用メソッド
    public User selectOne(String id) {
        return userMapper.selectOne(id);
    }

    // 全件検索用メソッド
    public List<User> selectMany() {
        return userMapper.selectMany();
    }

    // 1件更新用メソッド
    public boolean update(User user) {
        return userMapper.updateOne(user);
    }

    // 1件削除用メソッド
    public boolean delete(String id) {
        return userMapper.deleteOne(id);
    }
}

コントローラーを作成

UserController.java
package パッケージ名.プロジェクト名.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import rsrepo.groupware.mygroupware.domain.model.User;
import rsrepo.groupware.mygroupware.domain.service.UserService;

@RestController
public class UserController {
    @Autowired
    UserService service;

    // ユーザー全件取得
    @GetMapping("/user/get")
    public List<User> getUserMany() {
        // ユーザー全件取得
        return service.selectMany();
    }

    // ユーザー1件取得
    @GetMapping("/user/get/{id}")
    public User getUserOne(@PathVariable("id") String userId) {
        // ユーザー1件取得
        return service.selectOne(userId);
    }

    // ユーザーを1件登録
    @PostMapping("/user/insert")
    public String putUserOne(@RequestBody User user) {
        boolean result = service.insert(user);
        String str = "";
        if (result) {
            str = "{\"result\":\"ok\"}";
        } else {
            str = "{\"result\":\"error\"}";
        }
        // 結果用の文字列をリターン
        return str;
    }

    // ユーザーを1件更新
    @PutMapping("/user/update")
    public String postUserOne(@RequestBody User user) {
        boolean result = service.update(user);
        String str = "";
        if (result) {
            str = "{\"result\":\"ok\"}";
        } else {
            str = "{\"result\":\"error\"}";
        }
        // 結果用の文字列をリターン
        return str;
    }

    // ユーザーを1件削除
    @DeleteMapping("/user/delete/{id:.+}")
    public String deleteUserOne(@PathVariable("id") String userId) {
        boolean result = service.delete(userId);
        String str = "";
        if (result) {
            str = "{\"result\":\"ok\"}";
        } else {
            str = "{\"result\":\"error\"}";
        }
        // 結果用の文字列をリターン
        return str;
    }
}

接続確認

DockerのMySQLを起動してテストデータを入れる。

INSERT INTO users ( name, password, role ) VALUES ( "test", "test", "ROLE_ADMIN" );

SpringBootを実行→http://localhost:8080/user/getにアクセス。

[{"id":"1","name":"test","password":"test","role":"ROLE_ADMIN","updated_at":"2020-01-22T12:17:56.000+0000"}]

jsonでデータが返される。

終わりに

やっとDB接続が完了したので、次回はログイン機能を完成させる事を目標に進めていこうと思います!
SpringBootでグループウェアの開発②〜DB接続〜
SpringBootでグループウェアの開発④〜ログイン機能の実装〜
GitHub:MyGroupware

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