20210608のdockerに関する記事は18件です。

SharePoint Framework 1.12.1 を Docker を使って開発したい

Docker を使って開発しようかなと思って環境を作ってみたら、debugBasePath の設定がきかなくなっていました。 めんどくさそうなので、一度諦めましたが、やっぱり気になったのでとりあえず動くところまでやってみました。 ちなみにWebパーツしか試していません。 コンテナ起動 毎度ながら、お世話になっている DockerFile を利用させていただきます。 ありがとうございます。 https://github.com/waldekmastykarz/docker-spfx PowerShell docker run -it --rm --name [コンテナ名] -v [プロジェクトディレクトリ]:/usr/app/spfx -p 5432:5432 -p 4321:4321 -p 35729:35729 waldekm/spfx:1.12.1 gulp インストール と Webパーツプロジェクトの作成 Docker spfx@5a38d4c15994:/usr/app/spfx$ npm install gulp npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies. npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. npm WARN saveError ENOENT: no such file or directory, open '/usr/app/spfx/package.json' npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules/chokidar/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN enoent ENOENT: no such file or directory, open '/usr/app/spfx/package.json' npm WARN spfx No description npm WARN spfx No repository field. npm WARN spfx No README data npm WARN spfx No license field. + gulp@4.0.2 added 326 packages from 226 contributors and audited 327 packages in 25.004s 7 packages are looking for funding run `npm fund` for details found 3 vulnerabilities (1 low, 2 moderate) run `npm audit fix` to fix them, or `npm audit` for details spfx@5a38d4c15994:/usr/app/spfx$ yo @microsoft/sharepoint --package-manager npm ? ========================================================================== We're constantly looking for ways to make yo better! May we anonymously report usage statistics to improve the tool over time? More info: https://github.com/yeoman/insight & http://yeoman.io ========================================================================== No _-----_ | | .--------------------------. |--(o)--| | Welcome to the | `---------´ | SharePoint Client-side | ( _´U`_ ) | Solution | /___A___\ | Generator@1.12.1 | | ~ | '--------------------------' __'.___.'__ ´ ` |° ´ Y ` The npm package manager will be used. Let's create a new SharePoint solution. ? What is your solution name? spfx ? Which baseline packages do you want to target for your component(s)? SharePoint Online only (latest) ? Where do you want to place the files? Use the current folder Found npm version 6.14.13 ? Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites? No ? Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant? No ? Which type of client-side component to create? WebPart Add new Web part to solution spfx. ? What is your Web part name? HelloWorld ? What is your Web part description? HelloWorld description ? Which framework would you like to use? React create package.json create config/package-solution.json create config/config.json create config/serve.json create gulpfile.js create tsconfig.json create .vscode/extensions.json create .vscode/launch.json create .vscode/settings.json create config/copy-assets.json create config/deploy-azure-storage.json create config/write-manifests.json create src/index.ts create README.md create .gitignore create tslint.json create src/webparts/helloWorld/components/IHelloWorldProps.ts create src/webparts/helloWorld/components/HelloWorld.module.scss create src/webparts/helloWorld/components/HelloWorld.tsx create src/webparts/helloWorld/HelloWorldWebPart.ts create src/webparts/helloWorld/loc/en-us.js create src/webparts/helloWorld/loc/mystrings.d.ts create src/webparts/helloWorld/HelloWorldWebPart.manifest.json create teams/e8018470-f2d3-4f37-8844-cd33966374c7_outline.png create teams/e8018470-f2d3-4f37-8844-cd33966374c7_color.png npm WARN deprecated tslint@6.1.3: TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information. npm WARN deprecated @types/anymatch@3.0.0: This is a stub types definition. anymatch provides its own type definitions, so you do not need this installed. npm WARN deprecated gulp-util@3.0.8: gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5 npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated left-pad@1.3.0: use String.prototype.padStart() npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 npm WARN deprecated har-validator@5.1.5: this library is no longer supported npm WARN deprecated fsevents@2.1.3: "Please update to latest v2.3 or v2.2" > deasync@0.1.21 install /usr/app/spfx/node_modules/deasync > node ./build.js `linux-x64-node-14` exists; testing Binary is fine; exiting > node-sass@4.14.1 install /usr/app/spfx/node_modules/node-sass > node scripts/install.js Cached binary found at /home/spfx/.npm/node-sass/4.14.1/linux-x64-83_binding.node > keytar@7.7.0 install /usr/app/spfx/node_modules/keytar > prebuild-install || npm run build > node-sass@4.14.1 postinstall /usr/app/spfx/node_modules/node-sass > node scripts/build.js Binary found at /usr/app/spfx/node_modules/node-sass/vendor/linux-x64-83/binding.node Testing binary Binary is fine npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^2.1.2 (node_modules/jest-haste-map/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.1 (node_modules/watchpack/node_modules/chokidar/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules/@rushstack/typings-generator/node_modules/chokidar/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN ajv-keywords@3.5.2 requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) added 1955 packages from 1037 contributors and audited 2288 packages in 264.269s 97 packages are looking for funding run `npm fund` for details found 218 vulnerabilities (54 low, 143 moderate, 21 high) run `npm audit fix` to fix them, or `npm audit` for details _=+#####! ###########| .-----------------------------------. ###/ (##|(@) | Congratulations! | ### ######| \ | Solution spfx is created. | ###/ /###| (@) | Run gulp serve to play with it! | ####### ##| / '-----------------------------------' ### /##|(@) ###########| **=+####! 以下のファイルを編集 config/serve.json hostnameを追加 { "$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json", "port": 4321, "hostname": "0.0.0.0", "https": true, "initialPage": "https://localhost:5432/workbench", "api": { "port": 5432, "entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/" } } config/write-manifests.json debugBasePathを追加 { "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json", "cdnBasePath": "<!-- PATH TO CDN -->", "debugBasePath": "https://localhost:4321" } WebpackConfigurationGenerator.js 場所 \node_modules\@microsoft\spfx-heft-plugins\lib\plugins\webpackConfigurationPlugin\WebpackConfigurationGenerator.js 変更内容 Before 369行目から402行目の変更前 let serveConfig = {}; try { serveConfig = await node_core_library_1.JsonFile.loadAsync(path.join(options.folders.buildFolder, 'config', 'serve.json')); } catch (e) { // Do nothing. } const debugBaseUrl = `${serveConfig.https ? 'https' : 'http'}://${serveConfig.hostname || 'localhost'}:${serveConfig.port || 4321}/dist/`; let cdnBaseUrl; try { const writeManifestsConfig = await node_core_library_1.JsonFile.loadAsync(path.join(options.folders.buildFolder, 'config', 'write-manifests.json')); cdnBaseUrl = writeManifestsConfig.cdnBasePath; } catch (e) { // Do nothing. } config.plugins.push(new ManifestPlugin_1.ManifestPlugin({ terminal, selectedLocales, sourceLocaleName: constants_1.DEFAULT_LOCALE, bundleEntries: bundleEntries, internalModuleBaseUrls: cdnBaseUrl ? [cdnBaseUrl] : [], debugInternalModuleBaseUrls: [debugBaseUrl], linkedExternals: linkedExternals, referencedProjects: referencedProjects, cumulativeManifestProcessor: cumulativeManifestProcessor, translatedStrings: localizedData, releaseDropPath: options.folders.releaseFolder, asyncOnlyDependencies: { asyncOnlyDependencyNames: options.configJson.asyncComponents || [], violationsAsErrors: options.production }, componentDependenciesAuditDropPath: path.join(options.folders.releaseFolder, 'component-dependency-audit', `${path.basename(options.folders.buildFolder)}.json`) })); After 369行目から404行目変更後 let serveConfig = {}; try { serveConfig = await node_core_library_1.JsonFile.loadAsync(path.join(options.folders.buildFolder, 'config', 'serve.json')); } catch (e) { // Do nothing. } const debugBaseUrl = `${serveConfig.https ? 'https' : 'http'}://${serveConfig.hostname || 'localhost'}:${serveConfig.port || 4321}/dist/`; let cdnBaseUrl; let debugBasePath; try { const writeManifestsConfig = await node_core_library_1.JsonFile.loadAsync(path.join(options.folders.buildFolder, 'config', 'write-manifests.json')); cdnBaseUrl = writeManifestsConfig.cdnBasePath; debugBasePath = writeManifestsConfig.debugBasePath; } catch (e) { // Do nothing. } config.plugins.push(new ManifestPlugin_1.ManifestPlugin({ terminal, selectedLocales, sourceLocaleName: constants_1.DEFAULT_LOCALE, bundleEntries: bundleEntries, internalModuleBaseUrls: cdnBaseUrl ? [cdnBaseUrl] : [], debugInternalModuleBaseUrls: debugBasePath ? [`${debugBasePath}/dist/`] : [debugBaseUrl], linkedExternals: linkedExternals, referencedProjects: referencedProjects, cumulativeManifestProcessor: cumulativeManifestProcessor, translatedStrings: localizedData, releaseDropPath: options.folders.releaseFolder, asyncOnlyDependencies: { asyncOnlyDependencyNames: options.configJson.asyncComponents || [], violationsAsErrors: options.production }, componentDependenciesAuditDropPath: path.join(options.folders.releaseFolder, 'component-dependency-audit', `${path.basename(options.folders.buildFolder)}.json`) })); gulp serve (serve-deprecated) でデバッグ とりあえず動きます。 パッケージにして展開 展開しても動きます。 感想 良い勉強になりました。 とりあえず動かせましたが、ここまでして Docker 使わなくてもいい気もします。 もっといい方法があれば教えてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【shellscript】コマンドライン引数取り扱いメモ

shellscriptのコマンドライン引数の取り扱いについて、 備忘録としてまとめておく test.sh ################### # 一番目の引数を取得 ################### arg_one=$1 echo "一番目の引数を取得" echo $arg_one ################### # 引数をすべて取得 ################### args_ex=$@ echo "引数をすべて取得 " echo $args_ex ##################### # 2番目以降の引数を取得 ##################### args_ex2=${@:2} echo "2番目以降の引数を取得" echo $args_ex2 ######################## # 2番目以降の引数を3つ取得 ######################## args_ex3=${@:2:3} echo "2番目以降の引数を3つ取得" echo $args_ex3 ########################### # 引数をすべてを配列として取得 ########################### args_array=("${@}") echo "引数をすべてを配列として取得" for args_value in ${args_array[@]}; do echo $args_value done 実行テスト $ sh test-args.sh a b c d e # 実行結果 一番目の引数を取得 a 引数をすべて取得 a b c d e 2番目以降の引数を取得 b c d e 2番目以降の引数を3つ取得 b c d 引数をすべてを配列として取得 a b c d e
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【sql】case式の使い方を実際に動かして理解する

はじめに case式を利用するとsql内でカラムの条件分岐を行えるらしい。 今回はsqlのcase式の学習のためにpostgresのコンテナ環境を利用して実際に実行し、理解を深める。 前準備 postgresテスト環境の構築 # postgresコンテナ環境を起動 $ docker run -i --rm -d\ --name psql_test \ -p 15433:5432 \ -v postgres-tmp:/var/lib/postgresql/data \ -e POSTGRES_HOST_AUTH_METHOD=trust \ postgres:13.3-alpine ## postgresコンテナにログイン $ docker exec -it psql_test sh テストデータの投入 CREATE DATABASE test_local; \c test_local; CREATE TABLE PERSON( name varchar(20), age integer ); INSERT INTO PERSON VALUES ('a', 20); INSERT INTO PERSON VALUES ('b', 10); INSERT INTO PERSON VALUES ('c', 15); INSERT INTO PERSON VALUES ('d', 30); INSERT INTO PERSON VALUES ('e', 40); -- データ確認 select * from person; test_local=# select * from person; -- 結果 a | 20 b | 10 c | 15 d | 30 e | 40 実験 case式はプログラミングで言うif文ようなもの。 書式は以下の通り CASE WHEN [条件式1] THEN [条件式1が正のときの処理] ELSE [条件式1が負のときの処理] END 例 年齢が20以上なら成人、20歳未満なら未成年と表示する SELECT *, CASE WHEN age >= 20 THEN '成人' ELSE '未成年' END FROM person; -- 結果 -- a | 20 | 成人 b | 10 | 未成年 c | 15 | 未成年 d | 30 | 成人 e | 40 | 成人
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker build時に複数のタグを付け、複数のタグを一度にpushする

docker の build 時に複数のタグを付ける BASE=xxx/yyy TAG1=${BASE}:v2 TAG2=${BASE}:v2.1 TAG3=${BASE}:latest # -t を複数追加します docker build . -t ${TAG1} -t ${TAG2} -t ${TAG3} docker の push 時に複数のタグを一度に送信する BASE=xxx/yyy # -a を付けます # -a が無い場合、デフォルトタグの「latest」が自動で設定されます docker push -a ${BASE}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

x86マシンでARM用dockerコンテナを実行する方法

通常、docker上で動作するコンテナはホストのCPUアーキテクチャと一致する必要がある。 例えばx86用コンテナはx86マシンでしか動かないし、ARM用コンテナはARMマシンでしか動かない。 しかし、x86上でARMコンテナをビルドしたい場合もでてくる。 そこでQEMUというCPUエミュレータを使用すると異なるCPUアーキのコンテナを動作させることができる。 QEMUの準備 以下のようにQEMUをインストールして、設定をおこなう。 sudo apt-get install qemu binfmt-support qemu-user-static docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes Dockerへの設定 コンテナ内に/usr/bin/qemu-aarch64-staticを配置することでARMコンテナをx86で実行することができる。 以下の二通りの実現方法があるので、目的に合わせて使用する。 1. docker runで使用する場合 -vオプションを使用してqemu-aarch64-staticをコンテナ内にマッピングする。 docker run -it --rm -v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static image_name 2. Dockerfileで使用する場合 事前にqemu-aarch64-staticをカレントディレクトリ(Dockerfileと同じ場所)にcopyしておく。 cp /usr/bin/qemu-aarch64-static . Dockerfile内でCOPYコマンドでcopyする。注意点としてはRUNコマンドよりも前にCOPYが実行されるようにすること。 COPY ./qemu-aarch64-static /usr/bin/qemu-aarch64-static # RUN コマンドの前にCOPYする RUN command_hogehoge 注意点 CPUエミュレータを使ってARMバイナリを随時x86に翻訳しているため、プロジェクトのビルドなどを実行するととても重くなるため注意 あくまでもapt等でパッケージをインストールするだけという利用法が無難 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React 公式チュートリアルを TypeScript + Hooks でリファクタリング

はじめに React を基礎から勉強する。最近の React は Hooks を用いることでクラスコンポーネントを扱わなくても開発ができるという耳障りのいい言葉を受け取った状態で React 公式チュートリアルを眺めてみると、なんとクラスコンポーネントを使っている。(チュートリアルのソースコードは数年以上更新されていないらしい。) クラスコンポーネントなんて触りたくないとチュートリアルを敬遠していたのだが、基礎が疎かで目も当てられない状態だったので割り切って一通り試してみた。たしかにわかりやすかったが、流行りの Hooks などは使用されていないので、TypeScript + Hooks という流行りについていけるようにリファクタリングを行った。 Hooks + TypeScriptでReact公式チュートリアルをリファクタ、Reactのチュートリアルをhooks + TypeScriptでモダンな仕様にリファクタしてみたを参考にした。 React + TypeScript 環境の導入 ローカルに開発環境を入れたくないので Docker コンテナで実行環境を作成する。概要はDocker 開発環境構築 (WSL2 + VSCode)を参照。VSCode が提供している Node.js & TypeScript のサンプルを元に作成した devcontainer.json および Dockerfile は以下。 devcontainer.json // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: // https://github.com/microsoft/vscode-dev-containers/tree/v0.177.0/containers/typescript-node { "name": "Node.js & TypeScript", "build": { "dockerfile": "Dockerfile", // Update 'VARIANT' to pick a Node version: 12, 14, 16 "args": { "VARIANT": "16" } }, // Set *default* container specific settings.json values on container create. "settings": { "editor.formatOnSave": true, "editor.tabSize": 2, "editor.wordWrap": "on", // "terminal.integrated.shell.linux": "/bin/bash" }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ "formulahendry.auto-close-tag", "formulahendry.auto-rename-tag", "mrmlnc.vscode-duplicate", "dsznajder.es7-react-js-snippets", "dbaeumer.vscode-eslint", "eamodio.gitlens", "xabikos.javascriptsnippets", "esbenp.prettier-vscode", "shardulm94.trailing-spaces", "msjsdiag.debugger-for-chrome", "visualstudioexptteam.vscodeintellicode", ], // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "yarn install", // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "node" } Dockerfile ARG VARIANT="16-buster" FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT} 公式チュートリアルのコード準備 上記をビルドして VSCode 上で接続する。問題なく接続できたら、VSCode 上のターミナルにて、npx create-react-app my-app --typescript を実行。作成された my-app/src 内のファイルをすべて削除して新たに index.css と index.tsx を作成し、それぞれに公式チュートリアルに載っている以下コードをコピペする。 index.css body { font: 14px "Century Gothic", Futura, sans-serif; margin: 20px; } ol, ul { padding-left: 30px; } .board-row:after { clear: both; content: ""; display: table; } .status { margin-bottom: 10px; } .square { background: #fff; border: 1px solid #999; float: left; font-size: 24px; font-weight: bold; line-height: 34px; height: 34px; margin-right: -1px; margin-top: -1px; padding: 0; text-align: center; width: 34px; } .square:focus { outline: none; } .kbd-navigation .square:focus { background: #ddd; } .game { display: flex; flex-direction: row; } .game-info { margin-left: 20px; } index.tsx import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; function Square(props) { return ( <button className="square" onClick={props.onClick}> {props.value} </button> ); } class Board extends React.Component { renderSquare(i) { return ( <Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} /> ); } render() { return ( <div> <div className="board-row"> {this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)} </div> <div className="board-row"> {this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)} </div> <div className="board-row"> {this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)} </div> </div> ); } } class Game extends React.Component { constructor(props) { super(props); this.state = { history: [ { squares: Array(9).fill(null) } ], stepNumber: 0, xIsNext: true }; } handleClick(i) { const history = this.state.history.slice(0, this.state.stepNumber + 1); const current = history[history.length - 1]; const squares = current.squares.slice(); if (calculateWinner(squares) || squares[i]) { return; } squares[i] = this.state.xIsNext ? "X" : "O"; this.setState({ history: history.concat([ { squares: squares } ]), stepNumber: history.length, xIsNext: !this.state.xIsNext }); } jumpTo(step) { this.setState({ stepNumber: step, xIsNext: (step % 2) === 0 }); } render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares); const moves = history.map((step, move) => { const desc = move ? 'Go to move #' + move : 'Go to game start'; return ( <li key={move}> <button onClick={() => this.jumpTo(move)}>{desc}</button> </li> ); }); let status; if (winner) { status = "Winner: " + winner; } else { status = "Next player: " + (this.state.xIsNext ? "X" : "O"); } return ( <div className="game"> <div className="game-board"> <Board squares={current.squares} onClick={i => this.handleClick(i)} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); } } // ======================================== ReactDOM.render(<Game />, document.getElementById("root")); function calculateWinner(squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a]; } } return null; } TypeScript 形式へのリファクタリング 上記の準備を終えた状態だと、index.tsx にて多くのエラーが吐かれているので順に修正していく。 typescript, @types/react まず yarn add typescript で typescript をインストールする。次に import React from "react"; で以下のようなエラーが出ているのを修正する。 Could not find a declaration file for module ‘react’. ... TypeScript に対応した React となっていないことが(たぶん)原因と思われる。エラーコードに書いてあるように npm i --save-dev @types/react を実行することで解消できる。(コンテナのビルド時にあらかじめこのあたりを解消できるように Dockerfile を修正したかったが、パッとできなかったのでわかる方教えて下さい。) リファクタリング 「はじめに」に載せたサイトを参考にリファクタリングをした。TypeScript の特徴である「静的型付け」や 「React Hooks」 の基本的な知識は、TypeScript: Documentation - Everyday Types や React.js&Next.js超入門 第2版で事前に勉強した。 以下にリファクタリング後のコードを載せた。もともと1つのファイルで構成されていたものをコンポーネントごとに分け、以下のようなディレクトリ構成になっている。 src ├── components │   ├── Board.tsx │   ├── Game.tsx │   └── Square.tsx ├── index.css ├── index.tsx └── interface.ts 各ファイルのコードは以下。(index.css は変更していないため省略。) index.tsx import ReactDOM from "react-dom"; import './index.css'; import Game from "./components/Game"; ReactDOM.render(<Game />, document.getElementById("root")); interface.ts export type ISquare = "X" | "O" | null; export type History = { squares: ISquare[]; position: number; }; components/Square.tsx import React from "react"; import {ISquare} from "../interface"; interface SquareProps { value: ISquare; onClick: () => void; } const Square: React.FC<SquareProps> = ({value, onClick}) => { return ( <button className="square" onClick={onClick}> {value} </button> ); } export default Square; components/Board.tsx import React from "react"; import {ISquare} from "../interface"; import Square from "./Square"; interface BoardProps { squares: ISquare[]; onClick: (i: number) => void; } const Board: React.FC<BoardProps> = ({squares, onClick}) => { const renderSquare = (i: number) => { return ( <Square value={squares[i]} onClick={() => onClick(i)} /> ); } return ( <div> <div className="board-row"> {renderSquare(0)} {renderSquare(1)} {renderSquare(2)} </div> <div className="board-row"> {renderSquare(3)} {renderSquare(4)} {renderSquare(5)} </div> <div className="board-row"> {renderSquare(6)} {renderSquare(7)} {renderSquare(8)} </div> </div> ); } export default Board; components/Game.tsx import React, {useState} from "react"; import {ISquare, History} from "../interface"; import Board from "./Board"; const Game: React.FC = () => { const [history, setHistory] = useState<History[]>([{squares: Array(9).fill(null), position: -1}]); const [stepNumber, setStepNumber] = useState<number>(0); const [xIsNext, setXIsNext] = useState<boolean>(true); const handleClick = (i: number) => { const _history = history.slice(0, stepNumber + 1); const current = _history[_history.length - 1]; const squares = current.squares.slice(); if (calculateWinner(squares) || squares[i]) { return; } squares[i] = xIsNext ? "X" : "O"; setHistory(_history.concat([{squares: squares, position: i}])); setStepNumber(_history.length) setXIsNext(!xIsNext); } const jumpTo = (step: number) => { setStepNumber(step); setXIsNext((step % 2) === 0); } const current = history[stepNumber]; const winner = calculateWinner(current.squares); const moves = history.map(({squares, position}, move) => { const x = position % 3 + 1; const y = Math.floor(position / 3) + 1; const desc = move ? 'Go to move #' + move + ` (${x}, ${y})`: 'Go to game start'; return ( <li key={move}> <button onClick={() => jumpTo(move)}>{desc}</button> </li> ); }); let status; if (winner) { status = "Winner: " + winner; } else { status = "Next player: " + (xIsNext ? "X" : "O"); } return ( <div className="game"> <div className="game-board"> <Board squares={current.squares} onClick={(i: number) => handleClick(i)} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); } const calculateWinner = (squares: Array<ISquare>) => { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a]; } } return null; } export default Game; 上記で問題なく、チュートリアルアプリが動く。 おわりに TypeScript + Hooks でのリファクタリングをした。かなり参考サイトにおんぶにだっこな状態で進めたので、自身の理解を深めるべくチュートリアル末尾に記載されている改良のアイデアを試そうと思う。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2にdockerをインストールする

dockerをインストールします。 ec2-userをdockerグループに参加させます。 sudo yum install docker sudo usermod -aG docker ec2-user シェルからログアウトします。 次のコマンドを実行します。 sudo service docker start Post-installation steps for Linux | Docker Documentation
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Prometheus] Postgres Exporter with Docker

概要 Prometheusでの、PostgreSQLのメトリクス収集用のPostgres ExporterのDocker環境構築手順。 前提条件 以下の手順でPrometheus環境を構築していることを前提とする。 https://qiita.com/Esfahan/items/0feaedfd771f49ac7ee4 Postgres exporter こちらを利用する。 https://github.com/prometheus-community/postgres_exporter 環境 postgres_exporter v0.9.0 PostgreSQL 9.6 監視対象のPostgresの設定 pg_stat_statementsの有効化 以下を参考にpg_stat_statementsを有効化する。 参考:https://qiita.com/Esfahan/items/2f0c5ad85671d435f209 もしpg_stat_statementsを有効化しない場合は、次項の「メトリクス収集用ユーザーの作成」で、CREATE OR REPLACE VIEW postgres_exporter.pg_stat_statementsの箇所を実行せずにskipする。 メトリクス収集用ユーザーの作成 defaultでは like pg_stat_statements や pg_stat_activity はsuperuser以外では参照できない。もしsuperuser以外でメトリクス収集する場合は、以下を実行する。 以下の例ではpostgres_exporterという名前のメトリクス収集用のユーザーを作成する。 パスワードは、ALTER USER postgres_exporter WITH PASSWORD 'password';で設定しているので、パスワード値を適宜変更する。 参考:https://github.com/prometheus-community/postgres_exporter#running-as-non-superuser -- To use IF statements, hence to be able to check if the user exists before -- attempting creation, we need to switch to procedural SQL (PL/pgSQL) -- instead of standard SQL. -- More: https://www.postgresql.org/docs/9.3/plpgsql-overview.html -- To preserve compatibility with <9.0, DO blocks are not used; instead, -- a function is created and dropped. CREATE OR REPLACE FUNCTION __tmp_create_user() returns void as $$ BEGIN IF NOT EXISTS ( SELECT -- SELECT list can stay empty for this FROM pg_catalog.pg_user WHERE usename = 'postgres_exporter') THEN CREATE USER postgres_exporter; END IF; END; $$ language plpgsql; SELECT __tmp_create_user(); DROP FUNCTION __tmp_create_user(); -- passwordを適宜変更 ALTER USER postgres_exporter WITH PASSWORD 'password'; ALTER USER postgres_exporter SET SEARCH_PATH TO postgres_exporter,pg_catalog; -- If deploying as non-superuser (for example in AWS RDS), uncomment the GRANT -- line below and replace <MASTER_USER> with your root user. -- GRANT postgres_exporter TO <MASTER_USER>; CREATE SCHEMA IF NOT EXISTS postgres_exporter; GRANT USAGE ON SCHEMA postgres_exporter TO postgres_exporter; GRANT CONNECT ON DATABASE postgres TO postgres_exporter; CREATE OR REPLACE FUNCTION get_pg_stat_activity() RETURNS SETOF pg_stat_activity AS $$ SELECT * FROM pg_catalog.pg_stat_activity; $$ LANGUAGE sql VOLATILE SECURITY DEFINER; CREATE OR REPLACE VIEW postgres_exporter.pg_stat_activity AS SELECT * from get_pg_stat_activity(); GRANT SELECT ON postgres_exporter.pg_stat_activity TO postgres_exporter; CREATE OR REPLACE FUNCTION get_pg_stat_replication() RETURNS SETOF pg_stat_replication AS $$ SELECT * FROM pg_catalog.pg_stat_replication; $$ LANGUAGE sql VOLATILE SECURITY DEFINER; CREATE OR REPLACE VIEW postgres_exporter.pg_stat_replication AS SELECT * FROM get_pg_stat_replication(); GRANT SELECT ON postgres_exporter.pg_stat_replication TO postgres_exporter; CREATE OR REPLACE FUNCTION get_pg_stat_statements() RETURNS SETOF pg_stat_statements AS $$ SELECT * FROM public.pg_stat_statements; $$ LANGUAGE sql VOLATILE SECURITY DEFINER; -- pg_stat_statementsを利用しない場合は以降は実行しない CREATE OR REPLACE VIEW postgres_exporter.pg_stat_statements AS SELECT * FROM get_pg_stat_statements(); GRANT SELECT ON postgres_exporter.pg_stat_statements TO postgres_exporter; 作成されたものなど確認 psql -U postgres_exporter -W -d postgres postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+------------------------------ postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =Tc/postgres + | | | | | postgres=CTc/postgres + | | | | | postgres_exporter=c/postgres template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows) postgres=# \dn List of schemas Name | Owner -------------------+---------- postgres_exporter | postgres public | postgres (2 rows) postgres=# \du List of roles Role name | Attributes | Member of -------------------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} postgres_exporter | | {} postgres=> \d List of relations Schema | Name | Type | Owner -------------------+---------------------+------+---------- postgres_exporter | pg_stat_activity | view | postgres postgres_exporter | pg_stat_replication | view | postgres postgres_exporter | pg_stat_statements | view | postgres (3 rows) Postgres Exporterの環境構築 docker-compose.yaml version: '3' services: postgres-exporter: container_name: postgres-exporter image: quay.io/prometheuscommunity/postgres-exporter hostname: postgres-exporter env_file: - .env ports: - 9187:9187 .env DATA_SOURCE_NAME="postgresql://postgres_exporter:password@sample-postgres:5432/postgres?sslmode=disable" $ docker-compose up -d --build Prometheusの設定 こちらの記事で構築したPrometheus環境の設定ファイルを編集する。 監視対象を追加 prometheus/node.yaml - labels: env: development targets: # 監視対象のPostgresのホスト名:9187を追記する - your-postgres-exporter-hostname:9187 ルールを追加 /etc/prometheus/alert.rules groups: - name: sample001 rules: # Postgres用のルールを追記 - alert: Postgres_down # Postgresが起動しているかのPromQL。 expr: pg_up == 0 # 5分間応答がなければアラートを飛ばす for: 5m labels: severity: critical # エラー文言 annotations: firing_text: "[{{ $labels.env }}] {{ $labels.instance }} PostgreSQL has been down for more than 5 minutes." resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} PostgreSQL has recoverd." UI確認 http://your_prometeus.com:9090/graph pg_up == 1であればpostgresが正常に起動しているということ。0が異常状態。 その他 Error: function pg_current_wal_lsn() does not exist pg_current_wal_lsn() はpostgres 10以降に実装された関数なので、9系ではエラーが出る。 $ docker logs -f postgres-exporter time="2021-06-07T17:51:16Z" level=info msg="Error running query on database \"sample-postgres:5432\": pg_replication_slots pq: function pg_current_wal_lsn() does not exist" source="postgres_exporter.go:1503" 2021/03/04にIssueが上がっており、対応してくれそうなので待ち。 https://github.com/prometheus-community/postgres_exporter/issues/495 関連記事 Prometheus MySQL Exporter with Docker Prometheus, Grafana, AlertMamager, Exporter with Docker
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Prometheus Postgres Exporter with Docker

概要 Prometheusでの、PostgreSQLのメトリクス収集用のPostgres ExporterのDocker環境構築手順。 前提条件 以下の手順でPrometheus環境を構築していることを前提とする。 https://qiita.com/Esfahan/items/0feaedfd771f49ac7ee4 Postgres exporter こちらを利用する。 https://github.com/prometheus-community/postgres_exporter 環境 postgres_exporter v0.9.0 PostgreSQL 9.6 監視対象のPostgresの設定 pg_stat_statementsの有効化 以下を参考にpg_stat_statementsを有効化する。 参考:https://qiita.com/Esfahan/items/2f0c5ad85671d435f209 もしpg_stat_statementsを有効化しない場合は、次項の「メトリクス収集用ユーザーの作成」で、CREATE OR REPLACE VIEW postgres_exporter.pg_stat_statementsの箇所を実行せずにskipする。 メトリクス収集用ユーザーの作成 defaultでは like pg_stat_statements や pg_stat_activity はsuperuser以外では参照できない。もしsuperuser以外でメトリクス収集する場合は、以下を実行する。 以下の例ではpostgres_exporterという名前のメトリクス収集用のユーザーを作成する。 パスワードは、ALTER USER postgres_exporter WITH PASSWORD 'password';で設定しているので、パスワード値を適宜変更する。 参考:https://github.com/prometheus-community/postgres_exporter#running-as-non-superuser -- To use IF statements, hence to be able to check if the user exists before -- attempting creation, we need to switch to procedural SQL (PL/pgSQL) -- instead of standard SQL. -- More: https://www.postgresql.org/docs/9.3/plpgsql-overview.html -- To preserve compatibility with <9.0, DO blocks are not used; instead, -- a function is created and dropped. CREATE OR REPLACE FUNCTION __tmp_create_user() returns void as $$ BEGIN IF NOT EXISTS ( SELECT -- SELECT list can stay empty for this FROM pg_catalog.pg_user WHERE usename = 'postgres_exporter') THEN CREATE USER postgres_exporter; END IF; END; $$ language plpgsql; SELECT __tmp_create_user(); DROP FUNCTION __tmp_create_user(); -- passwordを適宜変更 ALTER USER postgres_exporter WITH PASSWORD 'password'; ALTER USER postgres_exporter SET SEARCH_PATH TO postgres_exporter,pg_catalog; -- If deploying as non-superuser (for example in AWS RDS), uncomment the GRANT -- line below and replace <MASTER_USER> with your root user. -- GRANT postgres_exporter TO <MASTER_USER>; CREATE SCHEMA IF NOT EXISTS postgres_exporter; GRANT USAGE ON SCHEMA postgres_exporter TO postgres_exporter; GRANT CONNECT ON DATABASE postgres TO postgres_exporter; CREATE OR REPLACE FUNCTION get_pg_stat_activity() RETURNS SETOF pg_stat_activity AS $$ SELECT * FROM pg_catalog.pg_stat_activity; $$ LANGUAGE sql VOLATILE SECURITY DEFINER; CREATE OR REPLACE VIEW postgres_exporter.pg_stat_activity AS SELECT * from get_pg_stat_activity(); GRANT SELECT ON postgres_exporter.pg_stat_activity TO postgres_exporter; CREATE OR REPLACE FUNCTION get_pg_stat_replication() RETURNS SETOF pg_stat_replication AS $$ SELECT * FROM pg_catalog.pg_stat_replication; $$ LANGUAGE sql VOLATILE SECURITY DEFINER; CREATE OR REPLACE VIEW postgres_exporter.pg_stat_replication AS SELECT * FROM get_pg_stat_replication(); GRANT SELECT ON postgres_exporter.pg_stat_replication TO postgres_exporter; CREATE OR REPLACE FUNCTION get_pg_stat_statements() RETURNS SETOF pg_stat_statements AS $$ SELECT * FROM public.pg_stat_statements; $$ LANGUAGE sql VOLATILE SECURITY DEFINER; -- pg_stat_statementsを利用しない場合は以降は実行しない CREATE OR REPLACE VIEW postgres_exporter.pg_stat_statements AS SELECT * FROM get_pg_stat_statements(); GRANT SELECT ON postgres_exporter.pg_stat_statements TO postgres_exporter; 作成されたものなど確認 psql -U postgres_exporter -W -d postgres postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+------------------------------ postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =Tc/postgres + | | | | | postgres=CTc/postgres + | | | | | postgres_exporter=c/postgres template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows) postgres=# \dn List of schemas Name | Owner -------------------+---------- postgres_exporter | postgres public | postgres (2 rows) postgres=# \du List of roles Role name | Attributes | Member of -------------------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} postgres_exporter | | {} postgres=> \d List of relations Schema | Name | Type | Owner -------------------+---------------------+------+---------- postgres_exporter | pg_stat_activity | view | postgres postgres_exporter | pg_stat_replication | view | postgres postgres_exporter | pg_stat_statements | view | postgres (3 rows) Postgres Exporterの環境構築 docker-compose.yaml version: '3' services: postgres-exporter: container_name: postgres-exporter image: quay.io/prometheuscommunity/postgres-exporter hostname: postgres-exporter env_file: - .env ports: - 9187:9187 .env DATA_SOURCE_NAME="postgresql://postgres_exporter:password@sample-postgres:5432/postgres?sslmode=disable" $ docker-compose up -d --build Prometheusの設定 こちらの記事で構築したPrometheus環境の設定ファイルを編集する。 監視対象を追加 prometheus/node.yaml - labels: env: development targets: # 監視対象のPostgresのホスト名:9187を追記する - your-postgres-exporter-hostname:9187 ルールを追加 /etc/prometheus/alert.rules groups: - name: sample001 rules: # Postgres用のルールを追記 - alert: Postgres_down # Postgresが起動しているかのPromQL。 expr: pg_up == 0 # 5分間応答がなければアラートを飛ばす for: 5m labels: severity: critical # エラー文言 annotations: firing_text: "[{{ $labels.env }}] {{ $labels.instance }} PostgreSQL has been down for more than 5 minutes." resolved_text: "[{{ $labels.env }}] {{ $labels.instance }} PostgreSQL has recoverd." UI確認 http://your_prometeus.com:9090/graph pg_up == 1であればpostgresが正常に起動しているということ。0が異常状態。 その他 Error: function pg_current_wal_lsn() does not exist pg_current_wal_lsn() はpostgres 10以降に実装された関数なので、9系ではエラーが出る。 $ docker logs -f postgres-exporter time="2021-06-07T17:51:16Z" level=info msg="Error running query on database \"sample-postgres:5432\": pg_replication_slots pq: function pg_current_wal_lsn() does not exist" source="postgres_exporter.go:1503" 2021/03/04にIssueが上がっており、対応してくれそうなので待ち。 https://github.com/prometheus-community/postgres_exporter/issues/495 関連記事 Prometheus MySQL Exporter with Docker Prometheus, Grafana, AlertMamager, Exporter with Docker
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[備忘録]Docker for Mac(M1)で急にビルドできなくなった。

ビルドできない また,Dockerでビルドができなくなりました. 以前は,Docker for Windowsでビルドができなくなりました. その際の記事は以下になります. 今回は,Macでビルドできなくなりました. 新しいM1 Macなので仕方ないと思いますが,解決したので備忘録として残します. エラー 以下のようにビルドを実行すると... docker build -f ./Dockerfile -t test . このようなエラーが出ました... failed to solve with frontend dockerfile.v0: failed to create LLB definition: failed to do request: Head https://registry-1.docker.io/v2/library/ubuntu/manifests/18.04: proxyconnect tcp: dial tcp 192.168.65.1:3128: i/o timeout 解決方法 !本解決方法は,Factory reset(初期化)を行うので,自己責任で実行してください! コンテナやイメージが消去されます. 1.右上のbugマークをクリックし,Troubleshootの設定に入ります. 2.Clean/Purge dataを行います. 3.Reset to factory defaultsを行います. 少し,強制的な直し方ですが,これでビルドしていただくと,うまくいくと思います. たまに,ビルドできなくて午前中なくなる:(
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Docker】docker-composeで2つのコンテナをつなぐ no.11

こんにちは、まゆみです。 Dockerについての記事をシリーズで書いています 今回の記事では、『Docker-compose』について書いていきます。 今までの記事では、Containerを作って、それ単独で動かしてきました ただ、現実の世界では、2つ以上のContainerをつないでサービスを作ることが多いと思います。 そのような時に役に立つのが『Docker compose』になります 今回の記事では、 nodeで作ったWebアプリと (アプリへのアクセス数をブラウザーに表示させる) インメモリ―データベースのredis-server のContainerをそれぞれ作りそれらのContainerをつなげるにはどのようしたら良いのか? を実際に手を動かしてコードを書きつつ解説していきます(下のイメージのようなサービスを作っていきます) ではさっそく始めていきますね。 Docker-compose はDockerと一緒にインストールされている まず、Docker-composeがちゃんとインストールされているかを確かめてみましょう Docker-composeは、Dockerをインストールした時に一緒にインストールされています。 試しに、ターミナルに docker-compose と打ってみてください。 docker-compose で使えるコマンドがずらっと表示されます。 準備するファイル では実際に、nodeのWebアプリと、redis-serverを作るためのコードをエディターに書いていきます package.json おなじみのpackage.jsonになります どんなdependenciesを使うのかなどを記載したファイル。 index.js 当記事は、Dockerに関する記事なので、詳しいコードの解説は省きますが、アクセスがあるごとに、その訪問数がredisに記録されるようにしました。 下記のスクショのぼかしているところが、Docker-composeを使う時は独特な書き方をする部分なので、後で解説するときにぼかしを取りますね。 Dockerfile Dockerfileの書き方の詳しい解説は前回の記事でさせていただきましたので、もし分からないって方は読んでみてくださいね。 これらのファイルが揃ったところで、 redisのイメージから作ったContainerと DockerfileからContainerを それぞれ起動させました。 が、このままでは2つのContainerはお互いにコミュニケーションが取れません。 docker-compose.ymlファイルを用意する そこで2つの独立したContainerをお互いにコミュニケーションできるように、単一のネットワークに実行させます。 そのためには『docker-compose.yml』というファイルが必要になります。 YAMLファイルのなかに、2つのContainerの情報とどのように実行させたいかの内容を書いていきます。 下記のようになります ①docker-compose.yml でファイルを作ると赤のDockerのアイコンのついたファイルができます ②versionは"3"になります ③servicesに実行したいContainer を記載していきます。 service名には、Containerそのものというより、どのようなタイプのContainerなのかを書いていきます ④redis-server はDockerhub からイメージを引っ張ってきて作ります ⑤node-appはDockerfileから作るので build: . と書きます ⑥portsにはつなげたいポートを記載します。portsには、つなげるポートを複数書くことができます(YAMLファイルでは『-』はarrayを表します) このようにYAMLファイルを書いて実行することで、水面下ではどんなことが起こっているのかを下記で説明していきます。 まず、先ほどindex.jsのぼかしていた部分のぼかしを取ってみましょう。 port: 6379 はredisのデフォルト値になります。 host: "redis-server" と書く理由を下記に解説していきます。 通常、Docker-composeを使わない場合、 『host:』の部分は、"https://URL" などと書かれますが、 Docker-composeを使う場合、docker-compose.ymlファイルの中のservices: のところに書かれたredis-serverの名前を書きます。(下記参考) どうして、docker-compose.ymlに書かれた、Container名を書くのか?ということについて、docker docsに良い説明がありましたので、引用しておきます 引用元:docker docs 赤で囲んだ部分を翻訳しますと デフォルトでは、Composeによってアプリ用に単一のネットワークが設定されます。各Containerはそのデフォルトのネットワークに組み込まれ、それぞれが双方向にコミュニケーションをすることができます。また各々のContainerはContainer名と同一のホスト名で検索可能です。 ではさっそく実行してみましょう docker run に対応するものは docker-compose up になります。 注目は、赤で囲んだ部分でまず最初にネットワークが構築されているのが分かります。 2つのContainerが作られ、同じネットワーク内でつながったようなので、ブラウザーから訪問してみましょう localhost:8081 でアクセスしてみます リロードするたびに、カウント数も増え、上手くいっています まとめ 今回の記事はここで締めくくらせていただきます。 次回の記事では、docker-composeで実行したContainerをストップするにはどうしたら良いのかを書いていきますね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Docker × Laravel】browsersyncの設定方法

環境 docker 20.10.6 docker-compose 1.29.1 composer 2.0.14 laravel 8.42.1 laravel Mix 6.0.19 php 8.0.7 browser-sync 2.26.14 手順 browser-syncをインストール webpack.mix.jsを編集 起動 browser-syncをインストール 以下のコマンドでグローバルにbrowser-syncをインストール(今後使わなそうなら開発環境のみでもOK) zsh npm install -g browser-sync browser-sync-webpack-plugin webpack.mix.jsを編集 webpack.mix.js mix.js("resources/js/app.js", "public/js") .postCss("resources/css/app.css", "public/css", [ require("postcss-import"), require("tailwindcss"), require("autoprefixer"), ]) // ここから下 .browserSync({ proxy: { target: "http://localhost:10080", }, files: ["./resources/**/*", "./public/**/*"], open: true, reloadOnRestart: true, }); webpack.mix.js proxy: { target: "http://localhost:10080", }, targetにはwebサーバのホスト側ポート番号を設定 docker-compose.yml version: "3.9" services:         (省略) web: image: nginx:1.20-alpine ports: - 10080:80 //ここの左側の値のこと volumes: - ./backend:/work - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf working_dir: /work         (省略) webpack.mix.js files: ["./resources/**/*", "./public/**/*"], ここで、各自変更を検知してほしいディレクトリを設定 今回で言うとresources、public配下のファイルに編集が加わるたびにブラウザに自動で反映してくれる webpack.mix.js open: true, これはbrowser-syncを起動したときに自動でブラウザを開くかの設定 tureにすると自動で開く webpack.mix.js reloadOnRestart: true, これはbrowser-syncを再起動したときに、開いているブラウザをリロードするかの設定 動作確認 laravelのプロジェクトルートで以下のコマンドを打つと npm run watch browser-syncが起動して (open: trueにしていれば)http://localhost:3000でブラウザが開かれます
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Docker × Laravel】browser-syncの設定方法

環境 docker 20.10.6 docker-compose 1.29.1 composer 2.0.14 laravel 8.42.1 laravel Mix 6.0.19 php 8.0.7 browser-sync 2.26.14 手順 browser-syncをインストール webpack.mix.jsを編集 起動 browser-syncをインストール 以下のコマンドでグローバルにbrowser-syncをインストール(今後使わなそうなら開発環境のみでもOK) zsh npm install -g browser-sync browser-sync-webpack-plugin webpack.mix.jsを編集 webpack.mix.js mix.js("resources/js/app.js", "public/js") .postCss("resources/css/app.css", "public/css", [ require("postcss-import"), require("tailwindcss"), require("autoprefixer"), ]) // ここから下 .browserSync({ proxy: { target: "http://localhost:10080", }, files: ["./resources/**/*", "./public/**/*"], open: true, reloadOnRestart: true, }); webpack.mix.js proxy: { target: "http://localhost:10080", }, targetにはwebサーバのホスト側ポート番号を設定 docker-compose.yml version: "3.9" services:         (省略) web: image: nginx:1.20-alpine ports: - 10080:80 //ここの左側の値のこと volumes: - ./backend:/work - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf working_dir: /work         (省略) webpack.mix.js files: ["./resources/**/*", "./public/**/*"], ここで、各自変更を検知してほしいディレクトリを設定 今回で言うとresources、public配下のファイルに編集が加わるたびにブラウザに自動で反映してくれる webpack.mix.js open: true, これはbrowser-syncを起動したときに自動でブラウザを開くかの設定 tureにすると自動で開く webpack.mix.js reloadOnRestart: true, これはbrowser-syncを再起動したときに、開いているブラウザをリロードするかの設定 動作確認 laravelのプロジェクトルートで以下のコマンドを打つと npm run watch browser-syncが起動して (open: trueにしていれば)http://localhost:3000でブラウザが開かれます
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「Amazon TimestreamのデータをGrafanaで可視化してみた | DevelopersIO」をやってみた

はじめに Amazon TimestreamのデータをGrafanaで可視化してみた | DevelopersIOをやってみたときのメモです。 手順 Grafana公式リポジトリからソースコードを取得します。 実際に使用するのは、Dockerfileの1ファイルのみです。 mkdir grafana cd grafana wget https://raw.githubusercontent.com/grafana/grafana/main/packaging/docker/custom/Dockerfile Dockerイメージをビルドします。 docker build \ --build-arg "GRAFANA_VERSION=latest" \ --build-arg "GF_INSTALL_PLUGINS=grafana-timestream-datasource" \ -t grafana-custom -f Dockerfile . Dockerコンテナを起動します。 docker run -d -p 3000:3000 --name=grafana grafana-custom ブラウザでhttp://localhost:3000にアクセスします。 admin/adminでログインします。 Grafanaの画面で、Configuration > Data Sources > Add data source で Amazon Timestreamを選択します。 AWSのアクセスキーとシークレットアクセスキーを入力します。 us-east-1リージョンを選択します。 ※Timestreamは、現時点では、東京リージョンでGAされていません。 次のコマンドでエンドポイントを取得します。 ※https://を補います aws timestream-query describe-endpoints --region us-east-1 Query Editorに次のクエリーを入力します。 SELECT measure_name, measure_value::double AS load, time FROM "sampledb".IoT WHERE measure_name = 'load' ORDER BY time
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerfileとdocker-compose.yamlの書き方を完全に理解した(わかっていない)

はじめに Dockerfileとdocker-compose.yamlの基本的な書き方を調べたので、自分なりの理解でまとめる 本記事のサンプルコードをそのままコピペしても一部動かない可能性あるので悪しからず ゴール GolangのAPIサーバ用コンテナ立てる ディレクトリ構成 ざっくりこんな感じ hogehoge.api ├── docker │   ├── Dockerfile │   └── docker-compose.yml └── src └── app └── main.go Dockerfile記述 Dockerfile # ベースイメージを指定 # alpine linuxが軽くてオススメらしいので採用 FROM golang:1.13.15-alpine3.12 # 環境変数の設定 # golangのバージョン1.11以降でGoモジュールの管理にこれが使われるようになったらしいのでonにしておく ENV GO111MODULE on # Goのパス通す ENV GOPATH /go ENV PATH /go/bin:$PATH # RUNコマンドは繋げられるならば繋げたほうが良い(軽量化に繋がる)らしいので&&で連ねる # apk(Alpin Linux Package Management)をアップデートする # go moduleインストール用にgit入れる # ホットリロード用にair(https://github.com/cosmtrek/air)を採用 RUN apk update \ && apk add --no-cache git \ && go get -u github.com/cosmtrek/air # コンテナ実行時のデフォルト処理 # docker-composeでも指定するから不要かも(?) CMD sh docker-compose.yaml記述 DBに関する記述は雑 →ネットワークの説明やbuildにDockerfile以外も使えることを示すためだけなので docker-compose.yaml # Docker Composeファイルフォーマットのバージョンを指定 version: "3" # コンテナ間のネットワーク networks: backend: # `docker-compose build`や`up`と打った際に作成するコンテナ services: # `docker-compose ps`と打った際に表示されるサービス名 # ここからDBのコンテナ作っていく my-db-for-hogehoge: # `docker ps`と打った際に表示されるコンテナ名 container_name: my-hogehoge-db # コンテナのベースイメージ指定 image: mysql:5.7 # ネットワークで`backend`を指定しているコンテナと疎通 networks: - backend # ここからAPIのコンテナ作っていく api-for-hogehoge: container_name: my-hogehoge-api # ビルド時に使うDockerfileを指定 # dbのほうではimagesだった箇所にあたる build: context: . dockerfile: ./Dockerfile # hogehoge.apiのファイル群を/goにマウント volumes: - ..:/go # コンテナ側の80番ポートを開放 expose: - "80" # ホストマシンの10080番ポートとコンテナ側の80番ポート繋ぐ ports: - "10080:80" # 環境変数置くファイル(開発環境でのみ使うパターンが多い?) env_file: - .env # 環境変数設定 environment: HOGE: "hoge" # ワークスペース、コンテナ入った時の初期ディレクトリ working_dir: /go/src # ネットワークで`backend`を指定することで、先ほどのDBと疎通 networks: - backend # `docker-compose up`と打った際に実行されるコマンド command: > air -c .air.toml # コンテナ永続化するか否か(ここではする) tty: true APIコンテナ起動してみる ここは本筋ではないので軽く 下記コマンドでエラー吐かれたら随時対処 $ docker-compose build $ docker-compose up -d $ docker-compose logs -f api-for-hogehoge ハマった点 GolangというかホットリロードAirの問題かもしれないが、docker-compose buildしてもAirがインストールされなかった コンテナに入って手動インストールして解消 docker-compose.yamlの書き方が統一されていない オプションの後は改行入れた方が良い? オプションの中身が複数ある場合はハイフン-でリスト表記したほうが良い?特にハイフン不要? 調べて修正必須 さいごに まだ「完全に理解した」だけなので、曖昧な理解や誤解を生む表現が混ざっている可能性もある 発見次第、随時修正していく予定 参考 Dockerfile リファレンス — Docker-docs-ja 19.03 ドキュメント Compose ファイル・リファレンス — Docker-docs-ja 19.03 ドキュメント
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでPostgreSQLコンテナを作成

docker-compose.yaml version: "3" services: sample-postgres: image: postgres:9.6 container_name: sample-postgres env_file: - .env ports: - "5432:5432" volumes: - database:/var/lib/postgresql/data - ./initdb:/docker-entrypoint-initdb.d volumes: database: driver: local .env POSTGRES_USER=postgres POSTGRES_PASSWORD=password POSTGRES_DB=sample_db Up $ docker-compose up -d --build Sign in to db $ sudo docker exec -it sample-postgres /bin/bash -c \ 'psql -U postgres -W -d sample_db' Password for user postgres: psql (9.6.22) Type "help" for help. 外部から $ psql -U postgres -h example.com -W -d sample_db pg_hba.conf $ docker exec -it sample-postgres /bin/bash -c 'ls -l /var/lib/postgresql/data/pg_hba.conf' -rw------- 1 postgres postgres 4490 Jun 7 14:15 /var/lib/postgresql/data/pg_hba.conf $ docker exec -it sample-postgres /bin/bash -c 'cat /var/lib/postgresql/data/pg_hba.conf' # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust # Allow replication connections from localhost, by a user with the # replication privilege. #local replication postgres trust #host replication postgres 127.0.0.1/32 trust #host replication postgres ::1/128 trust host all all all md5 Databases sample_db=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | sample_db | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows) Schemas sample_db=# \dn List of schemas Name | Owner --------+---------- public | postgres (1 row) Roles sample_db=# \du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} Search path sample_db=# show search_path; search_path ----------------- "$user", public (1 row) Create table create table users ( id SERIAL NOT NULL, name VARCHAR(255) NOT NULL, created_at TIMESTAMP, updated_at TIMESTAMP, PRIMARY KEY (id) ); sample_db=# \dt List of relations Schema | Name | Type | Owner --------+-------+-------+---------- public | users | table | postgres (1 row) sample_db=# \d users; Table "public.users" Column | Type | Modifiers ------------+-----------------------------+---------------------------------------------------- id | integer | not null default nextval('users_id_seq'::regclass) name | character varying(255) | not null created_at | timestamp without time zone | updated_at | timestamp without time zone | Indexes: "users_pkey" PRIMARY KEY, btree (id)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【docker-compose】requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/version

エラー内容 下記の記事を参考に https://qiita.com/eighty8/items/0288ab9c127ddb683315 $ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle を入力したところ、下記のエラーが発生。 Traceback (most recent call last): File "docker/api/client.py", line 268, in _raise_for_status File "requests/models.py", line 941, in raise_for_status requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/version During handling of the above exception, another exception occurred: Traceback (most recent call last): File "docker/api/client.py", line 214, in _retrieve_server_version File "docker/api/daemon.py", line 181, in version File "docker/api/client.py", line 274, in _result File "docker/api/client.py", line 270, in _raise_for_status File "docker/errors.py", line 31, in create_api_error_from_http_exception docker.errors.APIError: 500 Server Error for http+docker://localhost/version: Internal Server Error ("b'dial unix docker.raw.sock: connect: connection refused'") During handling of the above exception, another exception occurred: Traceback (most recent call last): File "docker-compose", line 3, in <module> File "compose/cli/main.py", line 81, in main File "compose/cli/main.py", line 200, in perform_command File "compose/cli/command.py", line 60, in project_from_options File "compose/cli/command.py", line 152, in get_project File "compose/cli/docker_client.py", line 41, in get_client File "compose/cli/docker_client.py", line 170, in docker_client File "docker/api/client.py", line 197, in __init__ File "docker/api/client.py", line 221, in _retrieve_server_version docker.errors.DockerException: Error while fetching server API version: 500 Server Error for http+docker://localhost/version: Internal Server Error ("b'dial unix docker.raw.sock: connect: connection refused'") [6004] Failed to execute script docker-compose 解決策 こちらの記事を参考に、 https://github.com/docker/for-win/issues/9561 docker-compose.ymlのversion指定をシングルクォーテーションからダブルクォーテーションに変えたらエラーが消えました。 # 修正前 version: '3' # 修正後 version: "3" 理由はわかりません。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【docker-compose】FileNotFoundError: [Errno 2] No such file or directory

エラー内容 下記の記事を参考に https://qiita.com/eighty8/items/0288ab9c127ddb683315 $ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle を入力したところ、下記のエラーが発生。 Traceback (most recent call last): File "urllib3/connectionpool.py", line 670, in urlopen File "urllib3/connectionpool.py", line 392, in _make_request File "http/client.py", line 1255, in request File "http/client.py", line 1301, in _send_request File "http/client.py", line 1250, in endheaders File "http/client.py", line 1010, in _send_output File "http/client.py", line 950, in send File "docker/transport/unixconn.py", line 43, in connect FileNotFoundError: [Errno 2] No such file or directory During handling of the above exception, another exception occurred: Traceback (most recent call last): File "requests/adapters.py", line 439, in send File "urllib3/connectionpool.py", line 726, in urlopen File "urllib3/util/retry.py", line 410, in increment File "urllib3/packages/six.py", line 734, in reraise File "urllib3/connectionpool.py", line 670, in urlopen File "urllib3/connectionpool.py", line 392, in _make_request File "http/client.py", line 1255, in request File "http/client.py", line 1301, in _send_request File "http/client.py", line 1250, in endheaders File "http/client.py", line 1010, in _send_output File "http/client.py", line 950, in send File "docker/transport/unixconn.py", line 43, in connect urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "docker/api/client.py", line 214, in _retrieve_server_version File "docker/api/daemon.py", line 181, in version File "docker/utils/decorators.py", line 46, in inner File "docker/api/client.py", line 237, in _get File "requests/sessions.py", line 543, in get File "requests/sessions.py", line 530, in request File "requests/sessions.py", line 643, in send File "requests/adapters.py", line 498, in send requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "docker-compose", line 3, in <module> File "compose/cli/main.py", line 81, in main File "compose/cli/main.py", line 200, in perform_command File "compose/cli/command.py", line 60, in project_from_options File "compose/cli/command.py", line 152, in get_project File "compose/cli/docker_client.py", line 41, in get_client File "compose/cli/docker_client.py", line 170, in docker_client File "docker/api/client.py", line 197, in __init__ File "docker/api/client.py", line 221, in _retrieve_server_version docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory')) [5763] Failed to execute script docker-compose 解決方法 単純に、Dockerを立ち上げていないだけでした。 僕はDocker Desktopを使っているので、アプリを立ち上げるだけでした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む