- 投稿日:2020-03-19T23:05:08+09:00
クラウドネイティブでよく聞くサービス概要
CNCFとは
CNCF(Cloud Native Computing Foundation)とはinux Foundationのプロジェクトで、コンテナ技術の発展と、その進化に関連するテクノロジ業界の連携を支援するための団体。
https://labs.mobingi.com/cncf/
✨ Kubernetes
- 公式: https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/
- ジャンル: オーケストレーションツール
- GitHub: kubernetes/kubernetes
- 実装言語: Go
- 概要: コンテナ化したアプリケーションのデプロイ、スケーリング、および管理を行うための、オープンソースのコンテナオーケストレーションシステム
- 参考: https://qiita.com/Kta-M/items/ce475c0063d3d3f36d5d
✨ containerd
- 公式:
- ジャンル: Container Runtime
- GitHub: https://github.com/containerd/containerd
- 実装言語: Go
- 概要: OCI Runtime Specificationに基づいて作られたKubernetesやDockerの高レベルなランタイム
- 参考: https://qiita.com/mamomamo/items/ed5db2ab1555078f8a24
✨Envoy
- 公式: https://www.envoyproxy.io/
- ジャンル: Service Proxy
- GitHub: envoyproxy/envoy
- 実装言語: C++
- 概要: Webサービスのためのロードバランサー
- 参考: https://i-beam.org/2019/01/22/hello-envoy/
✨ Prometheus
- 公式: https://prometheus.io/
- ジャンル: Monitoring
- GitHub: prometheus/prometheus
- 実装言語: Go
- 概要: サーバーやインフラなどの監視ツール
- 参考: https://knowledge.sakura.ad.jp/11633/
✨ Grafana
- 公式: https://grafana.com/
- ジャンル: Monitoring
- GitHub: grafana/grafana
- 実装言語: Go
- 概要:
- 参考: https://qiita.com/MahoTakara/items/7b414c2a0d47e75d7234
✨Fluentd
- 公式: https://www.fluentd.org/
- ジャンル: Logging
- GitHub: fluent/fluentd
- 実装言語: Ruby
- 概要:
- 参考: https://qiita.com/ritorut18/items/4230ec6b524be15ede01
- 投稿日:2020-03-19T19:08:43+09:00
オフライン環境のDockerでAlfrescoを立ち上げる
概要
dokcer-composeとdockerイメージを取得し、オフライン環境で起動する。
オンライン環境作業
- docker-composeの取得
- dockerイメージをpullで取得
- 取得したdockerイメージをtarで圧縮
オフライン環境作業
- docker-composeの導入
- dockerイメージを展開
- docker-composeコマンドでコンテナ起動
オンライン環境作業
初めにdocker-composeを取得する。
## docker-composeをgitから取得 sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /tmp/docker-compose ## ファイル確認 $ ls -l /tmp/docker-compose -rw-r--r-- 1 root root 11750136 Mar 19 08:24 docker-composeあわせて、必要な3つのイメージを取得する。
- webcenter/rancher-alfresco:v5.1-201605-1
- alpine
- postgres:9.4
## webcenter/rancher-alfresco:v5.1-201605-1 $ docker pull webcenter/rancher-alfresco:v5.1-201605-1 ## alpine $ docker pull alpine ## postgres:9.4 $ docker pull postgres:9.4 ## イメージ取得後の確認 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE postgres 9.4 ed5a45034282 4 weeks ago 251MB alpine latest e7d92cdc71fe 2 months ago 5.59MB webcenter/rancher-alfresco v5.1-201605-1 c76b4794cf11 3 years ago 2.14GB続いて、公式ドキュメントにある通り、dockerイメージをtarファイルに出力する。
## dockerイメージをtarにする $ docker save postgres:9.4 webcenter/rancher-alfresco:v5.1-201605-1 alpine > alfresco.tar ## ファイル確認 $ ls -l alfresco.tar -rw-rw-r-- 1 root root 2435766272 Mar 19 07:41 alfresco.tarここまでで取得した以下の2ファイルをオフライン環境へ配置する。
- docker-compose
- alfresco.tar
オフライン環境で作業
ここからはオフライン環境での作業になる。
まずは取得したファイルが配置してあることを確認する。## 配置確認 $ ls -l /tmp -rw-r--r-- 1 root root 11750136 Mar 19 08:24 docker-compose -rw-rw-r-- 1 root root 2435766272 Mar 19 07:41 alfresco.tardocker-composeの導入を行う。
## bin配下にdocker-composeを配置 $ sudo mv /tmp/docker-compose /usr/local/bin/ ## 実行権限を付与 $ sudo chmod +x /usr/local/bin/docker-compose ## 導入確認(バージョンが表示されること) $ docker-compose -v docker-compose version 1.22.0, build f46880fedocker-compose.ymlは以下に書かれていたもの参考に用意。
参考:【Docker】これは役に立つ!! docker-compose.ymlの例まとめ
docker-compose.ymlalfresco: environment: CIFS_ENABLED: 'false' FTP_ENABLED: 'false' tty: true image: webcenter/rancher-alfresco:v5.1-201605-1 links: - postgres:db stdin_open: true ports: - 8081:8080/tcp volumes_from: - alfresco-data alfresco-data: image: alpine volumes: - /opt/alfresco/alf_data net: none command: /bin/true postgres: environment: PGDATA: /var/lib/postgresql/data/pgdata POSTGRES_DB: alfrescodb POSTGRES_PASSWORD: password POSTGRES_USER: alfrescouser tty: true image: postgres:9.4 stdin_open: true volumes_from: - postgres-data postgres-data: labels: io.rancher.container.start_once: 'true' image: alpine volumes: - /var/lib/postgresql/data/pgdata net: none command: /bin/true私が使用しているオフライン環境では8080ポートが使用済みのため、ポートを8081へ変更している。
いよいよ、dokcerコンテナを起動する。
docker-compose.ymlが置いてある階層で以下のコマンドを実施する。## コンテナ起動 $ docker-compose up -d Starting alfresco_alfresco-data_1 ... done Starting alfresco_postgres-data_1 ... done Starting alfresco_postgres_1 ... done Starting alfresco_alfresco_1 ... done ## コンテナ起動確認 $ docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------------------------------------------------------------------- alfresco_alfresco-data_1 /bin/true Exit 0 alfresco_alfresco_1 /bin/sh -c /app/run.sh Up 137/tcp, 138/tcp, 139/tcp, 21/tcp, 445/tcp, 7070/tcp, 8009/tcp, 0.0.0.0:8081->8080/tcp alfresco_postgres-data_1 /bin/true Exit 0 alfresco_postgres_1 docker-entrypoint.sh postgres Up 5432/tcp最後に実際にアクセスしてみる。
ブラウザを開き、以下のアドレスを入力。
http://[オフライン環境のIPアドレス]:8081/share/page以上で終了になります。
おわりに
Qiita初投稿でした!
アウトプットを全くしてこなかったので記事にしてみました。余談
私はオンライン環境にAWSを使用していました。
EBS容量不足やエンドポイントの使い方など含めて、記事には出していない問題もいくつかありました。
あと、Markdown形式の文章も初めて書いたかも。
いい学習になったかも。~おしまい~
- 投稿日:2020-03-19T18:20:58+09:00
Raspberry Pi 3にDockerでfluentdを建ててみる
経緯
- Raspberry Pi内部で動いているアプリケーションがエラーを吐いたらログをSlackに出したい
- Raspiに直接fluentd入れるのは嫌なのでDocker化したい!
前提
- Raspberry Piのセットアップは完了してる
- 何らかのアプリケーションが既にRaspberry Pi上に存在する
手順
Dockerfileの準備
- ポイントとしてはRaspberry PiとcompatibleなRubyイメージが必要
- fluentd動かすにはRuby v2.4.0以上が必要らしい
- slack通知したいのでfluent-plugin-slackを入れる
FROM lockitron/rpi-ruby:2.4.0 RUN apt-get update -y && \ apt-get install -y ruby-dev g++ make && \ gem install fluentd fluent-plugin-secure-forward fluent-plugin-slack && \ apt-get remove --purge -y $(apt-mark showauto) && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ mkdir -p /fluentd/etc /fluentd/plugins WORKDIR /home/ubuntu COPY fluent.conf /fluentd/etc/ COPY plugins /fluentd/plugins/ EXPOSE 24224 CMD ["exec", "fluentd", "-c", "/fluentd/etc/fluent.conf", "-p", "/fluentd/plugins"]
- fluentdの設定は以下の感じ
/ERROR|Error|error|NameError/
に引っ掛かる場合に通知する感じfluent.conf<source> @id app @type tail read_from_head true # Raspberry PiのアプリケーションログをfluentdのDockerコンテナにマウントして、その先を指定する path /fluentd/logs/app/output.log pos_file /var/log/fluentd/logs/app/output.log.pos format none tag error_log_detail.app </source> # filter by error message <filter error_log_detail.**> @type grep <regexp> key message pattern /ERROR|Error|error|NameError/ </regexp> </filter> # post to slack <match error_log_detail.**> @type slack webhook_url https://hooks.slack.com/services/xxxxx/xxxxx/xxxxx # slackのslack incoming webhooksを設定する channel raspi_health_check # 任意のslackチャネル username error-log flush_interval 10s color error icon_emoji :ghost: </match>
- 上記のDockerfileをbuildしてDockerHubにpushしておく
Raspberry PiにDockerをいれる
- 以下の手順でRaspberry PiにDockerをインストールする
# Raspiにログインする # Docker周りの必要なライブラリをインストールしてくれる $ curl -sSL https://get.docker.com | sh $ sudo usermod -aG docker pi $ docker --version #--> Docker version 19.03.8, build afacb8b # 一度ログアウトする作ったDockerコンテナをRaspberry Pi上で起動する
# Raspiにログイン $ ssh pi@${raspiのIP} # このDockerイメージは https://github.com/koska-devs/RasFluentd で管理してる $ docker pull ${DockerHubのアップ先} # マウントする先は適宜変える $ docker run -d --name=rpi-fluentd -p 24224:24224 -v /home/pi/logs:/fluentd/logs ${DockerHubのアップ先}参考
- wsrak/rpi-fluentd
- fluentdの起動に必要なDockerfileの参考に使用
- lockitron/rpi-ruby
- Raspi用のfluentdのDockerイメージ
- 投稿日:2020-03-19T14:19:59+09:00
VisualStudio2017でリモートデバッグ
やること
ubuntu環境をdockerで構築し、VisualStudio2017からリモートデバッグを行います。
リモートデバッグを行うコンテナを用意
dockerfileFROM ubuntu:16.04 # 各種インストール RUN apt-get update RUN apt-get install -y openssh-server sudo bash-completion g++ gdb gdbserver rsync git # SSH用のディレクトリ作成 RUN mkdir /run/sshd # ユーザーを追加 RUN useradd -m -s /bin/bash ubuntu && gpasswd -a ubuntu sudo # パスワードを設定 RUN echo 'ubuntu:ubuntu' | chpasswd # 22番ポートを公開 EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]docker-composeversion: '2.3' services: dev: build: . ports: - "2222:22" volumes: - ../volume:/tmp/dataイメージをビルド/コンテナを起動
$ docker-compose build $ docker-compose up -dSSH
$ docker exec -it docker_dev bashVisualStudio
デバッグを行うプロジェクトを用意
- 新規作成 > Visual C++ > クロスプラットフォーム > Linux
- ない場合はインストーラから「C++によるLinux開発」を選択し、インストール
VisualStudio側の設定
- 接続先の指定
- ツール > オプション > クロスプラットフォーム > 接続マネージャー > 追加
- ホスト名:リモート先のIP(localhost)
- ポート:22番ポートにマッピングされているポート(2222)
- ユーザー名:ゲストOSのユーザー名(ubuntu)
- 認証の種類:パスワード
- パスワード:上記で設定したパスワード(ubuntu)
()は上記で設定した場合の値
デバッグ
- ソリューションのリビルドを実行
- ビルド > ソリューションのリビルド
- Linuxコンソールの表示
- デバッグ > linux コンソール
- 投稿日:2020-03-19T13:58:22+09:00
Docker で Ubuntu 環境を作り、Nuxt.js を動かしてみる
Prologue
Nuxt.js で作成したプロジェクトを
Ubuntu
環境でbuild
した際エラーが出ました。
このエラーはlocalでは起こらず、エラー内容の詳細を取得できるか試すため、Ubuntu
の環境を作って確認しようとしたことがきっかけです。ここではDockerの初期設定から簡単なNuxt.jsプロジェクトの作成までを行います。
結果としてエラーは環境とは関係なかったため、ここでは言及していません。環境
- macOS: 10.15.2
terminal: iTerm
Project概要
- 言語: Nuxt.js, TypeScript
- パッケージマネージャ:
yarn
Docker の初期設定
Mac の Docker Desktop をインストール
- 以下からDockerをインストールします。
参考: https://hub.docker.com/editions/community/docker-ce-desktop-mac/
- インストール後、Docker.appをAppフォルダに移動
- clickするとアラートが出るためOKをclick
- sign inを求められるためsign in
ここでアカウントを持っていなければアカウントを作成します。
- アカウント作成
- アカウント名、PWD、メールアドレスを入力
- 名前、職種、会社名等入力後、登録のメールアドレスに確認メールが来ます。
- メールの指示通り対応して、完了
参考: https://docs.docker.com/docker-for-mac/install/
Dockerでbuildする
ubuntuをインストール
- エラーが起こった環境の
Ubuntu
のversionを確認し、今回は18.04.4
だったため、最新のものをインストールします。
ターミナルで以下のコマンドを入力。docker version // dockerがインストールされているか確認 docker pull ubuntu // ubuntuをインストール docker images // イメージ一覧を取得してubuntuがインストールされていることとバージョンを確認 docker run -it -d --name miiiii-ubuntu ubuntu // ubuntuを起動 docker ps // 起動中のコンテナを確認参考: https://www.sejuku.net/blog/82240
Ubuntu
を起動する際名前をつけることができます。今回はmiiiii-ubuntu
としました。必要なコマンドの確認
Dockerコンテナに入ります。
docker exec -it miiiii-ubuntu /bin/bashコンテナ内に入ったため、以降は
Ubuntu
のコマンドで進みます。cd /usr/src // /usr/src に移動 mkdir app // プロジェクトを置くためのディレクトリを作成 cd app // 作成したディレクトリに移動
curl
とsudo
をインストールエラー解決のため、作業環境を整えていきます。
yarnをインストールするため、curl
とsudo
をインストール。
- sudo
find . -name sudo // sudoコマンドが存在しないことを確認 apt-get update // update apt-get install sudo
- curl
sudo apt install curl参考: https://qiita.com/Sa2Knight/items/bdb6d821a3ac10088289
yarn をインストール
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -参考: https://classic.yarnpkg.com/en/docs/install#debian-stable
- errorが出ました。
E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation curl: (23) Failed writing body (577 != 1369)
- 解決: エラー内容からパッケージがないということなので、
gnupg
をインストールapt-get install gnupg再度
yarn
をインストールしてエラーは出なかったため、以下のコマンドできちんとインストールされているか確認します。yarn --version
error:
bash: yarn: command not found
- まだ
yarn
がない。とのことなのでsudo
をつけて、別のコマンドで実行
sudo apt install yarnバージョンが古いためyarnのアップグレードを行います。
sudo apt-get update sudo apt-get install yarn yarn -v 1.21.1今度は成功しました。
参考: https://phoenixnap.com/kb/how-to-install-yarn-ubuntu
Nuxtプロジェクトを作成
\usr\src\app に移動して以下のコマンドを実行
yarn create nuxt-app sampleerror
error semver@7.1.3: The engine "node" is incompatible with this module. Expected version ">=10". Got "8.10.0" error Found incompatible module.nodeのバージョンが古い、とことなのでバージョンを確認
node --version v8.10.0検証したいプロジェクトで使っているバージョン(10.16.0)に合わせます
sudo apt install nodejs npm sudo npm install -g n sudo n 10.16.0一度 ubuntu から exit する
node -v v10.16.0再度プロジェクトを作成(
yarn create nuxt-app sample
)、成功しました。
あとは通常のNuxtのプロジェクトと同じようにComponentを作ったり等等、問題なく使えました。
今回の目的だったbuild
も無事成功。Epilogue
build
できなかった理由は環境ではなく、依存関係にあるライブラリのバージョン問題でした。
バージョンを最新にするとubuntu
環境でもbuild
は成功...。
環境が問題なのか、という部分が今回のDocker立ち上げのキーポイントだったため、今回はここで一旦終了しました。
なぜ環境によってインストールされるバージョンが異なるのか、は時間があれば確認します。これまではVirtualBoxをよく使っていたので、初めてDockerを使ってみました。
つまずいたところは特になく、基本公式のドキュメント通りに進めれば問題はないと感じました。
ミニマムなトライ内容でしたが、初心者という壁は超えられたので、これからもっと慣れていこうと思います!課題
- 環境の違いでバージョンが異なってインストールされるのは何故なのか。わかり次第別の記事を書きます。
- 投稿日:2020-03-19T13:01:08+09:00
NestJSアプリケーションのビルドサイズをncc使って300MB減らした話
Dockerイメージサイズをできるだけ小さくする際に試行錯誤した結果、nccを使ってイメージサイズを減らせたので備忘録
ncc使う前 ncc使った後 結果 599MB 245MB 354MB削減! ビルド手順
nccはTypeScriptをサポートしています。ですが、tsconfig.jsonの指定ができないため
tsconfig.app.json
のような複数の設定ファイルを保持している場合、うまく使用することができません。そこで次の手順を踏みます。
例:
api
というアプリをビルド
1. nest-cliでwebpackモードでビルドする:nest build api --webpack
2. 1の成果物をnccで更にビルドするncc build dist/api.js -m -o dist/api
するとアプリに必要なファイルをまとめて出力してくれます。 Dockerイメージにはこれを含めればいいだけ。
nccすごいですよ。webpackのやつを更にビルドできるの。
これにより、node_modulesが必要なくなり必要最低限のファイルのみがDockerイメージに含まれることになりました。
(node_modulesはもちろんnpm ci --production
でインストールしたもの)
... attempted to require "@nestjs/microservices" but could not be resolved, assuming external.
(↑正確なエラー文忘れて記録にも残ってないので前半ぼかしてます...)
nccでビルドしたファイルを実行すると、
@nestjs/microservices
のインポートがうまく解決できないエラーが発生しました。関連issueはこちら: https://github.com/zeit/ncc/issues/463私の場合、@nestjs/microservicesはメインで使っておらず
@nestjs/terminus
が動的に読み込みを行っているようです。terminusはヘルスチェックに必要ですが、少し前にサーバーレスに移行したため、重要度が低くなりました。なので@nestjs/terminus
自体を削除しました。nccの成果物にtypescriptが含まれる
場合によって、typescriptがまるっと含まれる可能性があります。47.8MB、めちゃくちゃでかい。当たり前なんですが、typescriptフォルダ自体削除しても特に動作に支障はありませんでした。
え、300MBも削減されてんの?動くのこれ?という不安
↑の結果を初めて見た時、かなり不安になりました。本当に最適化されただけ...?何か重要なファイル消えてない..?と言う感じで。
e2eテストをこのnccで行いましたが、ちゃんとテストは通っているので問題無しとしています(テスト書いててよかった)あと、パッケージによっては古いバージョンのライブラリを参照してることがあります。バージョンの異なる同じパッケージが含まれているか調べましたが、ちゃんと含まれているようです(uuidのパッケージが4つも含まれてた...)。
更にpkgでシングルファイルにすれば完璧では...!?
alpine + pkg の組み合わせは動かなかった。static link周りでエラーが出る。
https://github.com/zeit/pkg-fetch/pull/72
そもそもpkgはサーバーレス用途では使わないでってREADMEに書いてあるし使うのは辞めた。
https://github.com/zeit/pkg/blob/master/README.md
- 投稿日:2020-03-19T10:33:37+09:00
備忘録集[Vue.js+Laravel+docker]
一つの記事に書く程ではないけれども、
ハマった所を今後同じ所でハマった同志のため、
また物忘れが最近酷いので再度自分がハマらないため
自分が躓いた所を備忘録集として残します。
基本的だけれども見落としやすい所が中心です。備忘録なので書きなぐりの文章が多いです。
また間違い等があるかもしれないので、
都度修正していきます。Javascript関連:VueJS,typescript,axios等
1.axiosのdeleteの方法
postとは異なる方法で設定する必要がある。
axios.delete('url', params: { foo: 'bar' } ).then( //以下省略 );2.[Vue.js]async,awaitでreturnの結果としてaxiosでgetしたデータを取得する。
下の例はupdateDate関数でaxiosを使っている。
このupdateDate関数は外部から呼び出され、this.Dataの値を更新している。
しかしthisを使用しているので、thisに依存している。
依存を解消するなら、axiosの結果をupdateDataの外で受け取るべき。
しかしaxiosはPromise型なので、thenの内部でreturnを書いても値を返さない。改善前methods:{ updateData(url) { //データ取得 axios .get( url ) .then(response => { this.Data=response; //下のように書いてもresponseを返さない //return respose; }) .catch(error => { console.log(error); }) }, }そこでasync,awaitを利用し以下のように書き直す。
then以降まで書かないでもaxios.get(url)までで,
結果を返してくれる。参考:https://github.com/axios/axios
例1.thisをupdateDataの外部に出すことができた.mounted: async function() { let url = "どこかのurl"; try { this.Data = await this.updateTable(url); } catch (err) { console.log(err); } }, methods: { async updateData(url) { //axiosでデータ取得.get以降にthenを書かない。 return axios.get(url); }例2async function updateData2(url) { try { const response = await axios.get(url); return response; } catch (error) { console.error(error); return error; } }注意:axiosをVue.jsのmounted内部で使っている。
Axiosは例外処理も含めて多用する可能性が高いので、
慣れてきたらaxios等の非同期処理を担うクラスを作成したほうがコードが散乱しないので良い。3.tr等に普通にtransition-groupしてもアニメーションはつかない
htmlの仕様によりliやtr等のタグはtableタグ直下等の特殊な条件でしか処理されない。
なので、tableとtrの間に普通にtransition-groupしてもtr以下が表示されなくなる。失敗例<tbody name="table-row"> <transition-group> <tr v-for="data in showData" class="table-row-item" :key="data.id"> <!--ここは表示されない.transition-groupをdiv等にしても同じ挙動になる.--> </tr> </transition-group> </tbody>対策の一例は、tbodyにis="transition-group"をつけること。
tbodyにisをつける回避策<tbody name="table-row" is="transition-group"> <tr v-for="data in showData.data.data" class="table-row-item" :key="data.title">他の対策も複数あるので、必要な時は参考urlを参照。
4.アップロードされた画像ファイルのプレビュー表示方法 + URL.createObjectURLの仕様
画像の出力<div class="col-sm-1"> <img class="icon-image border border-dark" :src="iconimg" /> </div>ファイルのアップロードを入力するhtmlタグは省略。
ファイルが入力された後、下のselectedFile関数を通して画像を格納する。selectedFile(event) { //必要に応じてkeyは変更 this.iconfile = event.target.files[0]; //プレビュー用のイメージ格納 if (this.iconfile.type.startsWith("image/")) { //ObjectURLを生成 this.iconimg = window.URL.createObjectURL(this.iconfile); } },以下はjavascriptのcreateObjectURLの仕様の話。
createObjectURL(object)
は、
与えられたobjectに対してアクセス可能となるURLを生成している。
このURLはクライアントのブラウザのメモリ上に保存されているblob(いわゆる生のデータ)を参照する。
アップロードされたファイルはクライアント上ではFileオブジェクトで保存されているが、
File自体がblobを継承しているため、createObjectURLでのURL生成が可能となる。
なので、createObjectURL関数の引数となるobjectはfile,blob,MediaSourceのどれかでなくてはならない。
生成されたブラウザを閉じるまでURLは有効。
ただ一度ブラウザに読み込まれればURLは必要ないので、可能ならば削除したほうが良い。
window.URL.revokeObjectURL(file);
でURLの削除が可能。参考:
https://developer.mozilla.org/ja/docs/Web/API/File
https://qiita.com/azu369yu/items/8998e1e1536a5acfb7b3
https://qiita.com/iLLviA/items/c24f385ca3334c05a6825.[typescript+Vue.js]子コンポーネントにて、propsを定義する際にはundefinedに注意
参考:https://qiita.com/kyokoshimizu/items/ee6c6e6b905b8aa101fa
参考https://tech-up.hatenablog.com/entry/2019/03/15/152258前提:vue-property-decoratorをimportしている。
@Prop() public name:string;のようにVue.jsのpropsをtypescriptで書くと
Property '----' has no initializer and is not definitely assigned in the constructor.というエラーが出て怒られ、コンパイルができないケースがある。
しかし@Prop() public name:string = "";と初期化したらしたで、コンパイルも稼働はするが、コンソールには
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "propsValue"とエラーが出てしまう。
この場合、前者はtypescriptのエラーで後者がVue.jsのエラーになる。原因
typescriptの設定でstrictPropertyInitializationという設定がオンになっているためである。
strictPropertyInitializationは、「undefinedの許容されてない型を初期化させる」という設定になる。
要するに変数に初期値設定しろって設定。
最初に定義したPropsはstring型であるが、何も定義されていないのでundefinedが代入される。
string型にはundefinedが許容されていないため、strictPropertyInitializationによりエラーが発生した。
2回目のPropsのように初期化すればstrictPropertyInitializationによるエラーは解決しコンパイルは可能になるが、
これは子コンポーネントでpropsを書き換えているので、今後はVue.jsがエラーを発生させた。対策
四苦八苦した過程が残るけど自分のお勧めは4番1.tsconfig.jsonに以下を記述しstrictPropertyInitializationの設定をオフにする
strictPropertyInitialization:false但し全体に影響する。
2.any型やstringならばUnion型に変更しundefinedで対応できるようにする。
@Prop() public name:string|undefined;ただし、number型の場合はundefinedまたはnullとunion型にできないので、
この解決はできない。@Prop() public name:any;anyはどの型でも機能する。但しanyになるので型の意味があまりなくなる。
stringやnumberのような複雑じゃない型の時までanyにするのは悲しい。3.そもそも@component以下に書く
@Component( { props:{ placeholder:String, } } )但しexport以下で呼び出せなくなる。
4.型宣言の際に!をつける、または?をつける
参考:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#strict-class-initialization
参考:https://dev.classmethod.jp/server-side/typescript-assertions/@Prop() public name!:any;!はコンパイラにこの型はnon-nullですよと伝える意味がある。
初期化されてないが実際には外部で変数が代入されている(丁度今回みたいな)場合に使える。
ちなみに@Prop()
の中身にはoptionが設定できる。ソースよりexport interface PropOptions<T=any> { type?: PropType<T>; required?: boolean; default?: T | null | undefined | (() => T | null | undefined); validator?(value: T): boolean; }defaultとか設定したいときは次のような感じ
@Prop({default:"text"}) public type!:string;ちなみに上のソースコードでも出現しているが、!の代わりに?をつけても解決する。
?は代入されてなくても構わない、という意味になる。6.[Vue.js]vue-routerのto属性に対してparamを設定しpropを渡したい時、pathではなくnameでurlを呼び出さないといけない
<router-link :to="{name:'hoge',params:{huga: 'hage'}}" >でないといけない。router.jsの方でnameで設定しないとparamsが有効にならない。
pathを設定するとurlに直接paramsを組み込まなければならない。Laravel
1.モデルでSELECTする時にidを取得しないと、そのインスタンスにsaveもupdateもできない
大ハマり
参考:https://qiita.com/moimoinon/items/5adb4b179e3c25d189a2悪い例$data = Article::select('title','updated_at')->with('hashtags:name')->get();例のようにモデルのidを取得していないインスタンスにsaveメソッドを使用して更新しようとした場合、
saveの結果としてtrueが返されてもデータベース上では更新されない。
この後の例等、予期せぬ挙動を生むことが多いので、selectする時は基本的にidは取得したほうが良い。2.EagerLoadを使う場合、SELECTでidを取らないとwithで参照してくれない
参考:https://mseeeen.msen.jp/laravel-5-5-get-specified-column-with-with/
relationのwithも、idを軸にリレーション先のデータを取得している。
よって、もしSELECT元でidが選択されていない場合、withの参照先のデータも取得されない。良い例//もしidのカラムを取得していない場合はhashtagsが空になってしまう $data = Article::select('title','updated_at','id')->with('hashtags:name')->get();3.belongsToの場合のモデル名は単数。データ取得の際も関数でなくプロパティを通して取得。
HasManyと同じつもりで複数形にすると、参照先モデルの取得が正しくされない。
悪い例public function admins(){ return $this->belongsTo(Admin::class); }belongsToの参照先は1対多の1側なので、単数にしなければならない。
良い例public function admin(){ return $this->belongsTo(Admin::class); }リレーション先のデータを取得する際も単数形で指示する。
プロパティでアクセスできるのが大きな違い。例//adminに対して()をつけずにプロパティでアクセスできる。 public function scopeGetAdminName($query,$id){ return $query->find($id)->admin->name; } //EagerLoad,withのadminが単数形になるのがhasManyの時との違い public function scopeWithAdmin($query){ return $query->with('admin:id,name'); }その他
1,[docker] php:7.4.2-apacheのdockerイメージでドキュメントルートを変更する方法
/etc/apache2/sites-available/000-default.confのドキュメントルートを変更
000-default.conf<VirtualHost *:80> # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request's Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. #ServerName www.example.com ServerAdmin webmaster@localhost #ここを変更 DocumentRoot /var/www/html/
- 投稿日:2020-03-19T09:24:53+09:00
GitHub Actionsでビルドするコンテナ内でGitHubのprivate repositoryをセキュアに参照する
はじめに
GitHub Actions、便利ですよね
ソースコードの変更後、いちいち手元でdocker buildしてpushなんてやってられないですし、
外部CIツールを新たに導入するよりは全部GitHub内で完結してたほうがシンプルです。しかしながら別のprivate repositoryにある社内用ライブラリを持ってくるのが地味に面倒だったのでやり方を書きます
1行で
リポジトリsecretsにトークンを入れてBuild-time secretsでコンテナ内に注入
説明
認証方法
GitHub→GitHub内とは言え認証は必要です
httpsかsshで認証することになります
権限を細かく絞れるためトークンを介するhttps接続の方が良いと思いますhttps
下記記事のようにトークンを作成し、トークンを用いて認証します
この際、個人ユーザのトークンを利用するとアカウント削除時にトークンが使えなくなりそうなので、マシンユーザを作成してそちらでトークンを作成します。マシンユーザがcloneしたいリポジトリのread権限を持っている必要がありますDockerfileのbuildで簡単にGithubのプライベートリポジトリをクローンする方法 - Qiita
https://qiita.com/Jah524/items/fa68f99c8b787f94b884ssh
GitHubに登録してある公開鍵に対応する秘密鍵をコンテナ内に入れてしまえば接続はできます
ただユーザに許可されている全権限がついてしまうので、トークンを利用したほうがより安全ですねBuild-time secrets
リポジトリにトークンを直書きするのはもちろん、
docker build
の--build-arg
に渡す方法も安全であるとは言えません
Build-time secretsという機能があるのでこちらを使いましょうDocker Engine 18.09 から使える Build-time secrets を試してみた | はったりエンジニアの備忘録
https://blog.manabusakai.com/2018/12/docker-build-secret/コンテナにsecretsを渡す
下記ドキュメントに
repo-token
で渡すとあるので、そうすればいいのかと思ってしまいがちなのですが(1敗)、
この形で渡したトークンはActionsの中のcloneで使えるだけなので、コンテナに渡す場合は普通にenv
を使いますGITHUB_TOKENでの認証 - GitHub ヘルプ
https://help.github.com/ja/actions/configuring-and-managing-workflows/authenticating-with-the-github_tokensteps: - uses: actions/labeler@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }}コード
事前にリポジトリのsecretsに
MACHINE_USER_TOKEN
の名前でトークンを入れておきます
下記のようにファイルの形でコンテナにトークンを渡しますgithub_actions_ecr.yml- name: Build, tag, and push image to Amazon ECR id: build-image env: TOKEN: ${{ secrets.MACHINE_USER_TOKEN }} run: | echo $TOKEN >> .token DOCKER_BUILDKIT=1 docker build --secret id=token,src=.token \ -t $ECR_REGISTRY/$ECR_REPOSITORY:latest \ . rm .token docker push $ECR_REGISTRY/$ECR_REPOSITORY:latestDockerfileの1行目にマジックコメントを入れます
# syntax = docker/dockerfile:1.0-experimental
Dockerfileでは下記のように受け取ります
pyproject.tomlにはssh形式でパスを入れておく想定で(どちらでもいいのですが手元で作業する分にはsshのほうが便利)
それを置換してトークンを入れていますCOPY pyproject.toml . RUN --mount=type=secret,id=token TOKEN=$(cat /run/secrets/token) \ && sed -i "s/ssh:\/\/git@github.com/https:\/\/$TOKEN@github.com/g" pyproject.toml \ && pip install . && rm pyproject.tomlpyproject.toml[tool.poetry.dependencies] <tool_name> = {git = "ssh://git@github.com/<org>/<repo>.git", tag = "1.0"}GithubActionsのログにも秘匿化された状態で出力されています
#18 9.075 Collecting <tool_name>@ git+https://***@github.com/<略>まとめ
Build-time secretsでクレデンシャルを安全に扱いましょう
https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information