Quantcast
Channel: kakakakakku blog
Viewing all 925 articles
Browse latest View live

「学ぶ」とは何か?を理論的に知ることができた /「エンジニアの知的生産術」を読んだ

$
0
0

今年8月に出版された「エンジニアの知的生産術」を読んだ.今までも「どう効率的に仕事を進めるか」とか「どう意識高くアウトプットをし続けるか」とか「知的生産」に興味があって取り組んできたけど,本書の目次と索引を見たら,気になる用語がたくさんあった.

  • 第1章 : 新しいことを学ぶには
  • 第2章 : やる気を出すには
  • 第3章 : 記憶を鍛えるには
  • 第4章 : 効率的に読むには
  • 第5章 : 考えをまとめるには
  • 第6章 : アイデアを思い付くには
  • 第7章 : 何を学ぶかを決めるには

エンジニアの知的生産術 ──効率的に学び、整理し、アウトプットする (WEB+DB PRESS plusシリーズ)

エンジニアの知的生産術 ──効率的に学び、整理し、アウトプットする (WEB+DB PRESS plusシリーズ)

やる気

第2章では「やる気」がテーマになっていた.冒頭に「延べ12000人以上のやる気が出ない人に調査をした」と書かれていて,パワーワードすぎて笑ってしまった.紹介されているプラクティスは「GTD (Getting Things Done)」や「ポモドーロ」など,有名なものも多かったけど,他にも「タスクを1つに絞れているか」や「どのように優先順位を決めるか」や「不確定要素があるときに何を優先するか」など,考えさせられる内容になっていた.

個人的に「ポモドーロ」は5年以上続けていて,自己流の「ポモドーロ + 収穫逓減の法則」を実践している.また最近はタイムボックスを 25min → 45min に伸ばして検証をしている.

kakakakakku.hatenablog.com

また僕は「タスクが大きすぎる」と腰が重くなり「やる気」が出ないため「小さな習慣」を意識している.

kakakakakku.hatenablog.com

効率的に読む

第4章では「効率的に読む」がテーマになっていた.個人的に本を読むのが遅いことに悩んでいて,でも「速読」を解決策にしたくないとも考えていたので,第4章は本書の中で1番学びがあった.

  • 「読む」とは何?
  • 本を「読む」ことの目的は?
  • 「読む」種類は?
  • 「読む」速度は?

特に「読む速度のピラミッド」として「読む速度」を「8段階 : A / B / C / D / E / F / G / H」に分類されていたのは印象的だった.今まで「読む速度」を意識したことはなく,どんな難易度の本でも同じように読んでしまっていたことに気付いた.さらに「段階 A / B」は「読まない読み方」となり,本書の中で紹介されていた本「読んでいない本について堂々と語る方法」も気になる.

読んでいない本について堂々と語る方法 (ちくま学芸文庫)

読んでいない本について堂々と語る方法 (ちくま学芸文庫)

「読む速度のピラミッド」の手書き図は以下の記事にも載っている.

d.hatena.ne.jp

特に「段階 D / E」の「速い読み方」の中で Whole Mind Systemというプラクティスが紹介されていた.Whole Mind System では以下の段階がある(本来ある "5段階"を著者がさらに "8段階"に再構築した).

  1. 準備
  2. プレビュー
  3. フォトリーディング
  4. 質問を作る
  5. 熟成させる
  6. 答えを探す
  7. マインドマップを作る
  8. 高速リーディング

「3. フォトリーディング」は「目のフォーカスをぼかしてページ全体を眺める」読み方で,どちらかと言うと速読に近く感じるけど,例えば「見出しを中心に読む」など,自己流に粗く読むことはできそうだと気付けた.今までは1文字1文字読む癖があり,誤植をよく見つけることもあったけど,時間とトレードオフになっていた.さらに「読む速度を変えて2回読む」という発想もなく,次に本を読むのが楽しみになった.

そして「4. 質問を作る」は良かった.近い観点だと「人に教えられるように読む」「読んだ後にブログを書く(言語化する)」も重要だと思う.質問を作ることを意識しながら読み直すと,自分自身の理解度も整理できるし,僕が担当しているトレーニングでも活用できるし,メリットが多くある.

f:id:kakku22:20181113122339p:plain

(参考 : 本書を読み終わった状態)

要約の素晴らしさ

本書は多くの参考文献(本だけでなく研究成果や歴史的な背景なども含む)に支えられている.そして,参考文献の重要なポイントが要約して説明されていたり,キレイに図解されていたり,理解しやすいように工夫されている点が素晴らしかった.点と点が繋がり,深く理解されているからこそ,ここまで構成できるんだと思う.今まで知らなかった用語を箇条書きにしておく.

最後に

本書は非常に理論的かつ学術的に構成されているので,スラスラと流し読みできるような本ではないと思う.また注釈も多く,全ページが充実して書かれている.今回読んで全てを理解できたとは言えないため,本書の冒頭に書かれている以下のメッセージの通り,また半年後に読み直そうと思う.

材料がそろっていないと、結合は起きません。「地」は経験です。本書を読んでしっくりこなかったなら、今回は残念ながら材料が足りなかったようです。でも大丈夫です。経験は日々あなたの中に蓄積されていくので、いつか「あ、これか」とつながるときが来るでしょう。半年経ってからまた読みなおしてみてください。きっと何かが変わるでしょう。

正誤表

Scrapbox にまとまっている.

scrapbox.io


Vue School の無料コース「Nuxt.js Fundamentals」を受講して Nuxt.js の基礎を学んだ

$
0
0

Vue School で今月から提供されている最新の無料コース「Nuxt.js Fundamentals」をさっそく受講した.最近よく聞くようになった Nuxt.js をまだ試したことがなく気になっていて,タイミングも良かった!今まで Vue School で「Vuex for Everyone」「Vue.js + Firebase Realtime Database」「Vue.js + Firebase Realtime Database」を受講して,素晴らしく体験が良く,今回もオススメできる内容だった!

vueschool.io

Nuxt.js Fundamentals

コースは計14個の動画で構成されている.動画を見るだけなら35分で見れるし,動画を見ながら写経をするとしても,2時間あれば終わる.Nuxt.js とは何か?を速習するのに最高なコースと言える.

  • 1 : Introduction to Nuxt.js
    • What is Nuxt.js? ⏲ 3:45
    • Create Nuxt App ⏲ 1:38
    • Guided Nuxt.js Project Tour ⏲ 2:02
  • 2 : Working with Nuxt.js
    • Customize the home page ⏲ 0:56
    • Create Application Pages ⏲ 2:59
    • Global CSS ⏲ 2:31
    • Adding a Navbar to Nuxt Apps ⏲ 1:29
    • Dynamic Routes ⏲ 1:53
    • Linking Between Pages ⏲ 2:37
    • Utilising the Vuex Store ⏲ 4:13
    • SEO and Meta Tags ⏲ 3:14
  • 3 : Build & Deploy
    • Build and Serve the Nuxt.js App ⏲ 0:49
    • Deploy Nuxt.js App to Heroku ⏲ 3:47
    • Deploy Nuxt.js App to Netlify ⏲ 3:54

以下のように英語字幕が出るので,英語が苦手な人でも,問題なく受講できると思う.前回とまた少しデザインが変わっていた.

f:id:kakku22:20181121233026p:plain

(受講画面例)

github.com/vueschool/nuxt-fundamentals

Vue.js 部分を写経するとして,スタイルやスタブデータなどは写経する意味があまりなく,Vue School の GitHub リポジトリからコピーした.動画ごとにコミットされていて,助かる!

github.com

1 : Introduction to Nuxt.js

What is Nuxt.js?

  • Nuxt.js = Vue.js フレームワーク
  • Server-Side Rendering
    • SEO 対策
    • meta タグ
  • Static Generated (Pre Rendering)
  • Automatic Code Splitting

nuxtjs.org

Create Nuxt App

yarnで Nuxt.js プロジェクトを作成する.

$ yarn create nuxt-app nuxt-fundamentals
yarn create v1.9.4
(中略)
? Project name nuxt-fundamentals
? Project description My tiptop Nuxt.js project
? Use a custom server framework none
? Use a custom UI framework none
? Choose rendering mode Universal
? Use axios module no
? Use eslint no
? Use prettier no
? Author name kakakakakku
? Choose a package manager yarn

$ cd nuxt-fundamentals
$ yarn dev

yarn devでローカルサーバを起動すると http://localhost:3000にアクセスできるようになる.

f:id:kakku22:20181121233122p:plain

インストール方法の詳細はドキュメントに書いてある.

nuxtjs.org

Guided Nuxt.js Project Tour

Nuxt.js プロジェクト階層を確認した.以下は treeコマンドで第一階層を出力している.

$ tree -L1 .
.
├── README.md
├── assets
├── components
├── layouts
├── middleware
├── node_modules
├── nuxt.config.js
├── package.json
├── pages
├── plugins
├── static
├── store
└── yarn.lock

2 : Working with Nuxt.js

Customize the home page

まず Nuxt.js のロゴを Vue School のログに変更した.

f:id:kakku22:20181121233140p:plain

Create Application Pages

Nuxt.js には最初から router が入っているため pagesディレクトリにファイルを追加すると,すぐアクセスできるようになる.今回は http://localhost:3000/postにアクセスできるように pages/post.vueを追加した.

f:id:kakku22:20181121233203p:plain

Global CSS

共通となる CSS を assets/style.cssに作成し,Nuxt.js の設定ファイルとなる nuxt.config.jsに以下のような設定を追加した.

module.exports = {(中略)
  /*  ** Global CSS  */
  css: ['~/assets/style.css'],
(中略)
}

nuxtjs.org

Adding a Navbar to Nuxt Apps

次にナビバーコンポーネントを追加する.このあたりは普通に Vue.js を実装するのと同じだった.

<template>
  <nav class="nav">
    <div class="logo">
      <a href="#"class="logo text-lg">
        Nuxt Fundamentals
      </a>

      <span class="subheader">A Vue School course</span>
    </div>
  </nav>
</template>

f:id:kakku22:20181121233242p:plain

Dynamic Routes

Nuxt.js の router 機能を使って http://localhost:3000/posts/${id}という URL にアクセスできるようにした.具体的にはスタブデータの関係上,以下の 3 URL にアクセスできる.

  • http://localhost:3000/posts/balut
  • http://localhost:3000/posts/whereIsIt
  • http://localhost:3000/posts/how

f:id:kakku22:20181121233315p:plain

Linking Between Pages

リンクを nuxt-linkコンポーネントにリファクタリングして,SPA として画面遷移ができるようになった.

<template><divclass="container">(中略)
    <aside><h3>Posts you might enjoy</h3><ul><li v-for="related in relatedPosts"><nuxt-link :to="{name: 'posts-id', params: {id: related.id}}">
            {{related.title}}
          </nuxt-link></li></ul></aside></div></template>

リンク一覧を返すメソッドでは,自分自身を filterで除外する実装になっている.

computed: {(中略)
  relatedPosts () {returnthis.posts.filter(post => post.id !== this.id)
  }}

右側にリンク一覧を追加できた.

f:id:kakku22:20181121233352p:plain

nuxtjs.org

Utilising the Vuex Store

スタブデータを Vuex を使ってリファクタリングした.さらにトップページにもリンク一覧を追加した.

f:id:kakku22:20181121233626p:plain

nuxtjs.org

SEO and Meta Tags

Nuxt.js には指定した meta タグを生成する機能がある.例えば,以下のように index.vueに実装した.

<script>
import Logo from '~/components/Logo.vue'exportdefault{
  components: {
    Logo
  },
  head () {return{
      title: 'Home Page 🍕',
      meta: [{ name: 'twitter:title', content: 'Nuxt Fundamentals by Vue School'},
        { name: 'twitter:description', content: 'Nuxt + Vue School = 🍕'},
        { name: 'twitter:image', content: 'https://i.imgur.com/UYP2umJ.png'},
        { name: 'twitter:card', content: 'summary_large_image'}]}},
  computed: {
    posts () {returnthis.$store.state.posts.all
    }}}</script>

nuxtjs.org

3 : Build & Deploy

Build and Serve the Nuxt.js App

最後は yarn buildで,本番環境用に minify する.

$ yarn build
$ yarn start

Deploy Nuxt.js App to Heroku

完成した Nuxt.js プロジェクトを Heroku にデプロイする.特にハマるところはなく,通常通り Heroku に push する.

$ heroku git:remote -a xxx
$ git push heroku master

f:id:kakku22:20181121233654p:plain

nuxtjs.org

Deploy Nuxt.js App to Netlify

さらに Heroku だけではなく Netlify にもデプロイする.Netlify は静的ファイルを配信するため,今回は Netlify 側で yarn generateを実行し,生成された /distディレクトリを配信できるようにした.

$ yarn generate

f:id:kakku22:20181121233709p:plain

nuxtjs.org

まとめ

  • Vue School が公開している無料コース「Nuxt.js Fundamentals」を受講した
  • Nuxt.js で簡単なアプリケーションを実装して,Nuxt.js の基礎を学ぶことができた
  • ローカルサーバだけではなく,Heroku と Netlify にデプロイする手順も学ぶことができた
  • 今回の写経結果は GitHub に push してある

github.com

Vue School 受講履歴

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

CSV に SELECT / UPDATE クエリを実行できる VS Code の拡張機能「Rainbow CSV」

$
0
0

定期的に CSV からデータを抽出する機会があり,抽出条件によって,今までは以下のような方法を使っていた.

  • CSV を Excel で開いてフィルターを使う方法
  • CSV を grep / egrep などの Linux コマンドで絞り込む方法
  • CSV をAmazon S3 にアップロードして Amazon S3 Select でクエリを実行する方法

Rainbow CSV

新しい方法として VS Code の拡張機能「Rainbow CSV」を試すことにした.Rainbow CSV には多くの機能があり,例えば「ハイライト」「CSVLint」「RBQL (RainBow Query Language)」がある.データを抽出する用途だけでなく,CSV を確認するときにも便利で,普段から使える最高の拡張機能だった.以下からインストールできる.

marketplace.visualstudio.com

実装は GitHub に公開されていた.

github.com

サンプルデータ

今回はサンプルデータとして,よく使われる郵便番号データ KEN_ALL.CSVを使う.事前にエンコードを Shift JISから UTF-8に変換しておく必要がある.

$ nkf -w--overwrite KEN_ALL.CSV

KEN_ALL.CSVは日本郵便のサイトからダウンロードできる.

www.post.japanpost.jp

ハイライト機能

Rainbow CSV には「ハイライト機能」があり,CSV を VS Code で開くと,自動的にカラムごとに色分けされる.さらに各データにマウスを合わせるとカラム名を確認できるので,もしヘッダー行が存在する CSV の場合は便利.

f:id:kakku22:20181129104930p:plain

CSVLint 機能

Rainbow CSV には「CSVLint 機能」もあり,例えば,カラム数が異なるレコードがあるとエラーになる.大量のデータの中からフォーマットエラーを探すときに使える.

f:id:kakku22:20181129105029p:plain

RBQL (RainBow Query Language) 機能

なんと言っても Rainbow CSV で1番便利な機能は「RBQL (RainBow Query Language) 機能」で,RBQL という SQL-like なクエリ言語でデータを抽出することができる.RBQL の仕様は以下のドキュメントにまとまっている.SELECTだけだと思ったら UPDATEもサポートされていた!CSV を UPDATEで更新できるのはスゴイ!

  • SELECT [ TOP N ] [ DISTINCT [ COUNT ] ]
  • UPDATE [ SET ]
  • WHERE
  • ORDER BY ... [ DESC | ASC ]
  • [ [ STRICT ] LEFT | INNER ] JOIN
  • GROUP BY
  • LIMIT N

github.com

SELECT を試す

実際に以下のクエリを実行した.単純な SELECTだけじゃなく WHEREGROUP BYも使えた.

SELECT * LIMIT 5SELECT * WHERE a1 == '01101' LIMIT 20SELECT a7, COUNT(*) GROUPBY a7

f:id:kakku22:20181129105108p:plain

(RBQL 実行画面)

UPDATE を試す

1行 UPDATEも複数行 UPDATEも実行できた.なお SELECTUPDATE「別ファイルとして」結果が出るため,直接ベースファイルを書き換えることはなく,誤った RBQL を実行しても影響なしという安心感も良かった.

UPDATESET a4 = 'aaaaa'WHERE a3 == '0600000'UPDATESET a4 = 'aaaaa'WHERE a1 == '01101'

RBQL backend language を試す

RBQL backend language を使うと RBQL を拡張できる.現状だと JavaScript と Python がサポートされている.

  • JavaScript – RBQL backend language
  • Python – RBQL backend language

今回は JavaScript を使って RBQL を拡張してみた.

-- 郵便番号が "15060" で始まるデータを抽出するSELECT * WHERE a3.indexOf("15060") == 0-- データとは関係なく乱数を10件出力するSELECT Math.random() * 100 LIMIT 10-- データとは関係なく文字列を結合して出力するSELECT'ka'.repeat(3) + 'kakku' LIMIT 5

クエリを実行したら「恵比寿ガーデンプレイスって階ごとに郵便番号が違うんだー」ということを発見した.今まで知らなかった!

f:id:kakku22:20181129105130p:plain

Rainbow CSV : Vim Plugin

github.com

Rainbow CSV は Vim Plugin もあり,以下のように ~/.vimrcを設定するとインストールできた.VS Code と同じく「ハイライト機能」があり,さらに F5を押して Vim から RBQL を実行することもできた.インストールしておくべき Vim Plugin だと思う.

NeoBundle 'mechatroner/rainbow_csv'

f:id:kakku22:20181129105217p:plain

まとめ

  • VS Code の拡張機能「Rainbow CSV」は便利!
    • ハイライト機能
    • CSVLint 機能
    • RBQL (RainBow Query Language) 機能
  • Rainbow CSV には Vim Plugin もある

HTML の Lint ツール「htmllint」を CircleCI で実行する

$
0
0

HTML を実装しながら Lint を実行するため「htmllint」を使うことにした.類似ライブラリに「HTMLHint」もある.

github.com

htmllint と htmllint-cli

「htmllint」を CLI で実行する場合は「htmllint-cli」を使う.

github.com

以下のように npm で htmllint-cli をインストールして,プロジェクトのルートディレクトリで htmllint initを実行すると,設定ファイルの .htmllintrcがデフォルトルールで自動生成される.Lint ルールをカスタマイズする場合は .htmllintrcを変更する.

$ npm install -g htmllint-cli

$ htmllint --version
0.0.7

$ htmllint init

$ htmllint sample.html

検証

検証用にサンプル HTML を実装しながら,適宜 htmllint を実行したところ,以下を確認できた.

  • the tag must contain a title
    • head タグに title タグを下記忘れていると検出される
    • カスタマイズする場合は .htmllintrchead-req-titleの設定を変更する
  • indenting spaces must be used in groups of 4
    • 4 スペース以外のインデントがあると検出される
    • カスタマイズする場合は .htmllintrcindent-widthの設定を変更する
  • id value must match the format: underscore
    • id 名にハイフンがあると検出される
    • カスタマイズする場合は .htmllintrcid-class-styleの設定を変更する
  • class value must match the format: underscore
    • class 名にハイフンがあると検出される
    • カスタマイズする場合は .htmllintrcid-class-styleの設定を変更する
  • the id attribute is not double quoted
    • id 名にクォートを忘れていると検出される
    • カスタマイズする場合は .htmllintrcattr-quote-styleの設定を変更する
  • the class attribute is not double quoted
    • class 名にクォートを忘れていると検出される
    • カスタマイズする場合は .htmllintrcattr-quote-styleの設定を変更する
  • the id "wrapper" is already in use
    • id 名が重複していると検出される
    • カスタマイズする場合は .htmllintrcid-no-dupの設定を変更する

Lint として基本的なルールは揃っている.デフォルト OFF になっているルールも多く,全ルールを確認するには公式 Wiki を見る.

github.com

Dockerized

次に HTML を GitHub に push したら自動的に CI で htmllint を実行するため,事前準備として htmllint を Dockerized した.Docker Hub から kakakakakku/htmllint-cliイメージを落とせば使える.

$ docker pull kakakakakku/htmllint-cli
$ docker run kakakakakku/htmllint-cli --version
$ docker run -v${PWD}:/assets kakakakakku/htmllint-cli --cwd /assets

CircleCI で htmllint を実行する

次は CircleCI で .circleci/config.ymlを以下のように書く.

version:2jobs:htmllint:docker:- image: kakakakakku/htmllint-cli
    steps:- checkout
      - run: htmllint --cwd .

workflows:version:2ci:jobs:- htmllint

試しにサンプル HTML を push すると,期待通りにエラーになった.

f:id:kakku22:20181130104707p:plain

まとめ

  • 「htmllint」を使うと HTML に Lint を実行できる
    • CLI で実行する場合は「htmllint-cli」を使う
  • CircleCI で htmllint を実行するために Dockerized した
  • HTML も CI しよう!

多くの CircleCI ファンが集まった「CircleCI Japan User Community Kickoff」に参加した

$
0
0

12/3 (月) にサイボウズ様オフィスで開催された「CircleCI Japan User Community Kickoff」に参加した.今回は招待制のプライベートイベントで,CircleCI を日頃から圧倒的に活用している人たちが集まっていたので,有名人多すぎでは?という感じだった.僕は CircleCI 関連のブログを多く書いているということで招待して頂いた.ありがとうございます!

f:id:kakku22:20181203233933j:plain

(参加者に配られたノベルティ!)

CircleCI User Community @kemorimo & @kimhirokuni

  • CircleCI User Community
    • 「CircleCI ファンのためのコミュニティ」を作る
    • 今後使うハッシュタグ「#circlecijp」
  • 最近のリリース情報

サイボウズを支える CircleCI @miyajan

  • 今までは Jenkins + Drone を使っていた
  • CircleCI 導入開始
    • 1.0 → 2.0 になり,使えるようになった
  • CircleCI Server (Enterprise) 導入
  • 事例
    • 1日1回 CicleCI 経由で VPC を再構築する(常に自動化を試す)
  • Performance Pricing Plan
    • コンテナ数課金ではなく,必要なときに従量課金で使える
  • CircleCI Config 2.1
    • config.yml : 1462行 → 923行 に削減
    • Orbs 未導入

Workflow の並列度が高く,大規模に CircleCI を活用している事例だった.さらに Config 2.1 に移行して config.ymlを削減できたとのこと.発表にもあった通り,Orbs を導入すればもっと削減できそう.VPC を1日1回再構築する運用も Infrastructure as Code のお手本として素晴らしかった.

www.slideshare.net

Mercari Frontend の CircleCI 活用事例 @urahiroshi

  • フロントエンドデプロイ
    • 今までは CircleCI でテストだけを実施して,サーバでビルドをしていた
    • CircleCI でビルドをして,Amazon S3 に保存するようにした
    • サーバで Amazon S3 から .tar をダウンロードすれば動くようになった
  • Storybook デプロイ
    • プルリクエスト単位に Storybook を見れるように
    • CircleCI で Amazon S3 に保存して,Amazon CloudFront からアクセスできるように
    • プルリクエスト番号を取得するために ${CIRCLE_PULL_REQUEST}を使う
  • 脆弱性検知

CircleCI と Amazon S3 を組み合わせてうまく CI / CD を実現している事例だった.場合によっては CircleCI Build Artifacts も使えるかも?と感じた.さらに npm auditを Orbs 化して公開されているのも素晴らしかった.npm を使ってるリポジトリにさっそく導入してみる予定!

How Quipper Works with CircleCI

monorepo だと全体的なビルド時間が長くなる点が大変そうだなと感じたけど,サブディレクトリごとに変更を検知する仕組みがあるのは良かった.CircleCI 関連ツールは興味深くて,さっそく circle-gh-tee を導入してみる.ここまで Infrastructure as Code 化できていると運用も安心してできそう.

CircleCI の Job 突然死と戦った話 @0gajun

  • Performance Pricing Plan 最高
  • 1ヶ月に 533,881分 = 1年 もビルドを実行している
  • resource_classmediumsmallに変更したら多くのジョブが落ちるようになった
    • 具体的には attach_workspaceが落ちるようになった
    • 原因は OOM Killer
    • cgroup の memory.max_usage_in_bytesなどを調査した
    • attach_workspaceを実行しているときに page cache の増加が確認できた
    • コンテナだと page cache を削除する権限がなかった
  • 現在まだ根本解決になってなく mediumを使っている

Performance Pricing Plan の resource_classを変更したときに発生したエラー調査報告だった.活用事例だけではなく,調査事例も非常に参考になる.CircleCI サポートと連携して原因特定に奮闘しているプロセスも素晴らしく,さらに page cache の増加が確認できた段階に至るステップバイステップの調査内容も参考になった.根本解決になることを期待している!

(資料公開待ち)

CircleCI Orbsの紹介 @ks888sk

  • Orbs 機能紹介
  • Explore Orbs で Orbs を検索できる
  • Good Practices
    • 1 : 実行時間を見積もる
      • 実行時間が長くなる場合に回避策を用意する
      • max-waitオプションを実装した
    • 2 : メッセージ部分を強調する
      • 文字色を付ける
      • 絵文字を付ける
    • 3 : CI / CD
      • Orbs を公開するためにも CircleCI を使う
      • テスト用設定ファイルを使う

そろそろ Orbs を使おうと思っていたため,Good Practices を聞けたのは良かった.特に OSS だから使う側のシチュエーションを想定して max-waitオプションを実装したという話は素晴らしい.紹介されていた h-matsuo/github-releaseはさっそく導入してみる.

CircleCI オンプレ版 Builder インスタンスのスケールインの話

  • CircleCI Server (Enterprise) では Builder インスタンスで Hashicorp Nomad が動いている
  • Builder インスタンスを Auto Scaling するときに「減らすテクニック」が必要になる
  • Auto Scaling Lifecycle Hooks / SQS / Lambda を組み合わせて,Builder インスタンスを安全に停止している

個人的に CircleCI Server (Enterprise) の経験がなく,運用関連の話を聞けて良かった.実行中のプロセスに影響なくスケールインするためにはドレイニング機能が必須で,Nomad の API を使って実現しているのは CircleCI に限らず参考になる.

(資料公開待ち)

まとめ

  • プライベートイベント「CircleCI Japan User Community Kickoff」に招待して頂いた
  • 圧倒的に活用している人たちが集まっていたので,どの発表も素晴らしかった
    • たまに「CircleCI Workflows ビューティフル選手権」に参加しているのかな?という気持ちになった(笑)
  • 今後 CircleCI Japan User Community を盛り上げていくとのことで,応援!僕もできる限り参加したいと思う

ポッドキャスト

CircleCI のアーキテクチャ / 開発プロセスの話が聞けるポッドキャストもある!オススメ!

fukabori.fm

CircleCI Orbs ミニハッカソン

12/15 に Orbs リリースを記念したイベントが開催される.まだ参加できるので Orbs に興味がある人は参加すると良いのでは!

circleci.connpass.com

関連資料

builderscon 2018 の資料を見ると CircleCI / Nomad の詳細を知ることができる.合わせて読むと良さそう!

プログラミング初心者に教えるときは「身近な比喩」が重要なのだ!

$
0
0

今日は「Rails Developers Meetup 2018 Day 4 Nouvelle Vague」に参加し,教育関連のネタで登壇をしてきた!パブリックイベントに登壇するのは約半年振りで,やはり登壇するのは楽しいなぁー!という気持ちになった.あと登壇前に司会者から「ブロガーの吉田さん」と呼ばれて,あまりにダサすぎて吹いた!笑

techplay.jp

登壇資料

伝えたかったこと

  • プログラミング初心者に教えるときに「身近な比喩」を使うと良い
    • プログラミング講師に限らず,誰でも「教える(伝える)機会」はある
  • 教えるときに重要なのは「生徒さんと同じ目線で考えられること」
    • そして「粘り強く何度でも伝え,常に笑顔でいること」
  • 「身近な比喩」の引き出しを増やそう!

関連書籍

「チェリー本」は初心者を対象にした本ではないものの「第11章 : Ruby のデバッグ技法を身につける」の内容が素晴らしく,プログラミング初心者は「第11章」のために「チェリー本」を買っても良いと思う.

2週間前に発売された「超入門本」は本当に初心者でも理解できるように工夫されていて素晴らしかった.今後はプログラミング初心者に「超入門本」を紹介しようと思う.今月中に書評を書く予定!

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

まとめ

  • Rails Developers Meetup 最高!
  • 登壇依頼は @yoshi_hirano さんに頂いた!ありがとうございました!

関連記事

今回のネタは今年1月に「表参道.rb」で登壇した内容をベースにブラッシュアップした.

kakakakakku.hatenablog.com

「チェリー本」は今年1月に書評を書いている.

kakakakakku.hatenablog.com

Rubyist が学び合うカンファレンス「Rails Developers Meetup 2018 Day 4」に参加した

$
0
0

12/8 (土) に開催された「Rails Developers Meetup 2018 Day 4 Nouvelle Vague」に参加した.イベント名に「Rails」と付いているものの,トークテーマは多岐にわたり,エンジニアなら誰でも楽しめるように工夫されていた.また YouTube ライブ配信もあり,リモート参加者も大切にするホスピタリティを感じたし,イベント運営プロジェクトのクオリティの高さに驚かされた!参加したトークの中で印象的なものを抜粋して紹介したいと思う.

techplay.jp

今回は僕も登壇をして,既に資料を公開している.内容的に Non-Tech だからイベントの趣旨と合わなかったらどうしよう!と不安もあったけど,オーディエンスの反応を読みながら楽しく登壇できた!えーっと「プレゼン芸人感」は出てた?笑

kakakakakku.hatenablog.com

ZOZOTOWN のバッチデータ転送基盤の紹介

  • Embulk + Digdag
    • Digdag Ruby scripts Operators も併用している
  • 多くの集計ジョブがある
  • CircleCI : データアナリストが実装した SQL 構文を CI している

Embulk + Digdag を活用した集計基盤のアーキテクチャ事例だった.後半に紹介されていたジョブ依存図は圧倒的な複雑さで大変そうだけど,どこまで Digdag を使っているんだろう?という点は興味を持った.構成次第だけど Embulk も Digdag も Dockerized すると今より運用しやすくなる可能性もありそう.登壇中にちょこちょこと ZOZO に関係する時事ネタが出てきて,笑ってしまった!

(資料公開待ち)

Rails x パターン @junk0612

  • 単一テーブル継承 (STI : Single Table Inheritance)
    • 出典 : 書籍「エンタープライズ アプリケーション アーキテクチャパターン」
    • サブクラスの追加に柔軟に対応できる
    • ただし,サブクラスのカラムに NOT NULLが付けられない
  • フォームオブジェクト
    • 出典 : 不明
    • 複数のモデルにまたがった処理を1箇所にまとめることができる
    • ただし,app/formsに多くのファイルが置かれてしまう
  • 勘定
    • 出典 : 書籍「アナリシスパターン」
    • 「取引モデル」と「勘定科目モデル」に分割して,勘定科目の合計金額が 0 になるようにバリデーションを実装する
  • パターン中毒
    • 導入前に本当に必要なのか?を議論する

「パターン」に興味を惹かれるエンジニアは多いと思う.計3種類のパターンが紹介されていて,特に STI とフォームオブジェクトに関しては Twitter のハッシュタグが盛り上がっていたので,ツイートを見ながら登壇を聞くというリアルタイムな体験は良かった!あと「PofEAA」と呼ばれる書籍「エンタープライズ アプリケーション アーキテクチャパターン」は読んだことがなく,気になる!個人的には「登壇直前に資料が完成した」と冒頭で言っていた点が気になり,実際に資料にミスもあり,もう少し準備をするべきかも?と感じた.

エンタープライズ アプリケーションアーキテクチャパターン (Object Oriented SELECTION)

エンタープライズ アプリケーションアーキテクチャパターン (Object Oriented SELECTION)

  • 作者:マーチン・ファウラー,長瀬嘉秀,株式会社テクノロジックアート
  • 出版社/メーカー:翔泳社
  • 発売日: 2005/04/21
  • メディア:大型本
  • 購入: 10人 クリック: 635回
  • この商品を含むブログ (143件) を見る

FiNC での5年間に渡るマイクロサービスの育て方

  • 開始
    • 開発案件を受託する形からスタートした
    • 最初はローカル環境から cap deploy productionを実行していた
    • FiNC に吸収される形で JOIN した
  • 成長期
    • 多くの機能が必要になり,モノリシックでは難しいと判断した
    • 「遺伝子検査の閲覧機能」を新規に Rails で実装した
      • これが FiNC のマイクロサービスのはじまり
  • 加速期
    • 一部のサービスに依存が強くなり「神サービス」になってしまった
      • BFF (Backend For Frontend) を導入する
  • グロース期
    • 積極的にマイクロサービス化とリアーキテクトを実施している
    • BFF は Kotlin で実装し直した

非常に刺激的な内容だった!単純にマイクロサービス化を進めるという話ではなく,スタートアップの成長フェーズによって適切な技術選定をし,さらに組織的な改善も日々しているんだろうなという苦労が感じられた.プロダクション環境で稼働中のモノリシックサービスをマイクロサービスに切り出すのは「言うは易く行うは難し」なので,ここまでリアーキテクトを実践されているのは本当に素晴らしい!

二人チームにおけるバックエンド開発の効率化を求めて @okuramasafumi

まさにスタートアップ!という状況の中,ライブラリを適切に選定し,開発プロセスに組み込んでいる事例だった.個人的には2人だとプルリクエストのレビューが止まったりして,期待するほどリードタイムが上がらない場合もあるので,せめて3人だったら良いのに!とは思った.RuboCop の .rubocop.ymlにオーディエンスの興味関心があったこともあり,お昼休憩中に .rubocop.ymlを紹介する飛び込み LT をされていたのも素晴らしかった!

The Cacher in the Rye

キャッシュを「使わない」という話だった.キャッシュは「諸刃の剣」であるという理解はあるものの,レスポンスタイムを短くするためにプロダクション環境で Memcached / Redis などを使っていた経験もあり,耳が痛い部分もあった.Memcached を使う場合は eviction をモニタリングするのもわかる.資料には「十分なリソースがあればキャッシュは不要」と書いてあったけど,例えば頻繁に実行されるクエリなど,実際にどのように対応しているんだろう?という点はもう少し聞きたかった.

複数のスタートアップを通して得た失敗と学び @threetreeslight

  • Repro 創業者
    • 現在 VPoE
  • 「失敗談」にフォーカスする
    • 失敗軸 : プロダクト / 組織 / 採用 / 技術
  • 0 → 1
  • 1 → 10
    • システム費を無理に削減せずに保守性を考える
  • 10 → 30
    • 採用に専念する
    • 平均以上なら採用する
  • 30 → 50
    • 要望に追われる
    • 雑な設計のスケール限界が見える
  • 50 → 100
    • リリースマネージャに権限委譲する
    • ミドルマネージャの数が組織規模の限界を決める
  • 100 → 300
    • Corporate Operations Engineer(≒ 社内 SE)を専任化する
      • できるなら「社内 SE」と呼ばない
  • 300 → ?

Ruby / Rails とは少し異なるテーマだけど,個人的にはベストトークだった!プレゼンスキルも圧倒的だった!そして「失敗談を楽しく語れる」ことの素晴らしさ(と強さ)を感じた.テクニカルサポートを当番制にしたり,サービスを伸ばすために個別要望に対応したら実装が破綻したり,アーキテクチャのスケール限界が見えたり,実体験とシンクロするあるある話もありつつ,ここまで言語化された資料も貴重なので,スタートアップ界隈は1度読むと良いのでは!

gitpitch.com

まとめ

  • 「Rails Developers Meetup 2018 Day 4 Nouvelle Vague」に参加した(計13トーク)
    • 僕も登壇した!
  • Ruby / Rails に限らず,トークテーマが多岐にわたり,エンジニアリング全般を学べるカンファレンスだった
  • イベント運営プロジェクトのクオリティが高かった
  • お疲れさまでした!

2018年のプルリクエストを振り返る

$
0
0

今年も OSS に送ったプルリクエストを振り返る.過去2年間の振り返りは以下の記事にある.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

プルリクエストを振り返るための検索

GitHub には Issue / プルリクエストを検索するための条件式があり,以下のように検索すると「今年 OSS に送ったプルリクエスト一覧」を確認することができる.便利!

is:pr is:public author:kakakakakku -user:kakakakakku created:2018

条件式は以下のドキュメントに詳しく載っている.

f:id:kakku22:20181215214709p:plain

2018/01

mackerelio/mackerel-plugin-aws-ecs

Mackerel で Amazon ECS クラスタのメトリクスを取得するプラグイン「mackerel-plugin-aws-ecs」を試したときに,README に書かれているコマンド名が間違っていたので,修正した.記念すべきプルリクエスト1番目になった!

github.com

「mackerel-plugin-aws-ecs」を試した結果は以下の記事にまとめてある.

kakakakakku.hatenablog.com

getredash/redash

「Elasticsearch」はよく誤って「ElasticSearch」や「Elastic Search」と表記されることがある.Redash の Data Sources も「ElasticSearch」と表記されていて,気になっていたところを修正した.

github.com

getredash/website

Redash のドキュメントにも多くの「ElasticSearch」があり,全てを「Elasticsearch」に修正した.リポジトリ全体を何度も grep しながらセルフレビューをした.

github.com

2018/03

silinternational/ecs-deploy

2017年からコントリビュートをしている ecs-deploy の README を読んでいたら typo を発見して,修正した.

github.com

aws-samples/aws-workshop-for-kubernetes

Kubernetes を学ぶために GitHub に公開されているワークショップ資料「aws-workshop-for-kubernetes」を試していたときに,Istio のバージョンが手順書よりも新しくなっていることが原因でエラーになったので,ワイルドカードを使った手順に修正した.

github.com

ワークショップ資料「aws-workshop-for-kubernetes」のまとめは以下の記事にある.

kakakakakku.hatenablog.com

2018/04

silinternational/ecs-deploy

春頃にリリースされた Amazon ECS の「Force New Deployment 機能 (--force-new-deployment)」を ecs-deploy でも使えるようにした.この頃から ecs-deploy の Contributors を見ると上位(トップ6)に上がっている.

github.com

2018/06

aws/aws-codedeploy-agent

AWS CodeDeploy を導入するときに,Ruby で実装された AWS CodeDeploy Agent のコードを読んでいたら,たまたま typo を発見して,修正した.

github.com

2018/12

awslabs/aws-cloudformation-templates

Amazon SQS の AWS CloudFormation テンプレートを調査していたら,Description セクションに書いてある FIFO キュー対応リージョンが古くなっていたので,最新情報に合わせて修正した.

github.com

silinternational/ecs-deploy

ecs-deploy で使っている Alpine Linux 3.5 が 2018/11/01 で End of Support になったため,現時点で最新となる Alpine Linux 3.8 に移行した.さらに一部のテストコードに誤ったシェルの構文があり,Alpine Linux 3.8 だとエラーになるため,合わせて修正した.

github.com

Alpine Linux の End of Support 情報は以下の公式 Wiki に載っている.

silinternational/ecs-deploy

Amazon ECS が AWS Systems Manager Parameter Store の SecureString をサポートしたため,ecs-deploy でも使えるようにした.もともと別のプルリクエストが出ていたけど,実装方法が間違っていて,このままマージされると困るので,参考実装の意味も込めてプルリクエストを送った.うまく動作しているとコメントをもらえているため,テストコードを追加したら WIP を外す.

github.com

awslabs/aws-cloudformation-templates

AWS Identity and Access Management (IAM) の AWS CloudFormation テンプレートを調査していたら typo と正式名称の誤りを発見して,修正した.awslabs/aws-cloudformation-templatesは AWS CloudFormation の勉強に便利!

github.com

まとめ

今年は計11個のプルリクエストを送ることができた.機能追加よりもドキュメント修正の方が多かったけど,実際に仕事で使っているライブラリを少しでも改善できて良かった.あとプルリクエストではないけど,今年は必要なライブラリを自分で Dockerized して Docker Hub に公開することも多かった.来年も仕事で使うライブラリを中心にプルリクエストを送れるように頑張るぞ!


プログラミング初心者だけじゃなくプログラミング講師も読むべき一冊だった /「ゼロからわかる Ruby 超入門」を読んだ

$
0
0

11月末に発売された「ゼロからわかる Ruby 超入門」を読んだ.最近まで2年ほどプログラミング講師として Ruby / Ruby on Rails を教えていたので,プログラミング初心者に教えるノウハウが得られたら良いなと考えていた.そして本書は「本当にプログラミング初心者でも挫折せずに読める」素晴らしい本だった.タイトルに「超入門」とあるけど,個人的には「超入門(から中級まで幅広く)」かなと感じた.なぜかと言うと,本書を読み進めていくと,例えば .methods.instance_variablesなど,中級レベルの内容も出てくるから.今回はプログラミング講師の観点で書評を書きたいと思う.

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

目次

  • CHAPTER 1 : 環境をつくる
  • CHAPTER 2 : かんたんなプログラムを書く
  • CHAPTER 3 : 処理の流れを変える
  • CHAPTER 4 : まとめて扱う - 配列
  • CHAPTER 5 : 便利な道具を使う
  • CHAPTER 6 : 組で扱う - ハッシュ
  • CHAPTER 7 : 小さく分割する - メソッド
  • CHAPTER 8 : 部品をつくる - クラス
  • CHAPTER 9 : 部品を共同利用する - モジュール
  • CHAPTER 10 : Webアプリをつくる
  • CHAPTER 11 : 使いこなす

オススメの読み方を考えた

あくまで参考程度にどうぞ!

プログラミング初心者には「無理に1回で読まず,一歩一歩自信を付けながら,繰り返し読むと良いよ!」と伝えたい.

  • 「超入門」1周目
    • CHAPTER 1 から CHAPTER 7 までを読む(メソッドまで)
    • 「写経」をする
    • Challenge は全部スキップする
    • 練習問題も全部スキップする
  • 「超入門」2周目
    • CHAPTER 1 から CHAPTER 11 までを全て読む
    • 「写経」をする
    • Challenge は全部スキップする
    • 練習問題を全部解く(実際にプログラムを書いて動作確認をする)
  • 「超入門」3周目
    • 苦手意識のある CHAPTER をピックアップして読み直す
    • Challenge を全部読む

インストール手順まで細かく書いてあって良い 👌

CHAPTER 1 で「Windows / Mac に Ruby をインストールする手順」がキャプチャ付きで載っている.今後キャプチャが変わってしまう可能性はあると思うけど,それでもインストールで挫折してしまう人を救うために載っているんだと思う.また「Windows / Mac に Visual Studio Code をインストールする手順」もキャプチャ付きで載っていて,日本語化 / ショートカットなどの絶対に必要になる Tips も丁寧に紹介されている.1点気になったのは Windows は Ruby 2.5 系なのに Mac は Ruby 2.3 系なところ.とは言え,最初に rbenv の話が出てくるとプログラミング初心者は絶対に挫折するので,検討された結果こうなっているんだと思う.

エラーに挫折しないように書かれていて良い 👌

プログラミング初心者は「エラーが出ると思考停止」してしまう.実際に教えているときにエラーが出て「何もわからない!お手上げ!」と悩まれている生徒さんが多くいた.そんなときに僕は「エラーを楽しみましょう!エラーは誰でも出ますから!」と伝えるようにしていた.本書では CHAPTER 1 で「打ち間違いを確認しよう」「全角スペースが入っていないか確認しよう」など,頻発パターンが紹介されているので,実際にエラーが出ても落ち着いて解決できるように書かれている.

さらに CHAPTER 2 ではもう1步踏み込んでいて「エラーメッセージを読み解く方法」が書かれている.エラーが出ると思考停止してしまう理由の1つは「英語や記号がたくさん並んでいてよくわからない」という点にあるので,エラーメッセージの説明は価値がある.僕は「NameError とか SyntaxError とか,エラーの原因を特定するヒントになる部分を探してみよう!」と伝えることが多い.さらに「Did you mean?」も説明されていたのも良かった.

身近な比喩やイメージしやすいシチュエーションが良い 👌

「変数はオブジェクトに付ける名札である」「irb はプログラムを1行ずつ実行できる道具である」など,身近な比喩で説明されている.他にも比喩ではないけど,メソッド引数のデフォルト値を説明するときに「カフェに幾度か通って同じ注文を続けたため、注文を言わなくてもコーヒーが出てくるようになったとしましょう」というイメージしやすいシチュエーションで説明されている点も良かった.プログラミングを学ぶときに「機能は理解できたけど,実際にどんな場面で使えば良いのだろう?」という状態に陥ってしまうことが多いため,使えそうなシチュエーションを知ることにも価値がある.

deforder(item = "コーヒー")
  "#{item}をください"end

puts order # コーヒーをください
puts order("カフェラテ") # カフェラテをください
puts order("モカ") # モカをください

キャラクターが可愛くて良い 👌

本書では多くのページに図解があり,プログラミング初心者でもイメージしやすいように工夫されている.さらにキャラクター(ゆるキャラ)がとても可愛く,例えば「整数オブジェクトさん」「文字列オブジェクトさん」などが登場する.僕のお気に入りは「ハッシュオブジェクトさん」で,実際に Ruby を教えるときに「ハッシュオブジェクト」は理解してもらうのが難しく,今後はこの「ハッシュオブジェクトさん」を見てもらえば良さそう!キャラクターの裏話は以下の記事に書いてある.

note.mu

また以下の書評記事には「pop メソッドのビューン」が挙がっているけど,僕は P.184 に出てくる「Drink クラスからDrink クラスのオブジェクトがベルトコンベアに乗って出てくる工場みたいなキャラクター」が好き.この図解があればクラスも教えやすくなる!

pupupopo88.hatenablog.com

Kindle で読みにくい 💦

あえて改善ポイントを挙げるとするならば,Kindle で読みにくいところだと思う.Amazon の商品ページにも記載がある通り,本書は現時点だと固定レイアウトになっているので,ハイライトや検索ができない.さらに解像度?もあまり高くなく,iPad や MacBook で見ると,文字や図解が滲んで見えた.

※この商品は固定レイアウトで作成されており,タブレットなど大きいディスプレイを備えた端末で読むことに適しています。また,文字列のハイライトや検索,辞書の参照,引用などの機能が使用できません。

プログラミング初心者に教えるときは「身近な比喩」が重要なのだ!

先週「Rails Developers Meetup 2018 Day 4 Nouvelle Vague」で登壇をしたときにも本書を引用した.プログラミング初心者だけじゃなく,プログラミング講師も読むべき一冊だと思う.是非,登壇資料も合わせて見てもらえると!

kakakakakku.hatenablog.com

まとめ

  • 「ゼロからわかる Ruby 超入門」を読んだ
  • 本当にプログラミング初心者でも挫折せずに読める素晴らしい本だった
  • 本書のレベルは「超入門(から中級まで幅広く)」だと思う
  • プログラミング初心者だけじゃなくプログラミング講師も読むべき一冊

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

知っておくと便利な MySQL の GROUP_CONCAT 関数

$
0
0

最近 MySQL で SQL の相談を受けたときに「もしかしたら GROUP_CONCATが使えるかも?」というアドバイスをした.GROUP BYだけではなく GROUP_CONCATも知っておくと便利なので,今回は GROUP_CONCATの紹介記事を書く.

GROUP_CONCATとは?

GROUP_CONCATを使うと GROUP BYで集約をしたレコードのデータを「連結した文字列として」返すことができる.

検証用データセット

今回は MySQL 5.7 で,MySQL から公式に公開されているデータセット「world database」を使って検証をする.

既に「world database」を含めた Docker イメージを公開しているので,今回は kakakakakku/mysql-world-database:5.7を使う.

$ docker pull kakakakakku/mysql-world-database:5.7
$ docker run -eMYSQL_ALLOW_EMPTY_PASSWORD=yes -d kakakakakku/mysql-world-database:5.7
$ docker exec-it$(docker container ls | grep'kakakakakku/mysql-world-database' | awk '{print $1}') /bin/sh

詳しくは以下の記事にまとめてある.

kakakakakku.hatenablog.com

GROUP_CONCATを試す

まず「日本の都市名」を都道府県ごとに集計し,連結した文字列として返す SQL を書く.

SELECT District, COUNT(Name), GROUP_CONCAT(Name)
FROM city
WHERE CountryCode = 'JPN'GROUPBY District
ORDERBY COUNT(Name) DESC;

実行すると,以下のように「日本の都市名」をカンマ区切りで取得できる.データセットの問題で,予想以上に「日本の都市名」が少ないこともわかる.

mysql> SELECT District, COUNT(Name), GROUP_CONCAT(Name)
    -> FROM city
    -> WHERE CountryCode = 'JPN'
    -> GROUPBY District
    -> ORDERBY COUNT(Name) DESC;
+-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| District  | COUNT(Name) | GROUP_CONCAT(Name)                                                                                                                                                                         |
+-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Osaka     |          22 | Osaka,Sakai,Higashiosaka,Hirakata,Toyonaka,Takatsuki,Suita,Yao,Ibaraki,Neyagawa,Kishiwada,Izumi,Moriguchi,Kadoma,Matsubara,Daito,Minoo,Tondabayashi,Kawachinagano,Habikino,Ikeda,Izumisano |
| Saitama   |          21 | Urawa,Kawaguchi,Omiya,Kawagoe,Tokorozawa,Koshigaya,Soka,Ageo,Kasukabe,Sayama,Kumagaya,Niiza,Iruma,Misato,Asaka,Iwatsuki,Toda,Fukaya,Sakado,Fujimi,Higashimatsuyama                         |
| Chiba     |          19 | Chiba,Funabashi,Matsudo,Ichikawa,Kashiwa,Ichihara,Sakura,Yachiyo,Narashino,Nagareyama,Urayasu,Abiko,Kisarazu,Noda,Kamagaya,Nishio,Kimitsu,Mobara,Narita                                    |
| Tokyo-to  |          18 | Tokyo,Hachioji,Machida,Fuchu,Chofu,Kodaira,Mitaka,Hino,Tachikawa,Hitachinaka,Ome,Higashimurayama,Musashino,Higashikurume,Koganei,Kokubunji,Akishima,Hoya                                   |
| Aichi     |          15 | Nagoya,Toyohashi,Toyota,Okazaki,Kasugai,Ichinomiya,Anjo,Komaki,Seto,Kariya,Toyokawa,Handa,Tokai,Inazawa,Konan                                                                              |
| Kanagawa  |          15 | Jokohama [Yokohama],Kawasaki,Sagamihara,Yokosuka,Fujisawa,Hiratsuka,Chigasaki,Atsugi,Yamato,Odawara,Kamakura,Hadano,Zama,Ebina,Isehara                                                     |
| Hyogo     |          11 | Kobe,Amagasaki,Himeji,Nishinomiya,Akashi,Kakogawa,Takarazuka,Itami,Kawanishi,Sanda,Takasago                                                                                                |
| Hokkaido  |          10 | Sapporo,Asahikawa,Hakodate,Kushiro,Obihiro,Tomakomai,Otaru,Ebetsu,Kitami,Muroran                                                                                                           |
| Shizuoka  |           9 | Hamamatsu,Shizuoka,Shimizu,Fuji,Numazu,Fujieda,Fujinomiya,Yaizu,Mishima                                                                                                                    |
| Mie       |           6 | Yokkaichi,Suzuka,Tsu,Matsusaka,Kuwana,Ise                                                                                                                                                  |
| Yamaguchi |           6 | Shimonoseki,Ube,Yamaguchi,Hofu,Tokuyama,Iwakuni                                                                                                                                            |
| Fukuoka   |           5 | Fukuoka,Kitakyushu,Kurume,Omuta,Kasuga                                                                                                                                                     |
| Gumma     |           5 | Maebashi,Takasaki,Ota,Isesaki,Kiryu                                                                                                                                                        |
| Hiroshima |           5 | Hiroshima,Fukuyama,Kure,Higashihiroshima,Onomichi                                                                                                                                          |
| Ibaragi   |           5 | Mito,Hitachi,Tsukuba,Tama,Tsuchiura                                                                                                                                                        |
| Fukushima |           4 | Iwaki,Koriyama,Fukushima,Aizuwakamatsu                                                                                                                                                     |
| Gifu      |           4 | Gifu,Ogaki,Kakamigahara,Tajimi                                                                                                                                                             |
| Kyoto     |           4 | Kioto,Uji,Maizuru,Kameoka                                                                                                                                                                  |
| Nagano    |           4 | Nagano,Matsumoto,Ueda,Iida                                                                                                                                                                 |
| Nara      |           4 | Nara,Kashihara,Ikoma,Yamatokoriyama                                                                                                                                                        |
| Niigata   |           4 | Niigata,Nagaoka,Joetsu,Kashiwazaki                                                                                                                                                         |
| Tochigi   |           4 | Utsunomiya,Ashikaga,Oyama,Kanuma                                                                                                                                                           |
| Yamagata  |           4 | Yamagata,Sakata,Tsuruoka,Yonezawa                                                                                                                                                          |
| Aomori    |           3 | Aomori,Hachinohe,Hirosaki                                                                                                                                                                  |
| Ehime     |           3 | Matsuyama,Niihama,Imabari                                                                                                                                                                  |
| Miyazaki  |           3 | Miyazaki,Miyakonojo,Nobeoka                                                                                                                                                                |
| Nagasaki  |           3 | Nagasaki,Sasebo,Isahaya                                                                                                                                                                    |
| Okayama   |           3 | Okayama,Kurashiki,Tsuyama                                                                                                                                                                  |
| Okinawa   |           3 | Naha,Okinawa,Urasoe                                                                                                                                                                        |
| Shiga     |           3 | Otsu,Kusatsu,Hikone                                                                                                                                                                        |
| Ishikawa  |           2 | Kanazawa,Komatsu                                                                                                                                                                           |
| Kumamoto  |           2 | Kumamoto,Yatsushiro                                                                                                                                                                        |
| Miyagi    |           2 | Sendai,Ishinomaki                                                                                                                                                                          |
| Oita      |           2 | Oita,Beppu                                                                                                                                                                                 |
| Tottori   |           2 | Tottori,Yonago                                                                                                                                                                             |
| Toyama    |           2 | Toyama,Takaoka                                                                                                                                                                             |
| Akita     |           1 | Akita                                                                                                                                                                                      |
| Fukui     |           1 | Fukui                                                                                                                                                                                      |
| Iwate     |           1 | Morioka                                                                                                                                                                                    |
| Kagawa    |           1 | Takamatsu                                                                                                                                                                                  |
| Kagoshima |           1 | Kagoshima                                                                                                                                                                                  |
| Kochi     |           1 | Kochi                                                                                                                                                                                      |
| Saga      |           1 | Saga                                                                                                                                                                                       |
| Shimane   |           1 | Matsue                                                                                                                                                                                     |
| Tokushima |           1 | Tokushima                                                                                                                                                                                  |
| Wakayama  |           1 | Wakayama                                                                                                                                                                                   |
| Yamanashi |           1 | Kofu                                                                                                                                                                                       |
+-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+47rowsinset (0.00 sec)

GROUP_CONCAT + ORDER BYを試す

GROUP_CONCATは関数内部での ORDER BYをサポートしているため,以下のように SQL を書くと連結した文字列を並び替えることができる.

SELECT District, COUNT(Name), GROUP_CONCAT(Name ORDERBY Name)
FROM city
WHERE CountryCode = 'JPN'GROUPBY District
ORDERBY COUNT(Name) DESC;

今回は「日本の都市名」を昇順に並び替えている.

mysql> SELECT District, COUNT(Name), GROUP_CONCAT(Name ORDERBY Name)
    -> FROM city
    -> WHERE CountryCode = 'JPN'
    -> GROUPBY District
    -> ORDERBY COUNT(Name) DESC;
+-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| District  | COUNT(Name) | GROUP_CONCAT(Name ORDERBY Name)                                                                                                                                                           |
+-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Osaka     |          22 | Daito,Habikino,Higashiosaka,Hirakata,Ibaraki,Ikeda,Izumi,Izumisano,Kadoma,Kawachinagano,Kishiwada,Matsubara,Minoo,Moriguchi,Neyagawa,Osaka,Sakai,Suita,Takatsuki,Tondabayashi,Toyonaka,Yao |
| Saitama   |          21 | Ageo,Asaka,Fujimi,Fukaya,Higashimatsuyama,Iruma,Iwatsuki,Kasukabe,Kawagoe,Kawaguchi,Koshigaya,Kumagaya,Misato,Niiza,Omiya,Sakado,Sayama,Soka,Toda,Tokorozawa,Urawa                         |
| Chiba     |          19 | Abiko,Chiba,Funabashi,Ichihara,Ichikawa,Kamagaya,Kashiwa,Kimitsu,Kisarazu,Matsudo,Mobara,Nagareyama,Narashino,Narita,Nishio,Noda,Sakura,Urayasu,Yachiyo                                    |
| Tokyo-to  |          18 | Akishima,Chofu,Fuchu,Hachioji,Higashikurume,Higashimurayama,Hino,Hitachinaka,Hoya,Kodaira,Koganei,Kokubunji,Machida,Mitaka,Musashino,Ome,Tachikawa,Tokyo                                   |
| Aichi     |          15 | Anjo,Handa,Ichinomiya,Inazawa,Kariya,Kasugai,Komaki,Konan,Nagoya,Okazaki,Seto,Tokai,Toyohashi,Toyokawa,Toyota                                                                              |
| Kanagawa  |          15 | Atsugi,Chigasaki,Ebina,Fujisawa,Hadano,Hiratsuka,Isehara,Jokohama [Yokohama],Kamakura,Kawasaki,Odawara,Sagamihara,Yamato,Yokosuka,Zama                                                     |
| Hyogo     |          11 | Akashi,Amagasaki,Himeji,Itami,Kakogawa,Kawanishi,Kobe,Nishinomiya,Sanda,Takarazuka,Takasago                                                                                                |
| Hokkaido  |          10 | Asahikawa,Ebetsu,Hakodate,Kitami,Kushiro,Muroran,Obihiro,Otaru,Sapporo,Tomakomai                                                                                                           |
| Shizuoka  |           9 | Fuji,Fujieda,Fujinomiya,Hamamatsu,Mishima,Numazu,Shimizu,Shizuoka,Yaizu                                                                                                                    |
| Mie       |           6 | Ise,Kuwana,Matsusaka,Suzuka,Tsu,Yokkaichi                                                                                                                                                  |
| Yamaguchi |           6 | Hofu,Iwakuni,Shimonoseki,Tokuyama,Ube,Yamaguchi                                                                                                                                            |
| Fukuoka   |           5 | Fukuoka,Kasuga,Kitakyushu,Kurume,Omuta                                                                                                                                                     |
| Gumma     |           5 | Isesaki,Kiryu,Maebashi,Ota,Takasaki                                                                                                                                                        |
| Hiroshima |           5 | Fukuyama,Higashihiroshima,Hiroshima,Kure,Onomichi                                                                                                                                          |
| Ibaragi   |           5 | Hitachi,Mito,Tama,Tsuchiura,Tsukuba                                                                                                                                                        |
| Fukushima |           4 | Aizuwakamatsu,Fukushima,Iwaki,Koriyama                                                                                                                                                     |
| Gifu      |           4 | Gifu,Kakamigahara,Ogaki,Tajimi                                                                                                                                                             |
| Kyoto     |           4 | Kameoka,Kioto,Maizuru,Uji                                                                                                                                                                  |
| Nagano    |           4 | Iida,Matsumoto,Nagano,Ueda                                                                                                                                                                 |
| Nara      |           4 | Ikoma,Kashihara,Nara,Yamatokoriyama                                                                                                                                                        |
| Niigata   |           4 | Joetsu,Kashiwazaki,Nagaoka,Niigata                                                                                                                                                         |
| Tochigi   |           4 | Ashikaga,Kanuma,Oyama,Utsunomiya                                                                                                                                                           |
| Yamagata  |           4 | Sakata,Tsuruoka,Yamagata,Yonezawa                                                                                                                                                          |
| Aomori    |           3 | Aomori,Hachinohe,Hirosaki                                                                                                                                                                  |
| Ehime     |           3 | Imabari,Matsuyama,Niihama                                                                                                                                                                  |
| Miyazaki  |           3 | Miyakonojo,Miyazaki,Nobeoka                                                                                                                                                                |
| Nagasaki  |           3 | Isahaya,Nagasaki,Sasebo                                                                                                                                                                    |
| Okayama   |           3 | Kurashiki,Okayama,Tsuyama                                                                                                                                                                  |
| Okinawa   |           3 | Naha,Okinawa,Urasoe                                                                                                                                                                        |
| Shiga     |           3 | Hikone,Kusatsu,Otsu                                                                                                                                                                        |
| Ishikawa  |           2 | Kanazawa,Komatsu                                                                                                                                                                           |
| Kumamoto  |           2 | Kumamoto,Yatsushiro                                                                                                                                                                        |
| Miyagi    |           2 | Ishinomaki,Sendai                                                                                                                                                                          |
| Oita      |           2 | Beppu,Oita                                                                                                                                                                                 |
| Tottori   |           2 | Tottori,Yonago                                                                                                                                                                             |
| Toyama    |           2 | Takaoka,Toyama                                                                                                                                                                             |
| Akita     |           1 | Akita                                                                                                                                                                                      |
| Fukui     |           1 | Fukui                                                                                                                                                                                      |
| Iwate     |           1 | Morioka                                                                                                                                                                                    |
| Kagawa    |           1 | Takamatsu                                                                                                                                                                                  |
| Kagoshima |           1 | Kagoshima                                                                                                                                                                                  |
| Kochi     |           1 | Kochi                                                                                                                                                                                      |
| Saga      |           1 | Saga                                                                                                                                                                                       |
| Shimane   |           1 | Matsue                                                                                                                                                                                     |
| Tokushima |           1 | Tokushima                                                                                                                                                                                  |
| Wakayama  |           1 | Wakayama                                                                                                                                                                                   |
| Yamanashi |           1 | Kofu                                                                                                                                                                                       |
+-----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+47rowsinset (0.00 sec)

GROUP_CONCAT + DISTINCTを試す

次にデータの重複を考える.以下の SQL だと「地域名」が,例えば Caribbean,Caribbean,Caribbeanのように重複してしまう.

SELECT Continent, GROUP_CONCAT(Region)
FROM country
GROUPBY Continent;

GROUP_CONCATは関数内部での DISTINCTをサポートしているため,以下のように SQL を書くと,データの重複を除外することができる.

SELECT Continent, GROUP_CONCAT(DISTINCT Region)
FROM country
GROUPBY Continent;

実際に「地域名」の重複を除外できている.

mysql> SELECT Continent, GROUP_CONCAT(DISTINCT Region)
    -> FROM country
    -> GROUPBY Continent;
+---------------+-------------------------------------------------------------------------------------------------+
| Continent     | GROUP_CONCAT(DISTINCT Region)                                                                   |
+---------------+-------------------------------------------------------------------------------------------------+
| Asia          | Eastern Asia,Middle East,Southeast Asia,Southern and Central Asia                               |
| Europe        | Baltic Countries,British Islands,Eastern Europe,Nordic Countries,Southern Europe,Western Europe |
| North America | Caribbean,Central America,North America                                                         |
| Africa        | Central Africa,Eastern Africa,Northern Africa,Southern Africa,Western Africa                    |
| Oceania       | Australia and New Zealand,Melanesia,Micronesia,Micronesia/Caribbean,Polynesia                   |
| Antarctica    | Antarctica                                                                                      |
| South America | South America                                                                                   |
+---------------+-------------------------------------------------------------------------------------------------+7rowsinset (0.00 sec)

GROUP_CONCAT + DISTINCT + SEPARATORを試す

GROUP_CONCATのデフォルト区切り文字は ,になっている.データに ,が入っている可能性がある場合など,意図的に区切り文字を変更する場合は SEPARATORを設定する.

SELECT Continent, GROUP_CONCAT(DISTINCT Region SEPARATOR ' ? ')
FROM country
GROUPBY Continent;

以下は区切り文字を ?にして SQL を実行している.

mysql> SELECT Continent, GROUP_CONCAT(DISTINCT Region SEPARATOR ' ? ')
    -> FROM country
    -> GROUPBY Continent;
+---------------+-----------------------------------------------------------------------------------------------------------+
| Continent     | GROUP_CONCAT(DISTINCT Region SEPARATOR ' ? ')                                                             |
+---------------+-----------------------------------------------------------------------------------------------------------+
| Asia          | Eastern Asia ? Middle East ? Southeast Asia ? Southern and Central Asia                                   |
| Europe        | Baltic Countries ? British Islands ? Eastern Europe ? Nordic Countries ? Southern Europe ? Western Europe |
| North America | Caribbean ? Central America ? North America                                                               |
| Africa        | Central Africa ? Eastern Africa ? Northern Africa ? Southern Africa ? Western Africa                      |
| Oceania       | Australia and New Zealand ? Melanesia ? Micronesia ? Micronesia/Caribbean ? Polynesia                     |
| Antarctica    | Antarctica                                                                                                |
| South America | South America                                                                                             |
+---------------+-----------------------------------------------------------------------------------------------------------+7rowsinset (0.00 sec)

group_concat_max_lenシステム変数

MySQL の group_concat_max_lenシステム変数は GROUP_CONCATが返す連結した文字列の最大バイト数を意味している.デフォルトは「1024」で,最小値は「4」を設定することができる.

実際に SHOW VARIABLESで確認すると「1024」になっていることを確認できる.

mysql> SHOW VARIABLES LIKE'group_concat_max_len';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| group_concat_max_len | 1024  |
+----------------------+-------+1rowinset (0.01 sec)

今回は意図的に最小値「4」に設定すると,GROUP_CONCATの連結した文字列を「4」バイトに制限できる.

mysql> SETSESSION group_concat_max_len = 4;
Query OK, 0rows affected (0.00 sec)

mysql> SELECT Continent, GROUP_CONCAT(DISTINCT Region)
    -> FROM country
    -> GROUPBY Continent;
+---------------+-------------------------------+
| Continent     | GROUP_CONCAT(DISTINCT Region) |
+---------------+-------------------------------+
| Asia          | East                          |
| Europe        | Balt                          |
| North America | Cari                          |
| Africa        | Cent                          |
| Oceania       | Aust                          |
| Antarctica    | Anta                          |
| South America | Sout                          |
+---------------+-------------------------------+7rowsinset, 7 warnings (0.00 sec)

まとめ

  • MySQL を使う場合 GROUP BYだけではなく GROUP_CONCATも知っておくと便利
  • GROUP_CONCATは関数内部で ORDER BYDISTINCTSEPARATORをサポートしている
  • GROUP_CONCATの結果列のバイト数を調整する場合には,MySQL のシステム変数 group_concat_max_lenを設定する

2018年 : 登壇を振り返る

$
0
0

今年の登壇を振り返る.去年の振り返り記事は以下にある.

kakakakakku.hatenablog.com

登壇 : 計9回

今年の登壇は計9回だった.去年の計14回よりも減ってしまった.

  • 勉強会 : 登壇8回
  • 社内勉強会 : 登壇1回

時系列で並べると以下のようになる.

振り返り

プロジェクトリード

社内勉強会のために作った「プロジェクトをリードする技術」という資料に大きな反響があり,今年最大のターニングポイントになった.人生初となる 1000 ブクマを達成したり,Kyash 様の社内イベントで再演をさせて頂いたり,F.O.X Meetup に登壇した内容を書き起こして頂いたりもした.ここまで大きな反響になるとは予想していなかったけど,プロジェクトリードのノウハウを資料として言語化できて良かった.

logmi.jp

アウトプット

豪雨の影響もあり中止になってしまったけど,「DevLOVE 関西」に登壇する予定だった「楽しく!アウトプットを習慣化しよう」という資料にも大きな反響があった.アウトプットに悩む人たちの背中を少しでも押せたら良いなと思っていたし,アウトプットを習慣化することによって良いことがあるということも伝えられたと思う.この資料を公開してからブログメンタリングの希望者がとにかく増えた!

技術

今年は技術ネタの登壇をあまりしてなく,計3回となった.そのうち2回は「Rails 関連」で,プログラミング講師としての学びを伝えた.残り1回は「インフラ関連」で,Mackerel で Amazon ECS をモニタリングする方法を詳細に解説した.今年は実戦投入した技術が他にも多くあったので,もっと登壇するべきだったという反省もある.

登壇する技術

今年も「登壇する技術」をまとめた過去記事を参考に貼っておく!

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

資料一覧

2018年の振り返りと2019年の抱負

$
0
0

2018年の振り返り 🎉

幅広く実戦投入をした

2016年から3年連続で目標にしている「実戦投入力を高める」を2018年も達成できた.インフラ関連で言うと「Redis on EC2 → Amazon ElastiCache 移行」「Embulk データ抽出基盤構築」「Zabbix → Mackerel 完全移行」など(書ける事例で言うと).サーバサイド関連で言うと,去年に続き「Go + Amazon ECS でのマイクロサービス構築」を推進した.また2018年は苦手意識のあったフロントエンド関連にも挑戦する1年となり,トレンドとも言える「Vue.js」を初経験し,プロダクション環境に実戦投入をすることもできた.幅広く実戦投入をした1年だと感じる.

また2018年は「プロジェクトリード」での事例を多く作ることができた.数年前からスクラムマスターとテックリードを兼任するポジションを担当しているものの,4月に公開した資料「プロジェクトをリードする技術」に大きな反響を頂くことができた.アジャイル推進の経験に加えて「ファシリテーション / 組織論 / 心理学 / メンタリング」などの領域も合わせて学び,実際にプロジェクトで最高の成果を出せたこともあり,個人的に2018年の中でもインパクトのある経験になった.

「教えること」を仕事にした

2017年を「技術を教えるための基礎力を整える1年間」と位置付けて,副業で Ruby / Rails 講師をはじめた.そして,2018年夏頃まで副業を続けて,最終的に「約50人」の生徒さんを卒業させることができた.エンジニアになることを目指している人をサポートすることができ,非常に嬉しい.さらに「2018年の抱負」で宣言した通り,2018年を「本格的に動き出す1年間」と位置付けていたこともあり,8月に転職をし,現在は「教えること」を仕事にしている.技術講師として「教えること」「楽しさ」「難しさ」を日々感じながら,仕事を楽しめている.

インプット/アウトプット 💡

登壇

2018年の登壇は計9回となった.既にまとめてある.

kakakakakku.hatenablog.com

勉強会

2018年はあまり勉強会に参加せず,登壇するときに参加することが多かった.印象的なのは4月に参加した「Japan Container Days v18.04」で,現在のトレンドとも言える「Kubernetes」の導入事例を多く聞くことができた.

プルリクエスト

2018年は計11個のプルリクエストを OSS に送ることができた.既にまとめてある.

kakakakakku.hatenablog.com

ブログ

2018年も「週1回」のノルマを達成し「計78記事」を書いた.ブログを書くことは習慣化できているため,仕事がどんなに忙しくても,娘(2人目)が生まれても,ノルマを達成し続けることができた.ブログネタはまだまだ大量にあり,2019年に持ち越すことにした.そして Google Analytics で PV を振り返ると,1年間を通して,2017年よりも増えていた.毎月 30000 PV を達成していることは2017年からの成長と言える.

f:id:kakku22:20190101022229p:plain

2018年はホッテントリに入る記事が非常に多かった.その結果もあり,累計ブクマ数は2018年で「6573 → 12285 (+5712)」となり,大きく伸びた1年間だった.2018年1月の時点では,ここまで伸びるとは予想していなかった.2019年も需要のある記事を書けるように頑張る.

f:id:kakku22:20190101022301p:plain

特に 500 ブクマを超えた記事を3本も書くことができた.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

ブログメンタリング

2017年末からはじめた「ブログメンタリング活動」は2018年も継続することができた.そして,2018年12月までに卒業したブログメンティは「計16人」となった.どんどんメンタリングの応募倍率が上がっているけど,2019年も「ブログメンタリング活動」は続ける.もしメンティ希望の場合は僕の Twitter をフォローしておいて頂けると良いかと!

ポッドキャスト

2018年は @iwashi86 さんに呼んで頂き,人気ポッドキャスト「Fukabori.fm」に出演することができた.ありがとうございました!

fukabori.fm

読んだ本

2018年は計12冊を読むことができた.ただし,中途半端に読んで書評記事を書けていない本があるので,2019年に持ち越すことになってしまった.読むのが遅いし,積読が増えてしまう状況は引き続きだけど,2019年は毎月1冊以上読めるように計画したいと思う.

2019年の抱負 ✨

幅広く技術を語れるように学び続ける

2019年の目標を「幅広く技術を語れるように学び続ける」に決めた.2016年から3年連続で掲げてきた「実戦投入力を高める」という目標に区切りを付けて,2019年はあえて「幅を広げる」ことに努力をする.まだまだ未経験の技術が多くあるし,トレンド技術だけではなく,要素技術も対象に学ぶ.当然ながら,アウトプットをする前提で学ぶので,学んだ内容はブログにまとめる.

教えることの本質を追求する

もう1個の目標は「教えることの本質を追求する」に決めた.技術講師として,ただ教えるのではなく,記憶に残るような学びを提供できるように,教えることの本質を追求する.そのためには,技術を学ぶだけではなく,例えば「アクティブラーニング」「教育心理学」「インストラクショナルデザイン(教育設計)」など,教育関連の領域を学ぶ必要がある.技術講師として,圧倒的に成長する!

まとめ

2019年も攻めていくぞ 🔥

過去の振り返り

最新バージョン Redash v6.0.0 をすぐに試せる「Redash ハンズオン資料」

$
0
0

2018年12月に「Redash v6.0.0」がリリースされた 🎉

blog.redash.io

Redash ハンズオン資料 v6.0.0 サポート

さっそく「Redash ハンズオン資料」で「Redash v6.0.0」をサポートした.サクッと Redash v6.0.0 を試すときに使ってもらえると!なお「Redash ハンズオン資料」は,2017年12月に公開し,既に1年間メンテナンスをしている.Redash バージョンで言うと v2 → v4 → v5 とメジャーバージョンをサポートし続けている.

github.com

主な変更点を以下にまとめる.

  • 全てのスクリーンキャプチャを取り直した
  • Docker Compose の Compose file を version 3 に変更した
    • Redash / Redis / PostgreSQL の Docker イメージも Redash 公式に合わせて変更した
  • UI 変更に合わせて文章を一部変更した

Redash v6.0.0 変更点

Redash v6.0.0 で個人的にイイ!と感じる新機能は以下がある.特に「IBM Db2」は SIer 時代にずっと運用してた経験もあり,最近だと IBM Db2 Express-C を Docker で起動できるため,今度試そうと思う.正確に言うと,2017年に名称変更があり,現在は「DB2」ではなく「Db2」と書く.データソース名は「DB2」になっていて少し気になる...!

  • データソースに「IBM Db2」が追加された
  • アラートに「PagerDuty」が追加された
  • クエリエディタで「Live Autocomplete」が使えるようになった
  • MySQL で sysスキーマが対象外になった
  • チャート種類に「ヒートマップ」が追加された

MySQL で sysスキーマが対象外になったのも嬉しくて,例えば「Redash ハンズオン資料」だと,以下のように差がある.

f:id:kakku22:20190102001710p:plain

詳細な Changelog は GitHub のリリース情報と @kyoshidajp さんの記事にまとまっている.

Feature Flags とは?

Redash v6.0.0 の動作確認をしていたら Settings 画面に「Feature Flags」という設定項目が増えていて,現在は「Enable experimental multiple owners support」とある.ほとんど情報がなく,どんな機能だろう?

f:id:kakku22:20190102001814p:plain

まとめ

「Redash ハンズオン資料」を使って Redash v6.0.0 を試そう!

github.com

関連記事

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

スタンディングデスクを買おうかと悩んでいる人にオススメする「LEVIT8」

$
0
0

運動不足と感じる場面も多く,自宅に「電動昇降式スタンディングデスク」を買おうかと悩んでいたところ,Twitter で @budougumi0617 さんに「LEVIT8」を教えてもらった.すぐに購入し,約2ヶ月半使っているけど,とにかく最高なので記事を書くことにした.

LEVIT8 Mレッド

LEVIT8 Mレッド

「LEVIT8」とは?

「LEVIT8」は折りたたみ式のスタンディングデスクで,デスクの上に「ひねって立てて」使う.折りたたみ式なので,使わないときは片付けておくことができる.価格も例えば「L サイズ」「3500円」なので,高価な「電動昇降式スタンディングデスク」と比べて,お手軽と言える.「LEVIT8」を購入してから,自宅作業の多くの時間をスタンディングで過ごし,コンピュータ以外の作業をする場合は,今まで10年以上も愛用している「Ergohuman」の椅子に座っている.ポモドーロに集中できるし,運動不足も解消できるし,とにかく満足している!当然ながら,姿勢と重心を間違えるとスタンディングでも骨盤などに負担がかかるので,気を付けること!

f:id:kakku22:20190101031941j:plain:w400

(自宅の LEVIT8 + MacBook Pro 環境)

サイズ展開

サイズ展開は現在4種類で「S / M / L / XL」がある.目線を合わせるために,机の高さや身長などを考慮して選ぶと良さそう.ただし,Amazon に記載されているサイズは正しくなく,Kickstarter に載っているサイズも微妙に違う気がする.僕自身は「L サイズ」を使っているので,参考までに「素人採寸」を載せておく.なお,Amazon の出品者には表記を正しくしてもらうように報告をしてある 🚧

  • L サイズ : 折りたたんだとき(素人採寸)
    • 42.5 cm (縦) x 24.0 cm x 1.5 cm
  • L サイズ : ひねったとき(素人採寸)
    • 35.5 cm (縦) x 24.0 cm x 24.0 cm

Kickstarter

「LEVIT8」を調べると,2015年末に Kickstarter でクラウドファンディングを実施し,成功していた.

www.kickstarter.com

ひねる技術

「LEVIT8」の特徴は「ひねって立てて」使う点にあり,慣れれば本当にサッとひねることができるけど,逆に言うと慣れるまでは非常に難しく,パズルのように感じる.以下の YouTube を何度も見て練習をした.

www.youtube.com

まとめ

  • 「電動昇降式スタンディングデスク」を買おうかと悩んでいる人にオススメする「LEVIT8」を約2ヶ月半使っている
  • 例えば「L サイズ」だと「3500円」で買える
  • ポモドーロに集中できるし,運動不足も解消できるし,とにかく満足している!(姿勢と重心には注意すること!)

関連記事

kakakakakku.hatenablog.com

Python で「両端キュー」として使えるデータ型 collections.deque

$
0
0

最近「Python チュートリアル 第3版」を読んでいて,11章で紹介されている collections.dequeを実際に使ったことがなく,ドキュメントを読みながら動作確認をした.Python 3.2 と Python 3.5 で追加されたメソッドもあり,メモ程度にまとめておこうと思う.

Pythonチュートリアル 第3版

Pythonチュートリアル 第3版

deque (double-ended queue) とは?

ドキュメントを読むと collections.dequeの説明は以下のように書かれている.特に「どちらの側からも append と pop が可能」という点がポイントで「スタックとしてもキューとしても」使うことができる.正直言って,最初に dequeを見たときに「デキュー」と読むのかな?と思ったけど,正しくは「デック」だった.「デキュー」dequeueだから間違える人もいそう.日本語だと「両端キュー」とも言う.

Deque とは、スタックとキューを一般化したものです (この名前は「デック」と発音され、これは「double-ended queue」の省略形です)。Deque はどちらの側からも append と pop が可能で、スレッドセーフでメモリ効率がよく、どちらの方向からもおよそ O(1) のパフォーマンスで実行できます。

前提

今回は Python 3.7.1 で動作確認をした.

$ python --version
Python 3.7.1

基本操作

まず,以下の基本操作を試した.

  • append()
  • appendleft()
  • pop()
  • popleft()

append()pop()dequeオブジェクトの右側を操作し,appendleft()popleft()は名前の通り,dequeオブジェクトの左側を操作する.

from collections import deque

d = deque(['B', 'C', 'D'])

# deque(['B', 'C', 'D'])print(d)

# deque(['B', 'C', 'D', 'E'])
d.append('E')
print(d)

# deque(['A', 'B', 'C', 'D', 'E'])
d.appendleft('A')
print(d)

# Eprint(d.pop())

# Aprint(d.popleft())

# deque(['B', 'C', 'D'])print(d)

最大長

dequeオブジェクトを作成するときに,第2引数に maxlenを指定することができる(オプション).maxlenを指定すると dequeオブジェクトの最大長となる.

class collections.deque([iterable[, maxlen]])

さらに maxlen()を使うと,dequeオブジェクトの最大長を確認できる.そして,気になるのは指定した maxlenを超えたときの挙動で,ドキュメントには「追加したのと反対側から要素が捨てられる」と書いてあった.

長さが制限された deque がいっぱいになると、新しい要素を追加するときに追加した要素数分だけ追加したのと反対側から要素が捨てられます。

実際に 6append()すると,左側にある 1が捨てられて,もう1度 1appendleft()すると,右側にある 6が捨てられた.ドキュメントの通りに「反対側」から捨てられた.

from collections import deque

# deque([1, 2, 3, 4, 5], maxlen=5)# 5
d = deque([1, 2, 3, 4, 5], 5)
print(d)
print(d.maxlen)

# deque([2, 3, 4, 5, 6], maxlen=5)
d.append(6)
print(d)

# deque([1, 2, 3, 4, 5], maxlen=5)
d.appendleft(1)
print(d)

さらに dequeオブジェクトを作成するときに,既に maxlenを超えている状態にしたところ,左側から捨てられた.

from collections import deque

# deque([4, 5, 6], maxlen=3)# 3
d = deque([1, 2, 3, 4, 5, 6], 3)
print(d)
print(d.maxlen)

反転

次に Python 3.2 で追加された reverse()を確認した.reverse()dequeオブジェクトを反転し Noneを返すため,破壊的にオブジェクトを更新する.

from collections import deque

d = deque([1, 2, 3, 4, 5])

# deque([5, 4, 3, 2, 1])
d.reverse()
print(d)

浅いコピー

次に Python 3.5 で追加された copy()を確認した.copy()dequeオブジェクトの「浅いコピー」を作成できる.

from collections import deque

d1 = deque([1, 2, 3, 4, 5])
d2 = d1.copy()

# deque([1, 2, 3, 4, 5])# deque([1, 2, 3, 4, 5])print(d1)
print(d2)

d1.append(6)

# deque([1, 2, 3, 4, 5, 6])# deque([1, 2, 3, 4, 5])print(d1)
print(d2)

Python の「浅いコピー」に関しては以下に書いてある.

インデックス検索

次に Python 3.5 で追加された index()を確認した.index()dequeオブジェクトの中から指定した値の位置を返す.複数該当する場合は,最初の位置を返す.該当しない場合は ValueError例外を返す.

from collections import deque

# 1
d = deque([1, 2, 3, 4, 5])
print(d.index(2))

挿入

次に Python 3.5 で追加された insert()を確認した.insert()dequeオブジェクトの任意の場所に値を挿入する.左右以外にも挿入できるため,スタックとキューでは行えない操作もできる.当然ながら,中央部分に挿入する場合は O(n)の計算量になる.

from collections import deque

d = deque([1.0, 2.0, 3.0, 4.0, 5.0])

# deque([1.0, 2.0, 3.0, 4.0, 5.0])print(d)

d.insert(3, 3.5)

# deque([1.0, 2.0, 3.0, 3.5, 4.0, 5.0])print(d)

動作確認 : PyCharm Python Console

インタラクティブに動作確認をする場合に「PyCharm Python Console」を使っている.Python インタプリタではなく IPython を使うとして,「PyCharm Python Console」を使うと,同時に変数なども確認できて便利.

f:id:kakku22:20190104194532p:plain

ドキュメント化 : Jupyter Notebook

動作確認をしながらメモを残す場合に,インラインコメントを付ける以外に「Jupyter Notebook」を使って,Markdown でドキュメント化してしまう方法もある.特に仮想サーバを構築する必要もなく,ローカル環境で jupyter notebookと実行すれば良くて,お手軽に使うことができる.

jupyter.org

以下は collections.dequeのドキュメントにあるサンプルコードを「Jupyter Notebook」でドキュメント化して,さらに GitHub に push している.「コメント」と「コード」と「実行結果」を確認できるので,今後見直す場合にも効率的に思い出せる.

f:id:kakku22:20190104194553p:plain

GitHub は2015年に対応していて,そのまま .ipynbを push すると,GitHub で「Jupyter Notebook」を閲覧することができる.

blog.github.com

まとめ

  • Python で使ったことがなかった collections.dequeの動作確認をした
    • deque「デキュー」ではなく「デック」と読む
  • collections.dequeには Python 3.2 と Python 3.5 で追加されたメソッドもあった
    • insert()を使うと任意の場所に値を挿入できる(もはや「両端キュー」ではない)
  • 動作確認には「PyCharm Python Console」を使って,ドキュメント化には「Jupyter Notebook」を使うと便利

ブラウザ経由で Windows Server にリモート接続ができる「Apache Guacamole」を Docker Compose で起動する

$
0
0

最近 Windows Server にリモート接続 (RDP) をする機会があり,ブラウザ経由で使えるツール「Apache Guacamole」を試すことにした.今までは「Microsoft Remote Desktop」を使っていて,違う選択肢を学んでおくという意図もあった.「Apache Guacamole」の公式ドキュメントを読むと「clientless remote desktop gateway」と書かれている.「クライアントレス」「リモートデスクトップゲートウェイ」で,RDP 以外に SSH もサポートしているツールと言える.

Apache Guacamole is a clientless remote desktop gateway. It supports standard protocols like VNC, RDP, and SSH.

guacamole.apache.org

Wikipedia を見ると「Guacamole」「ワカモレ(グワカモーレ)」と読むらしく,メキシコ料理のことだった!確かに「Apache Guacamole」のロゴもアボカド色になっている!

ja.wikipedia.org

Guacamole with Docker

以下の公式ドキュメントに載っている通り,「Apache Guacamole」を構成するサービスである guacamole-serverguacencは比較的多くのライブラリに依存している.

guacamole.apache.org

今回は「Apache Guacamole」をお手軽に試すため,Docker を使うことにした.

guacamole.apache.org

ただし,公式ドキュメントに載っている手順を読むと,計3種類のコンテナイメージを起動し,さらに --linkで参照する必要があった.

  • guacamole/guacamole
  • guacamole/guacd
  • mysql

個別に起動するぐらいなら Docker Compose を使えば良さそう!と考えて,今回は雑に docker-compose.ymlを実装した.

version:'3'services:guacd:image: guacamole/guacd:latest
    expose:- '4822'guacamole:image: guacamole/guacamole:latest
    ports:- '8080:8080'environment:MYSQL_HOSTNAME:'mysql'GUACD_HOSTNAME:'guacd'MYSQL_DATABASE:'guachamole'MYSQL_USER:'guachamole'MYSQL_PASSWORD:'guachamole'mysql:image: mysql:5.7
    environment:MYSQL_ALLOW_EMPTY_PASSWORD:'yes'MYSQL_DATABASE:'guachamole'MYSQL_USER:'guachamole'MYSQL_PASSWORD:'guachamole'volumes:- './initdb.sql:/docker-entrypoint-initdb.d/initdb.sql'

公式ドキュメントの手順通り,MySQL の初期化(マイグレーション)もする.

$ docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql> initdb.sql
$ docker-compose up -d

起動すると http://localhost:8080/guacamoleにアクセスできる.初期パスワードは guacadmin / guacadminになっている.

f:id:kakku22:20190108233822p:plain

Windows Server に接続する

SettingsConnectionsNew Connectionと画面遷移をし,以下を設定する.

  • Name
  • Protocol
  • Network (Hostname, Port)
  • Authentication (Username, Password)

f:id:kakku22:20190108233835p:plain

すると Windows Server にリモート接続ができる.インスタンス側の設定は今回は割愛する.

f:id:kakku22:20190108233859p:plain

クリップボード共有

guacamole.apache.org

ホスト側とリモート側でクリップボードを共有する機能もある.ホスト側で以下のショートカットを押すと,画面左側に「Guacamole メニュー」が表示される.この Clipboard(テキストエリア)を使うと,クリップボードを共有することができる.

  • Windows : Ctrl + Alt + Shift
  • Mac : Ctrl + Command + Shift

f:id:kakku22:20190108233947p:plain

(画面左に「Guacamole メニュー」が表示されている)

ショートカットが効かない

環境依存かもしれないけど,今回試した Mac + Guacamole (v0.9.14) 環境だと,Command キーを使うことができず,Command + A / Command + C / Command + Vなど,よく使うショートカットをマウス操作で代替する必要があった.ちなみに「Guacamole メニュー」に Input method という設定があり,ここで Text input を選ぶと,画面右下に「Ctrl / Alt / Esc / Tab」の仮想ボタンが表示されるため,Ctrl を有効にしながら Cを押すとコピーすることはできた.とは言え,操作感は良くなく,根本解決ではない.ショートカットを使う方法があったら是非教えて欲しい!

f:id:kakku22:20190108234017p:plain

(右下に仮想ボタンが表示されている)

まとめ

  • ブラウザ経由で Windows Server にリモート接続 (RDP) ができる「Apache Guacamole」を試した
    • RDP 以外に SSH もサポートしている
  • Docker を使うとお手軽にインストールできる
    • さらに Docker Compose を使うと便利だった(今回 docker-compose.ymlを実装した)
  • ホスト側とリモート側でクリップボードを共有する機能もあった

キャリアを選ぶときの価値観を発見しよう /「キャリア・アンカー」を今年も読んだ

$
0
0

今回は「キャリア」をテーマにしたオススメ本「キャリア・アンカー(自分のほんとうの価値を発見しよう)」を紹介する.過去の記事で本書のことを少し紹介したことはあったけど,実は今まで書評記事を書いていなかった.2019年になり,目標設定をしている人も多いと思う.自分のキャリアを見直したり,自分の価値観を確認したりするときにオススメの1冊と言える.僕自身も年末年始に「キャリア・アンカー(自分のほんとうの価値を発見しよう)」を読み直し,再診断をした.

キャリア・アンカー―自分のほんとうの価値を発見しよう (Career Anchors and Career Survival)

キャリア・アンカー―自分のほんとうの価値を発見しよう (Career Anchors and Career Survival)

「キャリア・アンカー」とは?

「キャリア・アンカー(自分のほんとうの価値を発見しよう)」は2003年に日本語版が出版された.原著は1993年に出版されていて,非常に歴史があるものの,今読んでも時代のズレなどはそこまで感じない.僕自身は Amazon の購入履歴を見ると「2016年10月」に本書を購入している.そして,2017年の目標設定をするために読んだことがキッカケとなり,年末年始に読む習慣がある.今年は計3回目の読み直しとなった.

そもそも「キャリア・アンカー」とは,一言で表現すると「自分のキャリアを選ぶときの価値観」となる.本書の P.1 に載っている紹介文を引用すると以下となる.自分はどんなキャリアを選ぶべきなのか?現在のキャリアは「自分らしい」のか?という点を知ることができる.また本書にも書いてある通り,キャリアを分類すると2種類あり,「内面的なキャリア」「外見上のキャリア」となる.「キャリア・アンカー」では,この「内面的なキャリア」を知るためにある.

あなたのキャリア・アンカーとは,あなたがどうしても犠牲にしたくない,またあなたのほんとうの自己を象徴する,コンピタンスや動機,価値観について,自分が認識していることが複合的に組み合わさったものです。

「キャリア・アンカー」を発見する方法

「キャリア・アンカー」は大きく2種類の方法で発見していく.「キャリア指向質問票」は1人で実施することができ,「キャリア・アンカー・インタビュー」はパートナーと2人で実施することができる.

  • キャリア指向質問票
    • 1人
    • 自己診断ツール
  • キャリア・アンカー・インタビュー
    • 2人
    • パートナーと話す

キャリア指向質問票

まず「キャリア指向質問票」は,自分自身の価値観で計40個ある質問に6段階評価を付けて,集計をする.1人で実施することができるので,最もお手軽な方法と言える.計40個ある質問は本書を見てもらえればと!集計をすると,以下の「8アンカー」ごとにスコアが出るため,1番スコアが高いアンカーが「キャリア指向質問票」から発見できた「キャリア・アンカー」となる.本書にはアンカーごとに「仕事のタイプ」「承認のしかた」がまとまっている.

  • 専門・職能別コンピタンス (TF : Technical / Functional Competence)
  • 全般管理コンピタンス (GM : General Managerial Competence)
  • 自立・独立 (AU : Autonomy / Independence)
  • 保障・安定 (SE : Security / Stability)
  • 起業家的創造性 (EC : Entrepreneurial Creativity)
  • 奉仕・社会貢献 (SV : Service / Dedication to a Cause)
  • 純粋な挑戦 (CH : Pure Challenge)
  • 生活様式 (LS : Lifestyle)

なお,本書の中盤には「2個以上のアンカーを持つことができるか」という解説がある.原則として「1個」であると書かれていて,理由は「1番目と2番目にスコアが高いアンカーに適する仕事が異なる場合にどちらを選択するか?」という意思決定が必要なときに1番目のアンカーから選ぶためとある.個人的には今だともっと柔軟に考えても良いと思っていて,2番目にスコアが高いアンカーに適する仕事を副業として選ぶことができる.実際に僕自身,2017年に「キャリア・アンカー」の診断結果からプログラミング講師という副業を選んだ.

キャリア・アンカー・インタビュー

次に「キャリア・アンカー・インタビュー」で,これは本書にある質問を使って,パートナーと話すことにより,「自分のキャリアを選ぶときの価値観」をより具体的に言語化をしていく.インタビューと呼ばれている通り,採用面接にも似ている.なぜ「キャリア・アンカー・インタビュー」が必要なのかと言うと「キャリア指向質問票のスコアは自分自身の欲求によってバイアスがかかっているから」と書かれている.大項目で計18個ある質問も本書を見てもらうとして,一部を載せておく.

  • 3 : キャリアを歩み始めたとき,どのような大きな望み(アンビション)あるいは長期的な目的をもっていましたか
    • あなたはその目的と照らし合わせてみて,最初についた仕事はどんな具合でしたか
  • 15 : あなたのこれからのキャリアを展望してみて,特に楽しみとして期待しているのはどんなことですか
    • そのようなことを楽しみとして期待しているのはなぜですか
    • あなたの次の仕事はどんなものになると思いますか
    • さらにその後,あなたの次の仕事はどんなものになるとお考えですか

正直言って,「キャリア・アンカー・インタビュー」で難しいのは「パートナーを選ぶこと」だと思う.本書には「パートナーの選び方」がまとまっていて,要約すると「心置きなく話し合える人(配偶者や親友)が良い」と書かれていた.僕の場合は,パートナーを複数人を選び,インタビューの背景を伝えた上で,あえてインタビュー形式にはせず,質問をトークテーマにして雑談をするスタイルを選んだ.理由は「雰囲気」と「お手軽さ(ある意味での雑さ)」を重要視したく,カスタマイズをしている.

「アンカー」推移(上位)

僕自身の「アンカー」推移(一部)を載せておくと,上位3アンカーは3年間同じだった.しかし,直近の診断で「奉仕・社会貢献」が1位となり,「専門・職能別コンピタンス」が2位となった.本書には「専門性を活かして人を育てる先生もしくはメンターが良い」と書かれていて,現在のキャリアと合っている.そして趣味で活動しているブログメンタリングも合っていると思う.なお,2017年の目標に「技術支援を仕事にする」と掲げたのは,実は2016年12月の診断結果が関係している.今のところ,大満足のキャリアを選択することができている.

  • 2016年12月
    • No.1 : 純粋な挑戦
    • No.2 : 奉仕・社会貢献
    • No.3 : 専門・職能別コンピタンス
  • 2017年12月
    • No.1 : 純粋な挑戦
    • No.2 : 奉仕・社会貢献
    • No.3 : 専門・職能別コンピタンス
  • 2018年12月
    • No.1 : 奉仕・社会貢献
    • No.2 : 専門・職能別コンピタンス
    • No.3 : 純粋な挑戦

kakakakakku.hatenablog.com

「アンカー」推移(下位)

下位2アンカーも3年間同じだった.今まで起業や安定した生活に興味を持ったことがなく,これはこれで「自分らしい」診断結果だった.

  • 2016年12月
    • No.7 : 起業家的創造性
    • No.8 : 保障・安定
  • 2017年12月
    • No.7 : 起業家的創造性
    • No.8 : 保障・安定
  • 2018年12月
    • No.7 : 起業家的創造性
    • No.8 : 保障・安定

まとめ

  • 「自分のキャリアを選ぶときの価値観」を発見するときに「キャリア・アンカー(自分のほんとうの価値を発見しよう)」はオススメ
  • 発見する方法は2種類ある
    • キャリア指向質問票(自己診断ツール)
    • キャリア・アンカー・インタビュー(パートナーと話す)
  • 直近3年間は年末年始に本書を読む習慣がある

キャリア・アンカー―自分のほんとうの価値を発見しよう (Career Anchors and Career Survival)

キャリア・アンカー―自分のほんとうの価値を発見しよう (Career Anchors and Career Survival)

Python の理解度確認をするために「Python チュートリアル 第3版」を読んだ

$
0
0

オライリーから出版されている「Python チュートリアル 第3版」を読んだ.読者対象として「Python 入門者のための」と書いてあるけど,そこそこ難しい内容もあり,中級者でも楽しめる内容になっている.本書の最初に載っている「訳者まえがき」にも,理解度によって読む方法を変えて良いと書いてあった.今回本書を読んでみて,勉強になった部分を整理しておこうと思う.なお,本書は「Python 3.5.1」をサポートしている.さらに付録もあり,特に「付録E」「付録F」は面白かった.

Pythonチュートリアル 第3版

Pythonチュートリアル 第3版

目次

  • 1章 : 食欲をそそってみようか
  • 2章 : Pythonインタープリタの使い方
  • 3章 : 気楽な入門編
  • 4章 : 制御構造ツール
  • 5章 : データ構造
  • 6章 : モジュール
  • 7章 : 入出力
  • 8章 : エラーと例外
  • 9章 : クラス
  • 10章 : 標準ライブラリめぐり
  • 11章 : 標準ライブラリめぐり - PartII
  • 12章 : 仮想環境とパッケージ
  • 13章 : 次はなに?
  • 14章 : 対話環境での入力行編集とヒストリ置換
  • 15章 : 浮動小数点(float)の演算:その問題と限界
  • 16章 : 補遺
  • 付録A : 用語
  • 付録B : Python のドキュメント群について
  • 付録C : 歴史とライセンス
  • 付録D : コピーライト
  • 付録E : Python初心者だった頃─みんながひっかかるPythonのヘンなとこ
  • 付録F : Python 2を読んだり書いたりせざるを得ない人へ

python -iオプション

2章「Pythonインタープリタの使い方」の中で,コマンドラインから python -iで実行すると,実行後にインタラクティブモードに入るという内容があり,今まで使ったことがなかった.サクッとデバッグをするときなどに使えそう.例えば,以下のように変数を宣言するコード name.pyを用意する.

name = 'kakakakakku'

次に python -iで実行すると,そのままインタラクティブモードになり,変数を確認することができる.

$ python -i name.py
>>> name
'kakakakakku'>>> quit()

docs.python.jp

ビルトイン変数 _(アンダースコア)

3章「気楽な入門編」では,データ型の紹介がメインだけど,インタラクティブモードの紹介もある.最後に表示した式はビルトイン変数 _(アンダースコア)に代入される.覚えておくと,使える場面もありそう.

$ ipython
In [1]: 100 * 5
Out[1]: 500

In [2]: _
Out[2]: 500

ただし,ローカル変数としても設定できてしまうため,結果としてビルトイン変数を隠蔽することに繋がってしまう.気を付けよう.

$ ipython
In [1]: _ =1000

In [2]: 100 * 5
Out[2]: 500

In [3]: _
Out[3]: 1000

PEP 8 : Style Guide for Python Code

4章「制御構造ツール」の最後にコーディングスタイルとして「PEP 8 : Style Guide for Python Code」の紹介も載っていた.「PEP 8」だと,インデントはタブではなく,4スペースが推奨されている.

www.python.org

リスト内包

5章「データ構造」は基本的なデータ構造の解説だった.リストを生成するときに「リスト内包」が使えることは覚えておくと良さそう.単純に forを複数書けるだけではなく,ifで条件を設定することもできる.とは言え,可読性とトレードオフになる可能性があるので,メリットがある場合に使う.

$ ipython
In [4]: [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]
Out[4]: [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

docs.python.jp

標準ライブラリ

11章「標準ライブラリめぐり - PartII」では,以下のライブラリなどが紹介されていた.

  • reprlib.repr()
  • textwrap.fill()
  • locale.format()
  • struct.unpack()
  • threading.Thread
  • logging
  • weakref.WeakValueDictionary()
  • collections.deque
  • bisect.insort()

weakrefなど,今まで使ったことがない標準ライブラリもあり勉強になった.collections.dequeに関しては既にまとめてある.

kakakakakku.hatenablog.com

pyvenvvenv

12章「仮想環境とパッケージ」では,pyvenvpipの紹介がある.本書は「Python 3.5.1」をサポートしているが,「Python 3.6」pyvenvは非推奨になり,現在は venvが推奨になっているので,注意が必要かも.

The pyvenv script has been deprecated as of Python 3.6 in favor of using python3 -m venv to help prevent any potential confusion as to which Python interpreter a virtual environment will be based on.

docs.python.org

実は本書はウェブでも公開されていて,既に「Python 3.6.5」をサポートしている.最新版を読むと venv前提で書かれている.量が多いため,個人的にはウェブよりも本の方が読みやすかった.

docs.python.jp

リンク集

13章「次はなに?」はリンク集になっている.Python を勉強するときに参考にすると良さそう.

正誤表

非常に多くの誤植があるので,読むときは正誤表も合わせて確認する.実は正誤表に載っていない誤植を1箇所発見していて,xiv にある 5.1.4 は「れ子」ではなく「入れ子」になるべき.

www.oreilly.co.jp

まとめ

  • 「Python チュートリアル 第3版」を読んだ
  • 「Python 入門者のための」と書いてあるけど,そこそこ難しい内容もあり,中級者でも楽しめる
  • 気になるライブラリなどは IPython や Jupyter Notebook を使って試そう!

Pythonチュートリアル 第3版

Pythonチュートリアル 第3版

Python の基礎知識を証明できる「Python 3 エンジニア認定基礎試験」に合格した

$
0
0

先週末に「Python 3 エンジニア認定基礎試験」を受験し,問題なく合格した.試験問題に関係する内容は NDA を厳守するため書かず,今回は「試験紹介(普及のため!)」「勉強方法」にフォーカスする.

Python 試験とは?

「一般社団法人 Python エンジニア育成推進協会」が提供する Python 試験は2種類ある.現在受験できるのは「認定基礎試験」で,「認定データ分析試験」は今年開始予定とアナウンスされている.

  • Python 3 エンジニア認定基礎試験
    • 概要 : 文法基礎を問う試験
    • 2017年6月開始
  • Python 3 エンジニア認定データ分析試験
    • 概要 : Pythonを使ったデータ分析の基礎や方法を問う試験
    • 2019年夏開始予定 🚧

もともと「認定データ分析試験」を受験しようと考えていたけど,調べてみるとまだ開始されていないことに気付き,その前に Python の理解度確認をする意味も兼ねて,今回「認定基礎試験」を受験したという経緯がある.あと個人的に資格コレクションをしていて,今回合格した「認定基礎試験」を含めると「計38個目(期限切れも含める)」になる.

www.pythonic-exam.com

試験概要

「Python 3 エンジニア認定基礎試験」の試験概要を公式サイトを引用しながら紹介する.まず,実施は Odyssey となるため,会場ごとに受験可能日が異なり,予約が取れれば希望日に受験できる.料金は10800円となる.僕は「有楽町会場」で受験した.過去に「Rails 技術者認定試験」で利用したことがある.

  • 受験日 : 通年(予約が取れれば)
  • 会場 : Odyssey CBT テストセンター
  • 料金 : 10800円(学割だと5400円になる)

cbt.odyssey-com.co.jp

問題数は「40問」となり,合格ラインが「70%」と公開されているため,単純計算で「28問正解」がボーダーラインとなる.

  • 問題数 : 40問(選択問題)
  • 試験時間 : 60分
  • 合格ライン : 正解率 70%

www.pythonic-exam.com

試験範囲

「Python 3 エンジニア認定基礎試験」の特徴的な点は「主教材を指定していること」「章ごとの出題数を公開していること」だと思う.主教材は「Python チュートリアル 第3版」となり,試験専用の本ではなくオライリー本が選ばれている点は個人的に素晴らしいと感じている.

Pythonチュートリアル 第3版

Pythonチュートリアル 第3版

既に「Python チュートリアル 第3版」の書評記事を書いている.

kakakakakku.hatenablog.com

「章ごとの出題数」は以下のように公開されている.勘に頼る必要もなく,主教材を全体的に学ぶ必要がある.

セクション 出題数 出題率
1章. 食欲をそそってみようか 1 2.5%
2章. Pythonインタープリタの使い方 1 2.5%
3章. 気楽な入門編 6 15.0%
4章. 制御構造ツール 9 22.5%
5章. データ構造 7 17.5%
6章. モジュール 2 5.0%
7章. 入出力 1 2.5%
8章. エラーと例外 4 10.0%
9章. クラス 2 5.0%
10章. 標準ライブラリめぐり 4 10.0%
11章. 標準ライブラリめぐり - PartII 1 2.5%
12章. 仮想環境とパッケージ 1 2.5%
13章. 次はなに? 0 0%
14章. 対話環境での入力行編集とヒストリ置換 1 2.5%

Python コードを書く & 読む

重要なのは主教材を読むだけではなく,実際に Python コードを書いたり,読んだりすることだと思う.オススメは「Jupyter Notebook」で,Markdown で Python コードとメモを合わせてドキュメント化することができる.他にも「PyCharm」をインストールしておくと,コードを書きやすくなるし,「PyCharm Python Console」は IPython に対応していて,インタラクティブに動作確認をするときにも便利に使える.

jupyter.org

模擬試験(無料)

認定スクール「DIVE INTO EXAM」から無料で提供されている模擬試験がある.まだ β であると記載されているけど,計80問あり,試験同様に計40問出題される.模擬試験の受験回数に制限はなく,何度も何度も繰り返し受験できる.少なくとも1度は受験しておくと良いと思う.

diver.diveintocode.jp

試験結果レポート 🎉

試験を終えると,すぐに試験結果レポートが出る.満点合格できたら良いなぁーと考えていたけど,今回は「925点」となり,計3問間違えてしまった!残念すぎる.セクションごとに正解率も出るし,個人的に間違えた箇所も全部把握できている.むむ!

セクション 正解率
1. 食欲をそそってみようか 100%
2. Pythonインタープリタの使い方 100%
3. 気楽な入門編 100%
4. 制御構造ツール 89%
5. データ構造 86%
6. モジュール 100%
7. 入出力 100%
8. エラーと例外 100%
9. クラス 100%
10. 標準ライブラリめぐり 75%
11. 標準ライブラリめぐり - PartII 100%
12. 仮想環境とパッケージ 100%
13. 対話環境での入力行編集とヒストリ置換 100%

まとめ

  • 「Python 3 エンジニア認定基礎試験」に合格した
    • 取得済資格 : 計38個目(期限切れも含めると)
  • 主教材を読むだけではなく,実際に Python コードを書いたり,読んだりする勉強方法が1番効果的だと思う
  • 無料で受験できる模擬試験も,少なくとも1度は受験しておくと良いと思う
  • 今年の夏に「Python 3 エンジニア認定データ分析試験」が開始される予定なので,公式 Twitter は要チェック!

twitter.com

Docker 公式のセキュリティ診断ツール「Docker Bench for Security」を試した

$
0
0

最近 Docker 関連のセキュリティツールを調査する機会があり,今回は「Docker Bench for Security」を試したログを残しておく.「Docker Bench for Security」は Docker から公式に提供されているセキュリティ診断ツールで,具体的には「CIS Docker Community Edition Benchmark v1.1.0」をサポートしている.

github.com

コンテナ実行

「Docker Bench for Security」を実行する方法は複数ある.1番簡単なのはコンテナを実行する方法で,Docker イメージ「docker/docker-bench-security」が Docker Hub に公開されている.

注意点としては,コンテナから CAP_AUDIT_CONTROLケーパビリティなどの特権を許可する必要があることと,診断対象となるディレクトリをコンテナから参照できるようにする必要がある.GitHub に載っているコマンドはあくまでサンプルで,systemd を指定しているため,CentOS 7 系を前提にしているように思う.

$ docker run -it--net host --pid host --userns host --cap-add audit_control \-eDOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST\-v /var/lib:/var/lib \-v /var/run/docker.sock:/var/run/docker.sock \-v /usr/lib/systemd:/usr/lib/systemd \-v /etc:/etc --label docker_bench_security \
    docker/docker-bench-security

シェル実行

「Docker Bench for Security」のリポジトリを clone して docker-bench-security.shを実行すると,シェルですぐに診断ができる.診断項目を include / exclude するオプションもあり,柔軟に使える.

$ ./docker-bench-security.sh

$ ./docker-bench-security.sh -c check_1_1

$ ./docker-bench-security.sh -c check_1_1,check_1_2

$ ./docker-bench-security.sh -h
  usage: docker-bench-security.sh [options]-b           optional  Do not print colors-h           optional  Print this help message
  -l FILE      optional  Log output in FILE
  -c CHECK     optional  Comma delimited list of specific check(s)-e CHECK     optional  Comma delimited list of specific check(s) to exclude
  -i INCLUDE   optional  Comma delimited list of patterns within a container name to check
  -x EXCLUDE   optional  Comma delimited list of patterns within a container name to exclude from check
  -t TARGET    optional  Comma delimited list of images name to check

ちなみに docker-bench-security.shの内部では ssコマンドを使っているため,Mac で Docker for Mac を診断しようとすると,以下のエラーが出る.とは言え,Mac で診断をするシチュエーションはあまりなさそう.

$ ./docker-bench-security.sh
ss command not found.

診断項目

GitHub Wiki などに診断項目の一覧がまとまってなく,自分用に整理をした.診断項目の実装は GitHub で testsディレクトリ直下のシェルを読めばわかる.基本的にはシェル芸で実装されている.

  • 1 - Host Configuration
    • 1.1 - Ensure a separate partition for containers has been created
    • 1.2 - Ensure the container host has been Hardened
    • 1.3 - Ensure Docker is up to date
    • 1.4 - Ensure only trusted users are allowed to control Docker daemon
    • 1.5 - Ensure auditing is configured for the Docker daemon
    • 1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker
    • 1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker
    • 1.8 - Ensure auditing is configured for Docker files and directories - docker.service
    • 1.9 - Ensure auditing is configured for Docker files and directories - docker.socket
    • 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker
    • 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json
    • 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd
    • 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc
  • 2 - Docker daemon configuration
    • 2.1 - Ensure network traffic is restricted between containers on the default bridge
    • 2.2 - Ensure the logging level is set to 'info'
    • 2.3 - Ensure Docker is allowed to make changes to iptables
    • 2.4 - Ensure insecure registries are not used
    • 2.5 - Ensure aufs storage driver is not used
    • 2.6 - Ensure TLS authentication for Docker daemon is configured
    • 2.7 - Ensure the default ulimit is configured appropriately
    • 2.8 - Enable user namespace support
    • 2.9 - Ensure the default cgroup usage has been confirmed
    • 2.10 - Ensure base device size is not changed until needed
    • 2.11 - Ensure that authorization for Docker client commands is enabled
    • 2.12 - Ensure centralized and remote logging is configured
    • 2.13 - Ensure operations on legacy registry (v1) are Disabled (Deprecated)
    • 2.14 - Ensure live restore is Enabled
    • 2.15 - Ensure Userland Proxy is Disabled
    • 2.16 - Ensure daemon-wide custom seccomp profile is applied, if needed
    • 2.17 - Ensure experimental features are avoided in production
    • 2.18 - Ensure containers are restricted from acquiring new privileges
  • 3 - Docker daemon configuration files
    • 3.1 - Ensure that docker.service file ownership is set to root:root
    • 3.2 - Ensure that docker.service file permissions are set to 644 or more restrictive
    • 3.3 - Ensure that docker.socket file ownership is set to root:root
    • 3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive
    • 3.5 - Ensure that /etc/docker directory ownership is set to root:root
    • 3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictive
    • 3.7 - Ensure that registry certificate file ownership is set to root:root
    • 3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictive
    • 3.9 - Ensure that TLS CA certificate file ownership is set to root:root
    • 3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictive
    • 3.11 - Ensure that Docker server certificate file ownership is set to root:root
    • 3.12 - Ensure that Docker server certificate file permissions are set to 444 or more restrictive
    • 3.13 - Ensure that Docker server certificate key file ownership is set to root:root
    • 3.14 - Ensure that Docker server certificate key file permissions are set to 400
    • 3.15 - Ensure that Docker socket file ownership is set to root:docker
    • 3.16 - Ensure that Docker socket file permissions are set to 660 or more restrictive
    • 3.17 - Ensure that daemon.json file ownership is set to root:root
    • 3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive
    • 3.19 - Ensure that /etc/default/docker file ownership is set to root:root
    • 3.20 - Ensure that /etc/default/docker file permissions are set to 644 or more restrictive
  • 4 - Container Images and Build File
    • 4.1 - Ensure a user for the container has been created
    • 4.2 - Ensure that containers use trusted base images
    • 4.3 - Ensure unnecessary packages are not installed in the container
    • 4.4 - Ensure images are scanned and rebuilt to include security patches
    • 4.5 - Ensure Content trust for Docker is Enabled
    • 4.6 - Ensure HEALTHCHECK instructions have been added to the container image
    • 4.7 - Ensure update instructions are not use alone in the Dockerfile
    • 4.8 - Ensure setuid and setgid permissions are removed in the images
    • 4.9 - Ensure COPY is used instead of ADD in Dockerfile
    • 4.10 - Ensure secrets are not stored in Dockerfiles
    • 4.11 - Ensure verified packages are only Installed
  • 5 - Container Runtime
  • 6 - Docker Security Operations
    • 6.1 - Avoid image sprawl
    • 6.2 - Avoid container sprawl
  • 7 - Docker Swarm Configuration
    • 7.1 - Ensure swarm mode is not Enabled, if not needed
    • 7.2 - Ensure the minimum number of manager nodes have been created in a swarm (Swarm mode not enabled)
    • 7.3 - Ensure swarm services are binded to a specific host interface (Swarm mode not enabled)
    • 7.4 - Ensure data exchanged between containers are encrypted on different nodes on the overlay network
    • 7.5 - Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster (Swarm mode not enabled)
    • 7.6 - Ensure swarm manager is run in auto-lock mode (Swarm mode not enabled)
    • 7.7 - Ensure swarm manager auto-lock key is rotated periodically (Swarm mode not enabled)
    • 7.8 - Ensure node certificates are rotated as appropriate (Swarm mode not enabled)
    • 7.9 - Ensure CA certificates are rotated as appropriate (Swarm mode not enabled)
    • 7.10 - Ensure management plane traffic has been separated from data plane traffic (Swarm mode not enabled)

改善 : 1 - Host Configuration

今回は Amazon Linux 2 を検証用ホストとして,Docker 18.06.1-ce のデフォルト状態に対して「Docker Bench for Security (1 - Host Configuration)」を実行した.すると,計7項目が WARN になった.今回は「auditd」 で Docker 関連の監査ログを取れるようにする.

$ ./docker-bench-security.sh -c check_1,check_1_1,check_1_2,check_1_3,check_1_4,check_1_5,check_1_6,check_1_7,check_1_8,check_1_9,check_1_10,check_1_11,check_1_12,check_1_13

(中略)

[INFO]1 - Host Configuration
[WARN] 1.1  - Ensure a separate partition for containers has been created
[NOTE] 1.2  - Ensure the container host has been Hardened
[INFO] 1.3  - Ensure Docker is up to date
[INFO]      * Using 18.06.1, verify is it up to date as deemed necessary
[INFO]      * Your operating system vendor may provide support and security maintenance for Docker
[INFO] 1.4  - Ensure only trusted users are allowed to control Docker daemon[INFO]      * docker:x:993:
[WARN] 1.5  - Ensure auditing is configured for the Docker daemon[WARN] 1.6  - Ensure auditing is configured for Docker files and directories - /var/lib/docker
[WARN] 1.7  - Ensure auditing is configured for Docker files and directories - /etc/docker
[WARN] 1.8  - Ensure auditing is configured for Docker files and directories - docker.service
[INFO] 1.9  - Ensure auditing is configured for Docker files and directories - docker.socket
[INFO]      * File not found
[INFO] 1.10  - Ensure auditing is configured for Docker files and directories - /etc/default/docker
[INFO]      * File not found
[INFO] 1.11  - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json
[INFO]      * File not found
[WARN] 1.12  - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd
[WARN] 1.13  - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc

[INFO] Checks: 13[INFO] Score: -7

以下の設定になるように /etc/audit/rules.d/audit.rulesを修正する.

$ auditctl -l
-w /usr/bin/docker -p wa
-w /var/lib/docker -p wa
-w /etc/docker -p wa
-w /usr/lib/systemd/system/docker.service -p wa
-w /lib/systemd/system/docker.socket -p wa
-w /usr/bin/docker-containerd -p wa
-w /usr/bin/docker-runc -p wa

すると,WARN を残り1個まで改善できた.項目 1.1 は docker info -f '{{ .DockerRootDir }}'で取得できるディレクトリを別ファイルシステムにすると改善できる.今回は実施しなかった.

$ ./docker-bench-security.sh -c check_1,check_1_1,check_1_2,check_1_3,check_1_4,check_1_5,check_1_6,check_1_7,check_1_8,check_1_9,check_1_10,check_1_11,check_1_12,check_1_13

(中略)

[INFO]1 - Host Configuration
[WARN] 1.1  - Ensure a separate partition for containers has been created
[NOTE] 1.2  - Ensure the container host has been Hardened
[INFO] 1.3  - Ensure Docker is up to date
[INFO]      * Using 18.06.1, verify is it up to date as deemed necessary
[INFO]      * Your operating system vendor may provide support and security maintenance for Docker
[INFO] 1.4  - Ensure only trusted users are allowed to control Docker daemon[INFO]      * docker:x:993:
[PASS] 1.5  - Ensure auditing is configured for the Docker daemon[PASS] 1.6  - Ensure auditing is configured for Docker files and directories - /var/lib/docker
[PASS] 1.7  - Ensure auditing is configured for Docker files and directories - /etc/docker
[PASS] 1.8  - Ensure auditing is configured for Docker files and directories - docker.service
[INFO] 1.9  - Ensure auditing is configured for Docker files and directories - docker.socket
[INFO]      * File not found
[INFO] 1.10  - Ensure auditing is configured for Docker files and directories - /etc/default/docker
[INFO]      * File not found
[INFO] 1.11  - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json
[INFO]      * File not found
[PASS] 1.12  - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd
[PASS] 1.13  - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc

[INFO] Checks: 13[INFO] Score: 5

改善 : 4 - Container Images and Build File

次に「Docker Bench for Security (4 - Container Images and Build File)」を実行した.すると,計1項目が WARN になった.

$ ./docker-bench-security.sh -c check_4_1,check_4_2,check_4_3,check_4_4,check_4_5,check_4_6,check_4_7,check_4_8,check_4_9,check_4_10,check_4_11

(中略)

[INFO] 4.1  - Ensure a user for the container has been created
[INFO]      * No containers running
[NOTE] 4.2  - Ensure that containers use trusted base images
[NOTE] 4.3  - Ensure unnecessary packages are not installed in the container
[NOTE] 4.4  - Ensure images are scanned and rebuilt to include security patches
[WARN] 4.5  - Ensure Content trust for Docker is Enabled
[PASS] 4.6  - Ensure HEALTHCHECK instructions have been added to the container image
[PASS] 4.7  - Ensure update instructions are not use alone in the Dockerfile
[NOTE] 4.8  - Ensure setuid and setgid permissions are removed in the images
[PASS] 4.9  - Ensure COPY is used instead of ADD in Dockerfile
[NOTE] 4.10  - Ensure secrets are not stored in Dockerfiles
[NOTE] 4.11  - Ensure verified packages are only Installed

[INFO] Checks: 11[INFO] Score: 1

項目 4.5 は「Docker Content Trust (DCT)」を有効化すると改善できる.

docs.docker.com

今回は環境変数 DOCKER_CONTENT_TRUSTを設定して診断をすると,改善できた.

$ export DOCKER_CONTENT_TRUST=1
$ ./docker-bench-security.sh -c check_4_1,check_4_2,check_4_3,check_4_4,check_4_5,check_4_6,check_4_7,check_4_8,check_4_9,check_4_10,check_4_11

(中略)

[INFO] 4.1  - Ensure a user for the container has been created
[INFO]      * No containers running
[NOTE] 4.2  - Ensure that containers use trusted base images
[NOTE] 4.3  - Ensure unnecessary packages are not installed in the container
[NOTE] 4.4  - Ensure images are scanned and rebuilt to include security patches
[PASS] 4.5  - Ensure Content trust for Docker is Enabled
[PASS] 4.6  - Ensure HEALTHCHECK instructions have been added to the container image
[PASS] 4.7  - Ensure update instructions are not use alone in the Dockerfile
[NOTE] 4.8  - Ensure setuid and setgid permissions are removed in the images
[PASS] 4.9  - Ensure COPY is used instead of ADD in Dockerfile
[NOTE] 4.10  - Ensure secrets are not stored in Dockerfiles
[NOTE] 4.11  - Ensure verified packages are only Installed

[INFO] Checks: 11[INFO] Score: 3

プルリクエストを出した 🎉

docker-bench-security.shの実装を読みながら README.mdに書いてあるオプション一覧を確認したところ,今月に追加されたオプション -tREADME.mdに反映されていないことに気付いた.さっそく README.mdを修正し,プルリクエストを出して,すぐに merge してもらえた!

github.com

なお Docker (Moby) 関連のリポジトリにプルリクエストを出す場合,コミットメッセージに署名を追加する必要がある.詳しくは CONTRIBUTING.mdに書いてある.覚えておこう!

github.com

まとめ

  • 「CIS Docker Community Edition Benchmark v1.1.0」をサポートしている診断ツール「Docker Bench for Security」を試した
  • コンテナを実行する方法とシェルを実行する方法がある
  • 例えば auditd を有効化するなど,診断結果を使って改善できる
  • README.mdを修正するプルリクエストを出して merge してもらえた!

関連ツールなど

www.aquasec.com

www.twistlock.com

sysdig.com

Viewing all 925 articles
Browse latest View live