Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

WindowsでGitLabを構築(Docker)

f:id:fa11enprince:20200413013004j:plain
Docker DesktopによるGitLab構築方法の紹介です。
一応、初心者向きにはなっていますが、
Dockerの基礎知識は知っている前提の記事です。
Windows + Docker Desktop (旧版 Docker for Windowsでも可)で構築します。
Windowsでも動けば、Mac/Linux等でも動くでしょう。
Windows固有のハマりポイントはマウントの設定でしょうか

Dockerは気づくとITエンジニアほぼ必須の知識になってしまいました。
正直ここまで広まるとは思っていませんでした。
一部環境ではVT-x(インテル 仮想化支援機構)がONにするのを許されていなくて、
手元でDocker使えない、不便だーなんてことが起きてますが、
その場合はあきらめて開発サーバーを建てましょう(わたしもご多分に漏れず…)。
Docker使う場合は基本的にはLinuxがベターではあります。
とはいえどういうわけか手元にはWindowsマシン(Windows 10 Pro Edition)しかないみたいなときとか役に立つかと。

この記事について

docker-composeにてサクッとGitLabを立ててみようという記事です。
ただ、デフォルトのままではメール設定どうすんの?
とかWindowsの場合、ちょっとハマりがあったりとか、
そもそも遅いとか言った問題があるかと思います。
GitLabで使うデフォルトはPostgreSQLです。
https://docs.gitlab.com/omnibus/settings/database.html

こだわりがなければこのまま使います。 ちなみに、Dockerを使っている人はご存知かと思いますが、 Docker内のデータは一度止めてしまうと基本的にすべて消えてしまいます。
そのために、ホスト側にデータ領域をマウントし、再起動時にそこから読むことで永続化を行っています。

前提条件

私の環境は以下です。多少異なっていてもおそらく大丈夫かと思います。
かなり古い場合でなければ、特にDocker for Windowsでも大丈夫かと。

OS/ソフト バージョン
Windows 10 1903
Docker Desktop community 2.2.0.4

設定方法

Docker Desktopおよびホスト側の設定

Settings > Resources > File Sharing でCドライブを選びます

docker volume の作成

Windowsでは起動時に権限がらみのエラーが発生してしまうので、
マウントするのに名前付きボリュームを利用します。 docker volume lsでその一覧があとで参照できます。
実際にどこにマウントされているかはDocker DesktopのDashBoardのコンテナのInspectから参照することもできます。

docker-composeの設定

ドキュメント(Documents)ディレクトリ配下
%USERPROFILE%\Documents
docker\gitlab
というフォルダを作り、そこにdocker-compose.ymlを作成します
今回はPostgreSQL使用、
メールはGmail使用
としました。 この辺りの設定(GITLAB_OMNIBUS_CONFIG [/etc/gitlab/gitlab.rb])は
gitlab-ctl reconfigureで設定できる内容です(詳細割愛)。
GitLab的にはGmailは非推奨のようですが、例として使いやすいのでGmailで説明します。
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/smtp.md
下記に示した内容をいくつか置き換えて社内メール等を設定すれば環境構築できるかと思います。
大抵のケースの場合SMTP周りの設定をしておけばいいと思われます。

version: "3.6"

services:
  web:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: '127.0.0.1'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://127.0.0.1:8929'
        gitlab_rails['gitlab_shell_ssh_port'] = 50022
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "smtp.gmail.com"
        gitlab_rails['smtp_port'] = 587
        
        gitlab_rails['smtp_domain'] = "smtp.gmail.com"
        gitlab_rails['smtp_authentication'] = "login"
        gitlab_rails['smtp_enable_starttls_auto'] = true
        gitlab_rails['smtp_tls'] = false
        gitlab_rails['smtp_openssl_verify_mode'] = 'peer'

        gitlab_rails['smtp_user_name'] = "<your gmail address>"
        gitlab_rails['smtp_password'] = "<your passowrd>"
        
        # Gitlab tuning
        unicorn['worker_processes'] = 2
        unicorn['worker_timeout'] = 600
        postgresql['shared_buffers'] = "512MB"
        
    ports:
      - '8929:8929'
      - '50022:22'
    volumes:
      - 'gitlab_config:/etc/gitlab'
      - 'gitlab_log:/var/log/gitlab'
      - 'gitlab_data:/var/opt/gitlab'

volumes:
  gitlab_config:
    external: true
  gitlab_log:
    external: true
  gitlab_data:
    external: true

1点注意事項があります。 2段階認証プロセスを使っている場合、あれれ?メールが飛ばないなんてことがあります。

Gmail を使って Net::SMTPAuthenticationError が出力される場合の解決法 https://karur4n.hatenablog.com/entry/2015/03/07/234600

この場合上記に従い、アプリパスワードを使います。

社内メールを使用する場合

仕事で使う場合は、社内メールだと思いますので
doc/settings/smtp.md · master · GitLab.org / omnibus-gitlab · GitLab
あたりの設定が参考になるのではないでしょうか。

パフォーマンスチューニングについて

GitLabは結構マシンパワーを要求するのでpostgresql['shared_buffers']を大きめにとったほうが良いかと思います。
できれば2GB以上あったほうがサクサク動きます。
unicorn['worker_processes']も多いほど良いです。

名前付きボリュームの作成

コマンドプロンプトにて初回のみ

docker volume create --name gitlab_config
docker volume create --name gitlab_data
docker volume create --name gitlab-logs

として名前付きボリュームを作成します。

サーバー立ち上げ

コマンドプロンプトにて

cd %USERPROFILE%\Documents
docker-compose up -d

で起動します。

立ち上がりはマシンによっては遅いのでカップラーメンを食べながら待ちます。
Dockerのタスクトレイ内のアイコンを右クリックして、
Dashboardにアクセスすると、起動状態が確認できます。

GitLabにアクセス

しばらくたつと、 http://127.0.0.1:8929/
にアクセスします。

初回はrootのパスワードを求められます。

ユーザを作成した時にメールが飛べば成功です。

あとは煮るなり焼くなり。
GitHub同様使いやすいかと思います。

参考リンク

https://docs.gitlab.com/omnibus/docker/
https://mikoto2000.blogspot.com/2018/06/gitlab-docker-image-https.html https://myamada9999.hatenablog.com/entry/2018/11/04/204613
https://qiita.com/TomoyukiSugiyama/items/b17800d4e142e3dc549b
https://qiita.com/comefigo/items/2066dd02e2a0f3b470ca

チューニング系参考リンク

http://www.sakutyuu.com/technology/?p=1979
https://qiita.com/k_nakayama/items/9f083a4700915d02104a

名前付きボリューム関連

https://tan-y.hatenablog.com/entry/2019/02/26/003000
https://mikoto2000.blogspot.com/2018/06/gitlab-docker-image-https.html

Docker Desktopのマウント問題

https://qiita.com/kikako/items/7b6301a140cf37a5b7ac
https://stackoverflow.com/questions/41036273/disable-autostart-of-docker-compose-project

docker volume削除

https://qiita.com/Ikumi/items/b319a12d7e2c9f7b904d

メール関連

https://h-otter.hatenablog.jp/entry/2015/07/31/220511
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/smtp.md

GitLab CE Omnibus の基本操作手順

https://fumiyas.github.io/gitlab/install-omnibus.html

Dockerのコマンド体系がわかりにく過ぎる

f:id:fa11enprince:20200408042801p:plain Docker自体は素晴らしいアプリケーションで、作っていただいている方、メンテナンスをされている方に畏敬の念を禁じえません。
CLIのフロントエンド、コマンド体系が理解するのが難しいと言わざるを得ません。理由としては、一見よく使うコマンドの対称性がないために、Dockerのライフサイクルとのイメージが慣れるまでズレてしまい、マッピングがよくわからずとっつきにくい印象を与えてしまうと思われるのです。
これはおそらく私だけではないはず。説明するときに毎度苦労します。
dokcer execdocker runって似ているけど何が違うの?とかdocker startもあるし、まぎらわしくない?とか、docker rmとかよくわからない…となると思います。
同様のことはGitにもあると思っています。
dockerの新体系のコマンドもありますが、こちらでは紹介しません。(一貫性がやや出てきたものの…)そもそもタイプ量が増えていやです。 ここでは旧体系のコマンドで記載します。

Dockerのライフサイクル

まず、Dockerのライフサイクルですが、この図が最小限の重要なところを表しています
f:id:fa11enprince:20200408034301p:plain

Dockerのコマンド体系

異論はあると思いますが、上図にマッピングするとこんな感じです

dockerの実際のコマンド 用途 備考
docker create image . docker build . Dockerイメージを作成 | cdして Dockerfileのあるディレクトリで使用
docker create [イメージ名] --name [プロセス名] Dockerイメージからコンテナを作成 複合コマンドrunがあるので使わないが、概念上知る必要がある
docker start [コンテナ名] Dockerコンテナからプロセスを開始状態にする 複合コマンドrunがあるので使わないが、概念上知る必要がある
docker run [コンテナ名] --name [プロセス名] Dockerイメージからコンテナを作成しプロセスを開始状態にする このコマンドが最難関(後述)
docker stop [プロセス名] プロセスを終了状態にする
docker rm [コンテナ名] Dockerコンテナを破棄する
docker rmi [イメージ名] Dockerイメージを破棄する

docker runについてですが、サーバ起動の場合(例: Express, Flaskの場合) docker run -itd --rm [コンテナ名] --name [プロセス名]のように使います。 単発起動の場合は docker run -it --rm [container name] --name [プロセス名] のように使います(通常は、DockerfileのCMDで指定されているものを実行したい場合が多いと思うが、lessとか使いたい場合はコマンドも指定できる)。さらに実質これを使うときは-p(ポートを外部にさらす)や-v(マウント)のオプションも必要になるケースが多いと思います。 あと、とっつきにくい点があるとすればdocker run時のオプション順を間違えるとエラーになってしまう点でしょうか。

番外編

Docker execいつ使うの?

docker exec -it [container name] /bin/bash[/bin/sh] の形でほぼ使い、バックグラウンドで動きっぱなしのコンテナの中に入る場合に使う
というか、バックグラウンド起動している場合以外中に入る必要性がほぼない。
これもdocker in [container name] [shell]とか作ればいいのにとか思う。

docker attachはまず使わないので無視してOK

あとはprocess確認系のコマンドも必須で覚える事項ですが、 これだけ覚えてしまえばdocker-composeとかもほぼ一緒なので実は大して覚えることがないはず。

JavaScriptで使えるグラフ描画ライブラリとその有効活用例について

f:id:fa11enprince:20200327025625j:plain ふとニュースなどをみていて、新型コロナウィルスの感染状況のグラフのサイトを見つけて、お、綺麗だしシンプルでいいなと思ったのがここ。
よくある質問の部分も、一見、グラフを眺めていて、ん???と思う疑問点が書かれてあって良い。

「具体的な基準はMITライセンスに準拠します」とさらりと書いてあるだけなのがクール。もちろんGitHubへのリンクもあります。 これ厳密に従うとちょっと面倒なんですよね。とはいえ、数あるライセンスの中でも緩い縛りのMITライセンス。
単なるリンクまたはiframeであれば著作権表示はいらないのですが、せっかくなのでスクリーンショットを拝借しました。
ということで厳密に対応してみました。ただ、ライセンスファイルはブログの関係上置けないので、貼り付けました。 f:id:fa11enprince:20200327031353p:plain https://github.com/kaz-ogiwara/covid19/

MIT License

Copyright (c) 2020 Kazuki OGIWARA / 荻原 和樹

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

一応これは何だっていうのを解説しておくと要はMITの場合

  • このソフトウェアを誰でも無償で無制限に扱って良い。ただし、著作権表示および本許諾表示をソフトウェアのすべての複製または重要な部分に記載しなければならない。
  • 作者または著作権者は、ソフトウェアに関してなんら責任を負わない。

という2点が大事です。

本題とはそれますが、こういうのって、いかにデータを集めるかというのが大変ですよね・・・。

Chart.jsいいなと思って、ふとグラフ描画ライブラリって何がいいんだろうなーとふと思いました。 自分が使ったことあるのはPlotly.js。d3.jsを拡張していてインタラクティブで綺麗で、きめ細かい設定が簡単にできて仕事で使ってました。 PythonでもJavaScriptでも使えるし。 が、このChart.jsもいいなと。あと有償ですが有名どころだとHighcharts.jsもありますよね。

代表的なグラフライブラリのリンク

https://www.chartjs.org/
https://plotly.com/javascript/
https://www.highcharts.com/

比較

https://tech.willgate.co.jp/entry/2018/03/20/141000
https://www.npmtrends.com/chart.js-vs-highcharts-vs-plotly.js-vs-taucharts
Chart.js強いなーという感じです。

僕はPlotly.js推しです(というかそれしか使ったことない)。 リファレンスもまぁまぁ充実しているし、細かいことをやろうと思うと、ソースコードを読めば、 あ、これも設定できるんだとわかるし。よかったです。 あれなんですよね。等高線(コンター)図で綺麗なのを描きたかったり、場合によっては3Dにしたいなと思ったので…前回はそれを選んだのかな。 でも、周りでChart.jsのこともよく聞くので、今度使ってみようかなと思いました。

VSCodeでPython3開発環境構築

f:id:fa11enprince:20200211214101j:plain

WindowsでVSCodeとAnaconda3(Python3)で開発環境を整えることにしました。
目標は次の通りです。

  • VSCode上で関数の定義へのジャンプや参照、コード補完ができる
  • docstring(JavaでいうJavadoc)が楽にかける
  • テストのカバレッジ取得及び通ったコードパスが視覚的にわかる

あと、開発環境と違うけれど…

  • loggerの使い方例
  • ソースコードの構成例

を一緒にまとめて置いておきました。
この例では極小の意味のないアプリケーションですが、MongoDBを使うサンプルになっています。 ここに書いてある
requirements.txtによる方法は既に古いらしいので別の方法にしたほうがいいそうです。

補足事項

Pythonの環境切替

この記事のようにAnaconda2 ,3の両方を入れている場合、VSCodeのこの部分から変更ができる
f:id:fa11enprince:20200211215021p:plain
Python 3.7,4 64-bitってところが実はクリックできて、ここで切り替え可能です。

カバレッジのコードハイライト

Coverage Gutters - Visual Studio Marketplace ここのアニメーションの通りなのですが、先ほどと同様に下部のWatch/Remove watchから表示切替ができます。

単体テスト実行について

基本的に該当のフォルダに移動して(PYTHONPATH/モジュール検索パスが通っているところ)で unittest
python -m unitest discoverとやっていたところを
coverage run -m unitest discoverとやればOKです。
ただしunittest前提です。pytestを使っている場合は別の方法になります。

pushd app1\test
coverage run -m unittest discover && coverage xml
popd

discoverってなんだ?と思ったらTestLoader.discover()を呼び出しているそうです。