Proxy環境下でdocker toolbox + docker-compseを使えるようにする(windows7)
やること
普段はMac+Docker for Macの環境でアプリ開発を行っているのですが、会社内のプロキシネットワーク下+Windows7の環境でDockerを使えるようにする設定です。
Docker Toolboxのインストール
公式サイトからダウンロードしてインストールします。
Docker Quickstart Terminal というソフトウェアもインストールされるので実行するとターミナルが開きます。以降の作業はこのターミナルで行います。
Dockerプロジェクトの作成(docker-compose)
以下ファイルを作成して適当な作業ディレクトリに配置します。
docker-compose.yml
hello: image: hello-world:latest
NOプロキシ設定と動作確認
以下NO_PROXY設定をexportします。小文字が大事!
$ export no_proxy=192.168.99.100
docker-compose up コマンドで hello_1 | Hello from Docker! が表示されたら成功です。
$ cd ${docker-compose.ymlを置いたディレクトリ} $ docker-compose up
プロキシ設定は既に設定済みの前提なので最終形は以下のようになります。
※自身のプロキシサーバーが設定されていることを確認してください。
$ env | grep proxy http_proxy=http://login:plainpassword@proxy.corp.com:8000 https_proxy=http://login:plainpassword@proxy.corp.com:8000 no_proxy=192.168.99.100
はまったところ
DockerToolboxインストール後にターミナルでdocker psを打つと Forbiddenになりました。
$ docker ps error during connect: Get https://192.168.99.100:2376/v1.33/containers/json: Forbidden
ネットで探すとNO_PROXYの設定でいけるとのことで設定するとうまくいきました。
$ export NO_PROXY=192.168.99.100 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
しかし、docker-compose は繋がりません。
$ docker-compose --verbose up (省略) requests.exceptions.ProxyError: HTTPSConnectionPool(host='192.168.99.100', port= 2376): Max retries exceeded with url: /v1.21/version (Caused by ProxyError('Cann ot connect to proxy.', error('Tunnel connection failed: 403 Forbidden',))) Failed to execute script docker-compose
小一時間悩んだ後、小文字にしたらいけました。。。
まとめ
docker toolbox:windows の no_proxy は、dockerコマンドは大文字でもOKですが、docker-composeは小文字じゃないとダメ!
※バージョンに依存する問題なのかもしれません。以下のバージョンを利用する際は参考にしてみてください。
$ docker-compose.exe -v docker-compose version 1.16.1, build 6d1ac219 $ docker -v Docker version 17.10.0-ce, build f4ffd25
SpringBoot+Gradleで別rootのプロジェクトへ依存関係をつけたビルド構成にする
やること
開発中のプロダクトで以下のようなgit repository上の構成にしたかったのですが、gradleがサポートしているmulti projectの構成だとうまいやり方がみつからなかったので以下のような方法で対応してみました。
- A: サーバー共通処理やドメインモデルをまとめたレポジトリ
- B: 個別の業務処理を行うサーバーのソースを格納したレポジトリでAに依存
- C: 個別の業務処理を行うサーバーのソースを格納したレポジトリでAに依存
Gradle multi project についてはこちら
以下リンクに公式の説明があります
第57章 マルチプロジェクトのビルド
フラット階層だと以下のような構成になるイメージです。
GitRoot | |-root | |--build.gradle | |--settings.gradle |-appA |-appB
やり方
Gradle設定ファイルの編集
以下の構成の前提です。 各プロジェクトのひな形はSPRING INITIALIZRで作っておきます。(ParentProjectは単独で起動させないのでのBoot用Javaソースは削除)
ChildProject |--build.gradle |--settings.gradle ParentProject |--build.gradle
子プロジェクト側の設定に以下を追加します。
- settings.gradleに以下記載(なければ新規作成してください)
include ':ParentProject' project(':ParentProject').projectDir = new File('../ParentProject')
- build.gradleに以下記載
dependencies { compile project(':ParentProject') }
親プロジェクト側の設定に以下を追加します。
- build.gradleに以下記載
springBoot { mainClass = "org.gradle.sample.Scan" }
Javaクラスの作成
親プロジェクト側にComponentScanのエントリーポイントになるクラスを用意します。 DI対象のクラスはこの下に配置します。
ParentProject |--src.xx |--Application.java |--service |--SampleService.java
Application.java
@ComponentScan public class Application { }
SampleService.java
@Component public class SampleService { @PostConstruct public void test() { System.out.print("DI success!"); } }
動作確認
ChildProjectを起動します。
cd ${ChildProjectのルートディレクトリ} ./gradlew bootRun
"DI success!"が表示されれば成功です。
コンドル -ゴルフ練習場検索サイト-
都内のゴルフ練習場の混雑状況がわかる検索サイトです。
ゴルフ練習場をお探しの際はご利用ください!
VSCodeでJavaプログラム(SpringBoot)のデバッグ
bitcoindからのメッセージをZeroMQ経由(+SpringBoot)で購読する
やること
bitcoindにはJSON-RPC以外にZeroMQを介したメッセージ購読ができるようになっていますが、これをSpringBootアプリケーション上にサンプル実装します。
ZeroMQの実装ライブラリとしてjeromqを使用します。
GitHub - zeromq/jeromq: Pure Java ZeroMQ
公式ドキュメント
bitcoin/zmq.md at master · bitcoin/bitcoin · GitHub
開発環境
- Windows10
- Java8
bitcoindのインストールと起動
公式サイトからインストーラをダウンロードしてインストールします。
ダウンロード - ビットコイン設定ファイル作成して適当なディレクトリに配置します。
bitcoin.confregtest=1 server=1 rpcuser=username rpcpassword=password zmqpubrawblock=tcp://127.0.0.1:28332 zmqpubhashblock=tcp://127.0.0.1:28332 zmqpubrawtx=tcp://127.0.0.1:28332 zmqpubhashtx=tcp://127.0.0.1:28332
実装の確認をするだけなので regtest 環境で起動させます。
bitcoindを起動します。
$ cd ${bitcoin intall dir}/daemon $ ./bitcoind.exe -conf=/path/to/bitcoin.conf
SpringBootアプリケーションの作成
Spirng Initializr等で作成したテンプレートプロジェクトにjeromqライブラリを追加します。
build.gradle
dependencies { compile('org.springframework.boot:spring-boot-starter-web') compile group: 'org.zeromq', name: 'jeromq', version: '0.4.2' }
zmqクライアント部分は公式のpython実装を参考に作成します。
https://github.com/bitcoin/bitcoin/tree/master/contrib/zmq
購読対象のメッセージを設定しないと受信できないので、追加する場合はsubscribeメソッドを呼んでください(コメントアウトの部分)。
bitcoindは以下4種類のメッセージをサポートしています。
socket.subscribe("hashtx"); // transactionのハッシュ値 socket.subscribe("hashblock"); // blockのハッシュ値 socket.subscribe("rawblock"); // blockの生データ socket.subscribe("rawtx"); // transactionの生データ
BitcondZmqClient.java
@Slf4j @Component public class BitcondZmqClient { private static final String url = "tcp://127.0.0.1:28332"; @PostConstruct private void init() { ExecutorService executor = Executors.newFixedThreadPool(1); Runnable runner = this::connectZmqServer; executor.execute(runner); } private void connectZmqServer() { ZMQ.Context context = ZMQ.context(1); ZMQ.Socket socket = context.socket(ZMQ.SUB); socket.connect(url); socket.subscribe("rawblock"); // socket.subscribe("hashblock"); // socket.subscribe("rawtx"); // socket.subscribe("hashtx"); log.info("connect to " + url); while (!Thread.currentThread().isInterrupted()) { String topic = socket.recvStr(); log.info("client - topic:" + topic); if (socket.hasReceiveMore()) { // byte[] body = socket.recv(); String body = socket.recvStr(); switch (topic) { case "rawblock": log.info("client - body:" + body); break; default: break; } } if (socket.hasReceiveMore()) { String sequence = socket.recvStr(); log.info("client - sequence:" + sequence); } } socket.close(); context.term(); } }
ComponentScan対象になるように@SpringBootApplication配下のディレクトリに配置してください。
メインの業務処理とは分けられるように別スレッドでZmqClientを起動しています。
ZeroMQ経由のメッセージ購読確認
SpringBootアプリケーションを起動します。
regtest環境とbitcoin-cliコマンドを使ってブロックをマイニングします。
$ cd ${bitcoin intall dir}/daemon $ ./bitcoin-cli.exe -conf=/path/to/bitcoin.conf generate 1
ログにブロックの情報が表示されれば成功です。
memo
トランザクション情報もメッセージを変えることで購読できるので試してみてください。
regtest環境を初期構築した後はマイニング報酬を得るのに100ブロック掘る必要があるので sendtoaddress コマンド実行時にお金が足りないと表示される場合には generate 100 で100ブロックを掘ってみてください。
Werckerを使ってGithubへのreleaseとJarアップロードを自動化する
やること
SpringBootでプロジェクトを開発する際に共通で使う機能などをライブラリ化して参照できるようにしたい。
プロジェクトの依存関係で解決してもいいですが、共通ライブラリが肥大化するような場合だとローカルビルドが面倒なので今回はJar化したものを配布することにします。
Wercker設定ファイルの編集
前回の続きから
公式ドキュメントにリリースとアップロードの手順があるのでこれを参考にします。
GitHub - wercker/step-github-create-release: wercker step for deploying to GitHub releases
GitHub - wercker/step-github-upload-asset: A wercker step for adding an asset to a GitHub release.
wercker.yml に以下のdeployワークフローを追加します。
deploy: steps: - script: name: get version code: | VERSION=`grep ^version build.gradle | awk -F\' '{print $2}'` - github-create-release: token: $GITHUB_TOKEN tag: $VERSION - github-upload-asset: token: $GITHUB_TOKEN file: build/libs/appname-${VERSION}.jar content-type: application/zip
Jarの名前はbuild.gradleから設定できるので以下をbuild.gradleに追加してください。
versionは適当にbuild.gradleからgrepしてます。
jar.baseName = 'appname' version = '0.0.1-SNAPSHOT'
Weckerの設定変更
Pipeline追加
WebページへログインしワークフローのメニューからAdd New Pipelineを選択します。
YML Pipeline nameにwercker.ymlで設定したdeployを入力してcreateを押します。
ワークフローに先ほど追加したdeployを繋げます。
Githubトークンの取得
WerckerからGithubへpushするのにGithubトークンが必要なので作成します。
GithubのWebページへ行って以下のリンクで設定画面を開きます。
Settings→Developer settings→Personal access tokens
Generate new tokenを選択して、新規トークンを作成します。
今回はpublicレポジトリを使うのでpublic_repoのみにチェックをいれます。
トークンが生成されたらコピーしておきます。
Githubトークン設定
Environmentのページを開いてValueに先ほどコピーしたトークンを設定します。
keyはGITHUB_TOKENとしてください。
Wercker実行確認
最初に設定したwercker.ymlをPUSHすると自動的にweckerも実行されます。
deployのpipelineが正常に実行され、githubのreleasesにJarがアップロードされていれば成功です。
参照側プロジェクトの設定
build.gradleに以下を追加
def urlFile = { url, name -> File file = new File("$buildDir/libs/${name}.jar") file.parentFile.mkdirs() if (!file.exists()) { new URL(url).withInputStream { downloadStream -> file.withOutputStream { fileOut -> fileOut << downloadStream } } } files(file.absolutePath) } dependencies { compile urlFile('https://github.com/nakanoya150151/siw/releases/download/0.0.1/siw-0.0.1-SNAPSHOT.jar?raw=true', 'siw') }
とりあえずこれで連携できますが、Mavenレポジトリを立てたほうがきれいですね。。。
Jar化も含めてやってくれるWebサービスもあるようです。
上のjitpackを紹介していた記事
JitPack.ioでGitHub上のJavaプロジェクトを簡単にライブラリとして参照する · tehepero note(・ω<) 2.0
課題
毎回のPUSHでreleasesを作成しようとしてしまうので制御できるように修正予定です。。。
Springboot+GradleのアプリケーションをWercker/Codecov連携する
やること
SpringBoot+Gradleで作ったアプリケーションをWercker/Codecovと連携させてCI環境を作ります。
Wercker : ビルド・デプロイ環境を提供するCIサービスです。類似のサービスにCircleCIやTravisCIがありますが無料で使える枠が大きいのとDockerイメージが使えるので今回はこれをビルド環境に使ってみます。
http://www.wercker.com/Codecov : テストカバレッジを計測するCIサービスです。テストレポート作成にはJacocoというライブラリを使います。類似のサービスにはcoverallsがありますが、codecovを勧める記事が多かったので今回はこれを使ってみました。
https://codecov.io/gh
実行環境
- Windows10
- Java8
Wercker環境構築
準備
SPRING INITIALIZR等を使って適当なSpringBootアプリケーションを作成します。
https://start.spring.io/
レポジトリを作成したらGithub上にPushしておきます。
アカウント作成
Githubアカウントを使ってwerckerアカウントを作成します。
https://app.wercker.com/sessions/new
先ほどのレポジトリを選択してください。
定義ファイル作成
公式ドキュメントのガイドに従ってwercker.ymlを作成します(プロジェクトルートに配置)。
http://devcenter.wercker.com/docs/quickstarts/building/java
wercker.yml
# docker box definition box: id: openjdk ports: - "8080" # Build definition build: # The steps that will be executed on build steps: # A step that executes `gradle build` command - script: name: run gradle code: | chmod +x ./gradlew ./gradlew --full-stacktrace -q --project-cache-dir=$WERCKER_CACHE_DIR build
chmod
を追加していますが、なしで実行したところPermissionErrorが発生したので追加しています。
wercker.ymlをPUSHするとwercker上でビルドが実行されます。
Codecov環境構築
準備
Jacocoを使用するのでbuild.gradleに以下の記述を追加します。 デフォルトのjacocoTestReportタスクだとレポートがhtml形式なのでタスクを定義してXML形式で出力します。
apply plugin: 'jacoco' task codeCoverageReport(type: JacocoReport) { executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec") reports { xml.enabled true xml.destination "${buildDir}/reports/jacoco/report.xml" html.enabled false csv.enabled false } classDirectories = fileTree(dir: './build/classes/main') sourceDirectories = files('src/main/java') }
Codecovアカウント作成
Werckerと同じようにGithubアカウントを使用してアカウント作成・レポジトリ連携を設定します。 完了画面でトークンが表示されるのでコピーしておいてください。 画面を閉じてしまった場合はレポジトリの画面からSettingsへ飛ぶと確認できたはずです。
定義ファイル更新
codecov用の定義を追加します。CODECOV_TOKENにはトークンを設定してください。
# docker box definition box: id: openjdk ports: - "8080" # defining the dev pipeline dev: steps: # A step that executes `gradle bootRun` command - script: name: run gradle code: | ./gradlew bootRun # Build definition build: # The steps that will be executed on build steps: # A step that executes `gradle build` command - script: name: run gradle code: | chmod +x ./gradlew ./gradlew --full-stacktrace -q --project-cache-dir=$WERCKER_CACHE_DIR build ./gradlew codeCoverageReport - script: name: post coverage to codecov code: | CODECOV_TOKEN={ここにトークンをペースト} bash <(curl -s https://codecov.io/bash) -t $CODECOV_TOKEN
wercker.ymlをPUSHするとwercker上でビルドが実行され、レポートがcodecovに連携されカバレッジレポートが表示されます。
以上です。