20201022のdockerに関する記事は16件です。

Docker Gradle Quick reference

Docker Hub の Gradle 公式イメージの説明書き の日本語訳。

Gradle とは?

Gradle は、ビルドの自動化と多言語開発のサポートに重点を置いたビルドツールです。
任意のプラットフォームでソフトウェアを構築、テスト、公開、デプロイする場合、 Gradle はコードのコンパイルとパッケージ化から Web サイトの公開までの開発ライフサイクル全体をサポートできる柔軟なモデルを提供します。
Gradle は Java, Scala, Android, C/C++, Groovy などの複数の言語とプラットフォームにわたるビルド自動化をサポートするように設計されており、Eclipse, IntelliJ, Jenkins などの開発ツールや継続的インテグレーションサーバーと緊密に統合されています。

このイメージの使い方

Gradle プロジェクトの構築

ビルドする Gradle プロジェクトのディレクトリから下記を実行します。

docker run --rm -u gradle -v "$PWD":/home/gradle/project -w /home/gradle/project gradle gradle <gradle-task>

上記のコマンドは root として実行されるのを避ける為に uid/gid 1000(ユーザー gradle)を使用して実行されることに注意してください。
ボリュームをマウントしており、 Docker を実行している uid/gid が 1000 でない場合は、ユーザー root( -u root ) として実行する必要があります。
root もデフォルトであるため、単純にユーザーを指定しないこともできます。

ライセンス

このイメージに含まれているソフトウェアのライセンス情報を表示します。
すべての Docker イメージと同様に、これらには他のライセンスの下にある可能性のある他のソフトウェア(ベースディストリビューションの Bash など、含まれているプラ​​イマリソフトウェアの直接的または間接的な依存関係)も含まれている可能性があります。
自動検出できたいくつかの追加のライセンス情報は、 repo-info リポジトリの gradle/ ディレクトリにある可能性があります。
ビルド済みのイメージの使用に関しては、このイメージの使用が、そこに含まれるすべてのソフトウェアに関連するライセンスに準拠していることを確認するのはイメージユーザーの責任です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker まとめ

Docker hub

Dockerレジストリの一つ
色々なリポジトリ(箱)があり、リポジトリに対して1種類のDocker imageが管理されている。
(タグが異なるdocker imageが複数入っている)

Dockerレジストリ

「Docker image」を保管している場所

Docker image

コンテナを作る元となるもの
タグと呼ばれるバージョンを管理する機能がある。

コマンド

docker login

docker hubにアクセスできる状態になる。

docker pull [image]

imageをdocker hubからローカル(ホスト、自分のパソコン)に持ってくる

docker run -it [image] bash

Docker imageからコンテナを作る

exit

コンテナから抜ける

docker ps -a

コンテナの状況を確認する
※ps・・・process status

docker images

ホストにあるimageのリストを表示

docker restart

コンテナをupの状態にする

docker exec -it [container] bash

コンテナに対して、指定したプログラム(bash)を実行する

docker commit [container] [image]

コンテナからimageにする
(新しいimageを作る)

docker tag [source] [target]

imageを新しい名前にタグ付けし直す。
古いimageは残ったままで、新しいimageの名前ができる。

[source]・・・今のimage名
[target]・・・新しいimage名

※docker imageの名前とリポジトリの名前は一致していなければいけない

docker push [image]

docker hub にpushする

docker rmi [image]

imageを削除する
rmi・・・remove image

最後に

この記事は、かめさん( https://twitter.com/usdatascientist?s=21 )のudemyのdocker講座の( https://www.udemy.com/share/103aTRAEMfeVhaTXoB/ )書き起こしです。

※あくまで、自分のための書き残しとして投稿しているので、講座と異なる部分を含んでいる可能性があります。

かめさんのブログ( https://datawokagaku.com/docker_lecture/ )

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

3.docker(12)

コマンド

・docker run hello-world
「hello-world」 というイメージからコンテナにする

・docker run -it ubuntu bash
「ubuntu」というイメージからコンテナにする。
※ it・・・bash起動に必要なオブション
※ bash・・・コンテナ起動時に実行するプログラム

「docker image」 は複数の「image layer」 から構成されている。
dockerのコンテナが作られると、「docker image」 に新しい「image layer」 が追加される。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

2.Docker-Linux

DockerはLinuxのコンテナ技術を利用している。
Dockerで何か環境を構築するというと、LinuxOSの上に何か作っていくことになる。

LinuxのOSにはカーネルという核がある。
シェルを仲介して、カーネルに命令を出す。

シェル

bash, zsh, sh・・・

シェルを動かすためのアプリケーションがターミナル。
シェルはカーネルに接続するためのツール
Ï

環境変数

OSの上で動くプロセスが情報を共有するために使う変数

※プロセス
(ターミナル、Chromeのブラウザ・・・)

シェルの環境変数確認

コマンド 「echo $SHELL」
$・・・環境変数の目印のようなもの

環境変数作り方

コマンド 「export AGE=20」

最後に

この記事は、かめさん( https://twitter.com/usdatascientist?s=21 )のudemyのdocker講座の( https://www.udemy.com/share/103aTRAEMfeVhaTXoB/ )書き起こしです。

※あくまで、自分のための書き残しとして投稿しているので、講座と異なる部分を含んでいる可能性があります。

かめさんのブログ( https://datawokagaku.com/docker_lecture/ )

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【0からCircleCIに挑戦】CircleCIの基礎を学ぶ

背景

未経験から自社開発系企業の就職を目指します。良質なポートフォリオ作成のためCircleCIを勉強することにしました。

現状の知識レベルとしては、Ruby on railsを使って簡単なアプリケーション開発、gitを使ったバージョン管理、herokuを使ってデプロイできるレベルです。自分の忘備録かつ、同じくらいのレベルでこれからCircleCIに挑戦してみようと思っている方に向けて少しでも役に立てればと思います。

最終目標

CircleCIとは何かを理解する。CircleCIの記述の基礎を抑える。

目次

①CI/CDについて
②CircleCIが選ばれる理由・他のツールの比較
③CircleCIを使ったテストの大まかな流れ
④CircleCIの設定ファイルの記述方法について

それでは早速いきましょう。

①CI/CDについて

CI/CDの意味

CI(Continuous Integration)は継続的インテグレーションを意味し、CD(Continuous Delivery/Deployment)は継続的デリバリまたは継続的デプロイを意味します。もう少し具体的にいうと、「gitなどのバージョン管理システムにpushしたら、自動的にテストを行い、テストがクリアしたら自動でデプロイしますよ」という仕組みのことです。

※ちなみ「delivery」と「Deployment」は、前者がいつでもdeployできる状態にしておくことを意味し、後者が実際に本番環境に展開することを意味します。

CI/CDが注目されている理由

最近「DevOps」という考え方がエンジニア界に広まっているからです。「DevOps」とは開発チームと運用チームの壁を取り払いビジネスを成長させようという考え方で、CI/CDは「DevOps」を実践するための1つの手法として注目されているのです。

②CircleCIが選ばれる理由・他のツールの比較

CI/CDツールとして有名なものがいくつかあります。
それらを簡単に比較し、CircleCIが選ばれる理由を考えます。

Jekins
オンプレミス型の代表的なCI/CDツール。オープンソースであり、プラグインでの機能拡張にも優れている。

CircleCI
saas型のCI/CDツール。GitHubとの連携にも優れ、近年爆発的に伸びているDockerを使うことを推奨している。
またssh経由での接続も可能。

Travis CI
こちらもsaas型のCI/CDツール。幅広い言語に対応し、簡単な設定でCIを導入できるのが強み。

Gitlab
バージョン管理ソフトで有名なgitのCIツール。業界ではみたところそんなにまだシェアはないが今後伸びていくかも。

上記が主に有名なツールだと考えれます。
選ぶ基準に関してですが、まずはオンプレ型かsaas型かを決めます。個人レベルの開発であれば間違いなく運用コストの低いsaas型が良いでしょう。saas型であれば基本どれを使っても問題ないですが、個人的にはその中でも現状で業界内に最も普及していて、近年注目されているコンテン技術のdockerを推奨しているCircleCIを選ぶのが最も良いかなと思います。(※もちろん開発環境にDockerを使っている場合ですが)

③CircleCIを使ったテストの大まかな流れ

流れ自体は非常に簡単です。
※githubにアカウントに登録済みで、すでにリポジトリが存在している状態の前提です。
※自動デプロイについては今回は書いてません

1.circleCIのアカウントを作成(このときgithubのアカウントと連携すると楽です)
2.アカウント作成後githubと連携
3.githubから1つリポジトリを選ぶ
4.選んだリポジトリのルートディレクトリに(.circleci/config.yml)を作成する
5.CircleCi用のコードを書く
6.gitにpushする
7.自動テスト開始
8.結果がプルリクに反映される

CircleCIのコードを一度書いてしまえば、いつものgitを使った開発の流れと相違ありません。なのでネックは(.circleci/config.yml)のファイルの記述の部分になるかと思います。

④CircleCIの設定ファイルの記述方法について

YAMLファイルについて

CircleCIの設定はすべてYAMLファイルに記述します。YAMLファイルとはなにかというと、XMLやJSONと同じようにデータの記述をするフォーマットのと事です。ちなみにYAMLとは(yaml ain't markup language)の略です。自己を自己で定義しているあたりセンスを感じます。

そしてYAMLの特徴は直感的にわかりやすいことです。主に下記3つの記述方式でできています。

yaml
# ① リスト →配列のことです
- 1
- 2
- 3

# ② マップ →ハッシュのことです
name: a
id :  1
text: ccc

# ③ スカラ →リストとマップ以外
true false
null
123

もちろん実際のファイルは上記が複数行にわたって記載されるのでもう少し複雑です。しかし基本はこの3つだけなので頭にいれておきましょう。

ファイルの基本構成について

CircleCIのファイルはいくつかの構成要素によって成り立っています。1つ1つ確認しましょう。

ⅰ. プロジェクト

ファイル記述とは関係ないですが、簡単にいうとgithubのリポジトリのことをCircleCIでは1プロジェクトとして扱います。

ⅱ. ステップ

ファイル上の一番小さい単位のことです。具体的にはCircleCIで実行するコマンドリストです。(CircleCI上の概念で一番小さい単位ですが、ステップはあくまでリストなので複数行にわたることもあります)。ちなみにステップにはrunステップとビルドインステップの2種類あり、前者がユーザー自身で定義したもの、後者はCircleCIで用意された特殊なものです。

ⅲ. ジョブ

ステップのまとまりのことをジョブといいます。

ⅳ. Executor(エグゼキュータ)

ジョブ・ステップの環境のことを差します。例えば、「Docker Executor」だったらDocker環境でステップを実行します。Docker以外にも「macOS Executor」や「Machine Executor」,「windows Executor」などがあり、自由に環境を設定できます。

ⅴ. ワークフロー

ジョブの実行順序のルールのことです。基本的には1つのファイル内に複数のジョブがあり、それをどの順序で実行するかをワークフローで定義します。同時並行で実行することも可能です。またワークフローにはデータを永続する仕組みとして、キャッシュとワークスペースとアーティファクトがあります。具体例で説明します。

例えば、「Aジョブ→Bジョブ→Cジョブ」という順序で行うファイルがあるとします。「Aジョブ」が終わったら、その「Aジョブ」で行った内容を引き継いで「Bジョブ」を行いたいとします。この「Aジョブ」から「Bジョブ」へデータを共有する方法をワークスペースといいます。
次に上記手順でファイルを実行した際に「Cジョブ」でエラーがでたとします。そうした場合、ファイル修正後にまた1から、すなわち「Aジョブ」から実行する必要があります。もし「Aジョブ」や「Bジョブ」に重たいファイルを読み込むステップが入っていたら時間がかかってしまいます。そういった時、1回目で行ったファイルを引き継ぎ2回目以降スムーズにできるようにデータを共有する方法をキャッシュといいます。
そして上記のようにファイルを実行していったら、ジョブの実行結果に関するデータがたくさん生成されます。このジョブの実行結果を保存するストレージをアーティファクトといいます。
少しわかりずらいかもですが、覚えておきましょう。

ⅵ. パイプライン

実はワークフローは複数作成でき、それをまとめるものとしてパイプラインが存在します。基本的にCircleCIでは1つのプロジェクトに対し、1つの(.circleci/config.yml)しか持つことができません。すなわちワークフローをまとめるファイル上一番大きい概念であるパイプラインはプロジェクトに対し、1つだけ存在します。※ちなみにこのパイプラインをいう概念を基に今後CircleCIは新しい機能を実装していくそうです。

ⅶ. Orbs

ステップやジョブなどの一連の処理をパッケージ化し、いろんなところで使えるようにしたものをOrbsといいます。Orbsは自分でも作れますが、CircleCI orb Registryなどで公開されてるものを使うことができます。


本記事はここで一旦切ります。次回記事で具体的にファイルを記述し自動テストを実行します。

まとめ・感想

基本的にDockerとは異なり大まかな流れや役割というのは理解しやすかったです。ただ今後ファイルを記述するとなると、少し苦労思想です。あとCircleCIは日本語の資料が少ないので少し苦労しますね。引き続きがんばります。

参考

【書籍】
『CircleCI実践入門──CI/CDがもたらす開発速度と品質の両立 浦井 誠人 (著), 大竹 智也 (著), 金 洋国 (著) 』

【qiita】
いまさらだけどCircleCIに入門したので分かりやすくまとめてみた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vagrant上で作成したポートフォリオをdockerの開発環境に移行してみた

はじめに

初めまして、初投稿になりますので自己紹介と記事のきっかけについて書かせていただきます。

  • 自己紹介
    2020年9月にDMMWEBCAMPを卒業し、現在転職活動中のエンジニアです。

  • 記事のきっかけ
    他のプログラミングスクールが同じかはわかりませんが、スクール生で共通の開発環境にするために全てvagrant上で仮想環境を構築しカリキュラムとポートフォリオの作成を行っていました。そのため、0からの自力で環境構築を行ったことがなく実務を意識するのならDockerぐらいは自力で入れておきたいと思い学習し始めたのがきっかけです。
    まだまだ勉強中のため、正直かなり怪しいところは多いとは思いますが同じような勉強中の方の参考に少しでもなれば嬉しいです!

この記事で扱うこと

  • Dockerを使用した開発環境の構築
    Vagrant上でできていたことがDocker上でもできるようにするイメージです

  • Dockerfile、docker-composeなどの表記
    参考までに、Vagrantを使用していた時の開発環境は下記になります

    • OS:macOS Catalina 10.15.4
    • バックエンド: Ruby 2.5.7、Rails 5.2.4.3
    • 開発環境: Vagrant 2.2.4、SQLite (※MySQLやPostgreSQLの場合、この後の見本の表記が異なります)
    • 本番環境: MySQL2、AWS (EC2、RDS for MySQL、Route53)、Nginx、 Puma、Capistrano

スクリーンショット 2020-09-13 12.40.05.png

  • 0からの開発環境の構築で起こりうるエラーと解決した方法
    記事のきっかけにもあるように、ローカル環境の構築自体も初めてのためdocker以前のエラーもいくつかありました。解決のために参考にさせていただいた記事をメインに紹介していきたいと思います。

この記事で扱わないこと

  • Dockerfile、docker-composeなどの基礎知識

    Dockerに関する記事やyoutube多くありますがほとんどがコピペでなんとなく進んでしまうので、最初は自分でドキュメントを読みながら手を動かして全体の仕組みをなんとなく先に掴んでおくのが理解しやすいと思いました。
    参考までに自分は下記サイトで学習を始めました。各用語調べながらでも半日〜2日ほどでできる内容かつDockerのイメージが掴めるかと思いますのでおすすめです。

事前準備

$ docker version
Client: Docker Engine - Community
 Cloud integration  0.1.18
 Version:           19.03.13
 API version:       1.40
  • ポートフォリオ(Dockerの開発環境にしたいプロジェクト)をgit cloneしてくる
    記事のきっかけにもありますよう、既にポートフォリオを作成している段階のため環境構築したいものをgithubからローカル上に持ってきましょう
$ mkdir docker
 # Desktopからもしくはvagrantを使用していた時のworkディレクトリなどで実行
$ git clone git@github.com:ユーザー名/リポジトリ名.git

各ファイルの準備

Dockerとプロジェクトの準備ができたので、環境構築に必要なファイルを作成していきます

①Dockerfile

# 先ほどクローンしたディレクトリ上で
$ touch Dockerfile

下記内容を記入していきましょう

# 元となるdocker imageを指定。ポートフォリオのrubyのバージョンと合わせましょう
FROM ruby:2.5.7

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
#sqlite3を指定
RUN apt-get update && apt-get install -y sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

# コンテナ起動した時に、コンテナ内でmyappディレクトリを作成
RUN mkdir /myapp

# コンテナ内の作業ディレクトリの指定(上のRUNで作成したディレクトリ)
WORKDIR /myapp

# ホストマシンのgemfileをコピーし、コンテナ内のディレクトリに貼り付け
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

# 貼り付けたgemfileを読み込み。bundlerバージョンが2以降だとこれが必要
ENV BUNDLER_VERSION 2.1.4
RUN gem install bundler
RUN bundle install

# アプリケーション(カレントディレクトリ)をコピーして、コンテナ内のディレクトリに貼り付け
COPY . /myapp

# ポートを3000で公開
EXPOSE 3000

# コンテナにてコマンドを実行
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]
  • ENV BUNDLER_VERSION 2.1.4について
    Gefile.lockの一番下にこのような表記があるかと思いますので確認してみて下さい
Gemfile.lock
BUNDLED WITH
   2.1.4

②docker-compose.yml

# 同じディレクトリ上で
$ touch docker-compose.yml

下記内容を記入していきましょう

docker-compose.yml
version: '3'
services:
  web:
    build:
      context: ./
      dockerfile: Dockerfile 
    # 変更を保存するファイルを指定
    volumes:
      - .:/myapp
    # ポートを指定
    ports:
      - "3000:3000"
    # コンテナの起動を維持させる
    tty: true
    stdin_open: true

MySQLやPostgreSQLを使用している場合だと、web+DBの記述も必要なのですがSQLiteの場合はこちらのみで大丈夫みたいです。まだこの辺りの知識が乏しいため、ゆくゆくはMySQLに変更したいと思っております・・・

コンテナを起動してみましょう

# Dockerfileを元にdocker imageの作成
$ docker-compose build 

# docker container をバックグランドで起動
$ dokcer-compose up -d

# コンテナ内にてmigrationを更新
docker-compose run web rails db:migrate

これで、いつものlocalhost:3000で表示ができればひと段落です!

引っかかったエラーと解決した方法

大体ですが引っかかった時系列順に記載していきます。最初にも記載しておりますが、エラー内容とおそらくの原因の考察がサブで、メインが解決参考にさせていただいた記事の紹介になります。ありがとうございました

①ActiveRecord::PendingMigrationError Migrations are pending

「dokcer-compose up -d で動いているのにっ・・・!」

$ docker-compose up -d                                                  
Creating network "~~~_default" with the default driver
Creating ~~~_web_1 ... done

localhost:3000のページへアクセス時に起きたエラーです
コンテナの起動後、docker-compose run web rails db:migrate を行いましょう、あるあるな気がします
参考:docker-compose upで立ち上げたRailsでActiveRecord::PendingMigrationError Migrations are pending

②To install the missing version, run 'gem install bundler:2.1.4'

「bundleで始まるコマンド(デプロイ・Rspecなど)ができないっ・・・!」

Traceback (most recent call last):
    2: from 
    1: from 
~
Could not find 'bundler' (2.1.4) required by your /Users/ユーザー名/ディレクトリ名/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:2.1.4`

Dockerfileを作成した時に確認した、Gemfile.lockの「BUNDLED WITH 2.1.4」がローカル上で見つからないイメージです。
参考:To install the missing version, run gem install bundler:2.1.4と出たときの対処法

エラー文の通りにインストールを試してみましょう、ダメだった場合は③へ

gem install bundler -v 2.1.4

③ERROR: While executing gem ... (Gem::FilePermissionError)

ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.

「gemのインストールの権限がありませんっ・・・!」
sudoを頭につけて行うという記事も多かったですが、そのままインストールよりも「rbenv」というバージョン管理のツールを用いて行う方法の方が今後のことを考えるといい気がします。

参考1:gem installでpermissionエラーになった時の対応方法
参考2:rbenvによるRubyのインストールからHello, World!まで

rbenvの用意ができたら、もう一度やってみましょう

gem install bundler -v 2.1.4

④bundle installができない

「bundleが・・・まだダメっ・・・!」

gem installができたところで、デプロイなどの「bundle~」系を入力するとまだエラー文がでます

Install missing gem executables with `bundle install`

エラー文に従って、bundle installをしてみると

# 長いため、最後の部分だけ抜粋
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

mysql周辺のエラーですが、原因は自力ではわかりませんでした。
下記の参考にさせていただいた記事通りで私は解決できました、本当にありがたい。

参考:【Rails】MySQL2がbundle installできない時の対応方法

これでデプロイはできるようになると思います。

⑤Could not find a JavaScript runtime ~

「動いているけどっ・・・!」

Rspecを走らせた時のエラーです

$ bundle exec rspec spec/ --format documentation

An error occurred while loading ./spec/models/cart_item_spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)

ExecJS::RuntimeUnavailable:
  Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes.

githubに飛んでみると、ExecJSのどれかをダウンロードするよう勧めています。
gemをいれる方法もありましたが、Node.jsを選択してダウンロードに進めばスムーズに解決できました。

これでRspecもできるようになりました。

終わりに

vagrantからdockerへの移行の手順とエラーの紹介をさせていただきました。
まだまだ勉強不足なところも多いため、dockerを十分に活用できていない点が多くあると改めて思いました。
参考にさせていただいた記事が多かったこともあり、当初思っていたよりも短い時間で導入まではできたので挑戦してみて良かったと感じています。

以前のvagrant環境と同じことはできるようになったので、次はCircleCIの導入でより良い開発環境にできるよう学習を続けたいと思います。

初投稿ということもあり、わかりにくい部分もあったかとは思いますが最後までみていただきありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vagrant上で作成したポートフォリオをDockerの開発環境に移行してみた

はじめに

初めまして、初投稿になりますので自己紹介と記事のきっかけについて書かせていただきます。

  • 自己紹介
    2020年9月にDMMWEBCAMPを卒業し、現在転職活動中のエンジニアです。

  • 記事のきっかけ
    他のプログラミングスクールが同じかはわかりませんが、スクール生で共通の開発環境にするために全てvagrant上で仮想環境を構築しカリキュラムとポートフォリオの作成を行っていました。そのため、0からの自力で環境構築を行ったことがなく実務を意識するのならDockerぐらいは自力で入れておきたいと思い学習し始めたのがきっかけです。
    まだまだ勉強中のため、正直かなり怪しいところは多いとは思いますが同じような勉強中の方の参考に少しでもなれば嬉しいです!

この記事で扱うこと

  • Dockerを使用した開発環境の構築
    Vagrant上でできていたことがDocker上でもできるようにするイメージです

  • Dockerfile、docker-composeなどの表記
    参考までに、Vagrantを使用していた時の開発環境は下記になります

    • OS:macOS Catalina 10.15.4
    • バックエンド: Ruby 2.5.7、Rails 5.2.4.3
    • 開発環境: Vagrant 2.2.4、SQLite (※MySQLやPostgreSQLの場合、この後の見本の表記が異なります)
    • 本番環境: MySQL2、AWS (EC2、RDS for MySQL、Route53)、Nginx、 Puma、Capistrano

スクリーンショット 2020-09-13 12.40.05.png

  • 0からの開発環境の構築で起こりうるエラーと解決した方法
    記事のきっかけにもあるように、ローカル環境の構築自体も初めてのためdocker以前のエラーもいくつかありました。解決のために参考にさせていただいた記事をメインに紹介していきたいと思います。

この記事で扱わないこと

  • Dockerfile、docker-composeなどの基礎知識

    Dockerに関する記事やyoutube多くありますがほとんどがコピペでなんとなく進んでしまうので、最初は自分でドキュメントを読みながら手を動かして全体の仕組みをなんとなく先に掴んでおくのが理解しやすいと思いました。
    参考までに自分は下記サイトで学習を始めました。各用語調べながらでも半日〜2日ほどでできる内容かつDockerのイメージが掴めるかと思いますのでおすすめです。

事前準備

$ docker version
Client: Docker Engine - Community
 Cloud integration  0.1.18
 Version:           19.03.13
 API version:       1.40
  • ポートフォリオ(Dockerの開発環境にしたいプロジェクト)をgit cloneしてくる
    記事のきっかけにもありますよう、既にポートフォリオを作成している段階のため環境構築したいものをgithubからローカル上に持ってきましょう
$ mkdir docker
 # Desktopからもしくはvagrantを使用していた時のworkディレクトリなどで実行
$ git clone git@github.com:ユーザー名/リポジトリ名.git

各ファイルの準備

Dockerとプロジェクトの準備ができたので、環境構築に必要なファイルを作成していきます

①Dockerfile

# 先ほどクローンしたディレクトリ上で
$ touch Dockerfile

下記内容を記入していきましょう

# 元となるdocker imageを指定。ポートフォリオのrubyのバージョンと合わせましょう
FROM ruby:2.5.7

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
#sqlite3を指定
RUN apt-get update && apt-get install -y sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

# コンテナ起動した時に、コンテナ内でmyappディレクトリを作成
RUN mkdir /myapp

# コンテナ内の作業ディレクトリの指定(上のRUNで作成したディレクトリ)
WORKDIR /myapp

# ホストマシンのgemfileをコピーし、コンテナ内のディレクトリに貼り付け
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

# 貼り付けたgemfileを読み込み。bundlerバージョンが2以降だとこれが必要
ENV BUNDLER_VERSION 2.1.4
RUN gem install bundler
RUN bundle install

# アプリケーション(カレントディレクトリ)をコピーして、コンテナ内のディレクトリに貼り付け
COPY . /myapp

# ポートを3000で公開
EXPOSE 3000

# コンテナにてコマンドを実行
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]
  • ENV BUNDLER_VERSION 2.1.4について
    Gefile.lockの一番下にこのような表記があるかと思いますので確認してみて下さい
Gemfile.lock
BUNDLED WITH
   2.1.4

②docker-compose.yml

# 同じディレクトリ上で
$ touch docker-compose.yml

下記内容を記入していきましょう

docker-compose.yml
version: '3'
services:
  web:
    build:
      context: ./
      dockerfile: Dockerfile 
    # 変更を保存するファイルを指定
    volumes:
      - .:/myapp
    # ポートを指定
    ports:
      - "3000:3000"
    # コンテナの起動を維持させる
    tty: true
    stdin_open: true

MySQLやPostgreSQLを使用している場合だと、web+DBの記述も必要なのですがSQLiteの場合はこちらのみで大丈夫みたいです。まだこの辺りの知識が乏しいため、ゆくゆくはMySQLに変更したいと思っております・・・

コンテナを起動してみましょう

# Dockerfileを元にdocker imageの作成
$ docker-compose build 

# docker container をバックグランドで起動
$ dokcer-compose up -d

# コンテナ内にてmigrationを更新
docker-compose run web rails db:migrate

これで、いつものlocalhost:3000で表示ができればひと段落です!

引っかかったエラーと解決した方法

大体ですが引っかかった時系列順に記載していきます。最初にも記載しておりますが、エラー内容とおそらくの原因の考察がサブで、メインが解決参考にさせていただいた記事の紹介になります。ありがとうございました

①ActiveRecord::PendingMigrationError Migrations are pending

「dokcer-compose up -d で動いているのにっ・・・!」

$ docker-compose up -d                                                  
Creating network "~~~_default" with the default driver
Creating ~~~_web_1 ... done

localhost:3000のページへアクセス時に起きたエラーです
コンテナの起動後、docker-compose run web rails db:migrate を行いましょう、あるあるな気がします
参考:docker-compose upで立ち上げたRailsでActiveRecord::PendingMigrationError Migrations are pending

②To install the missing version, run 'gem install bundler:2.1.4'

「bundleで始まるコマンド(デプロイ・Rspecなど)ができないっ・・・!」

Traceback (most recent call last):
    2: from 
    1: from 
~
Could not find 'bundler' (2.1.4) required by your /Users/ユーザー名/ディレクトリ名/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:2.1.4`

Dockerfileを作成した時に確認した、Gemfile.lockの「BUNDLED WITH 2.1.4」がローカル上で見つからないイメージです。
参考:To install the missing version, run gem install bundler:2.1.4と出たときの対処法

エラー文の通りにインストールを試してみましょう、ダメだった場合は③へ

gem install bundler -v 2.1.4

③ERROR: While executing gem ... (Gem::FilePermissionError)

ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.

「gemのインストールの権限がありませんっ・・・!」
sudoを頭につけて行うという記事も多かったですが、そのままインストールよりも「rbenv」というバージョン管理のツールを用いて行う方法の方が今後のことを考えるといい気がします。

参考1:gem installでpermissionエラーになった時の対応方法
参考2:rbenvによるRubyのインストールからHello, World!まで

rbenvの用意ができたら、もう一度やってみましょう

gem install bundler -v 2.1.4

④bundle installができない

「bundleが・・・まだダメっ・・・!」

gem installができたところで、デプロイなどの「bundle~」系を入力するとまだエラー文がでます

Install missing gem executables with `bundle install`

エラー文に従って、bundle installをしてみると

# 長いため、最後の部分だけ抜粋
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

mysql周辺のエラーですが、原因は自力ではわかりませんでした。
下記の参考にさせていただいた記事通りで私は解決できました、本当にありがたい。

参考:【Rails】MySQL2がbundle installできない時の対応方法

これでデプロイはできるようになると思います。

⑤Could not find a JavaScript runtime ~

「動いているけどっ・・・!」

Rspecを走らせた時のエラーです

$ bundle exec rspec spec/ --format documentation

An error occurred while loading ./spec/models/cart_item_spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)

ExecJS::RuntimeUnavailable:
  Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes.

githubに飛んでみると、ExecJSのどれかをダウンロードするよう勧めています。
gemをいれる方法もありましたが、Node.jsを選択してダウンロードに進めばスムーズに解決できました。

これでRspecもできるようになりました。

終わりに

vagrantからdockerへの移行の手順とエラーの紹介をさせていただきました。
まだまだ勉強不足なところも多いため、dockerを十分に活用できていない点が多くあると改めて思いました。
参考にさせていただいた記事が多かったこともあり、当初思っていたよりも短い時間で導入まではできたので挑戦してみて良かったと感じています。

以前のvagrant環境と同じことはできるようになったので、次はCircleCIの導入でより良い開発環境にできるよう学習を続けたいと思います。

初投稿ということもあり、わかりにくい部分もあったかとは思いますが最後までみていただきありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初学者によるDocker理解まとめ② 〜docker-composeまで〜

はじめに

ようやくDockerを学び始めんたので自分の理解をまとめておく。

今日の学びをメモ

node.jsでexpressを実行するコンテナを立ち上げる。たったこれだけをdocker-composeを使ってやってみた。

スクリーンショット 2020-10-22 11.29.14.png

まずはローカルで準備

cd ~
mkdir sample && cd sample
yarn init -y
yarn add express
touch index.js
index.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
  res.send('Hello').status(200);
});

app.listen(3000, () => {
  console.log('Listening on port 3000');
});
node index.js

当然ですが、ローカルでcurlコマンドを叩くと返事が帰ってきますね。

curl http://localhost:3000
Hello

一応、いまの状況を図化します。一応ね。
スクリーンショット 2020-10-22 11.49.29.png

Dockerfileの準備

node.jsのdockerイメージをつくることきはここを参照する。今回はコピペ。sampleディレクトリ直下に下記のDockerfileを作る。

Dockerfile
FROM node:alpine

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .
# package.jsonをコピー後にnpm installするという作業をビルドの度に毎回やりたくない。
# そのため、上記を終わらせてから COPY. .をやる。
# そうすればコードを変えた部分だけビルドが実行される。

EXPOSE 3000
CMD [ "node", "index.js" ]

そして、node_modulesもコピーされると辛いので、.dockerignoreも作っておく。

touch .dockerignore
echo 'node_modules' >> .dockerignore

ちなみに、ここまでくれば、別にdocker-composeを使わなくても

docker build -t app .
docker run -p 3000:3000 app

をすればコンテナが立ち上がります。
今回は上記コマンドを使わず、docker-composeによってコンテナを立ち上げます。

docker-compose.ymlの準備

sampleディレクトリ直下に下記のdocker-compose.ymlを作る。

docker-compose.yml
version: '3'
#何も考えず3を指定

services:
#コンテナに関する情報を記述。ここに複数のコンテナ情報を書くことで、複数のコンテナを同時に起動できる
  app:
  # appという(DNSの名前空間を持つ)コンテナを立ち上げる。
    build:
    # ビルド時の情報をここに記載する。Dockerfileがあればそれを参照できるし、なければ直接ここに書く。
      context: .
      # ビルド時にこのdocker-compose.ymlと同じディレクトリ(.)にあるDockerfileを参照する。
      # Dockerfileが複数ある場合は、ディレクトリを分けてcontextに指定する、もしくはその名前を docokerfile:XXX として指定する必要がある。
    container_name: express-app
    # 任意のコンテナ名をつける。このコンテナ名を使って、下記コマンドでコンテナにアクセスすることができる
    # docker exec -it express-app sh
    ports:
      - '3000:3000'
    # docker run -p 3000:3000 と一緒の意味です。
    volumes:
      - './:usr/src/app'
    # ローカルPCのカレントディレクトリ(./)とコンテナの~/usr/src/appディレクトリを同期させる
    # 開発にとっても便利。

docker-compose up して終わり

docker-compose upすればコンテナが立ち上がります。
ローカルPCからcurlコマンドを打てばコンテナから返事が帰ってきます。最初の図の通りです。

curl http://localhost:3000
Hello

スクリーンショット 2020-10-22 13.30.27.png

コンテナを止めるにはdocker-compose downをします。index.jsの中身を書き換えるなどした際は、 docker-compose buildで再ビルドします。

また、docker-compose up -dとすればバックグラウンドでコンテナが立ち上がるんですが、このときはコンテナ内の console.logが見えづらかったりするので、自分はフォアグラウンドが好きです。

最後に

初歩中の初歩をまとめました。ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSL2とVSCで作るWindowsでのDocker内開発環境(2021年睦月)

初めに

こんにちは、本書をご覧になっていただき、読者のみなさまに感謝します。

最近ではDocker/K8Sの利用が増え、確実に動く環境で開発し、テストし、デバッグし、そのままデプロイすることが増えている。
現在筆者が携わっているオープンアソシエイツ(RPAテクノロジーズ/BizROBO,JimuROBO)社やスキャる社でもアプリの一部がDockerコンテナやK8Sポッドとして動き、サービスを提供している。
筆者はこうしたシステムの設計や開発・運用・パフォチューなどに従事しているのだが、Windowsでの開発環境でVSCodeとDockerを組合わせて使っている。
今回は、この環境の作成方法を説明することで、これまでの総括をし、似たような環境を構築したいと考えている方々の参考になるのではとの思いから本書を投稿した。

念のために、タイトルなどの略語は以下のこと。詳しい説明は省略。

  • WSL: Windows subsystem for linux
  • VSC: Visual Studio Code
  • K8S: Kubernetes

対象の読者

以下のような方々のお役にたてれば幸いです。

  • ソフトウェア開発、特に製造や評価などに関わる人
  • WSLのLinux/DockerDesktopが素直でなく、使う気になれなかった人
  • WSLでDockerを動かしてVSC開発しようとしたが、うまくいかなかった人。
  • WSLとWindowsでのファイル共有などで、文字コードの違いに困っていた人

時は満ちた

念願のWSL2

VSCとDockerの開発にはWSLを使わず、やや古い環境である、DockerMachineを改造してHyper-Vで使っていた。(SambaClientが動作するようにLibraryを追加・更新し、WindowsのドライブをマウントできるようにN/WやDNSを設定などを追加1) 仮想環境の仮想Switchを固定IPで作成し、C:ドライブを/cにマウントしておくことで、Docker定義のBindMountがうまく働いでDockerファイルやDockerComposeなどを動かすことができていた。
 本当はWSLを使いたかっただが、以下のような理由から断念していた。(今となってはうろ覚えだが、、、)

  • 素直でない:docker コマンドを素直に使えない
  • 文字コード:BindMountなどで共有した場合のファイル名の文字コードなどに日本語が使えない

だったと思う。

アップデートができない、、、

WSL2への更新が2020年9月から開始された。「Windows 10 May 2020 Update (Version 2004)」で使えるようになるとアナウンスされ2、Windows Updateでも以下のような表示がされるようになった。しかし、筆者のマシンは会社のポリシーからか一向に更新可能にならず、、、 残念な思いをしていた。

image.png

でも大丈夫

よくよく調べてみると、Version 2004に上げなくともWSL2を使えるようになるというのが分かった。(MSの記事3では、x64 システムの場合:バージョン 1903 以降、ビルド 18362 以上) そこで、何度かWindows Updateを繰り返すことで、Version 1903(OS ビルド 18362)にすることができた。

image.png

インストールのやり方などは省略

 インストールの仕方自体は他の記事に譲り、ここでは、以下のような流れでVSCode開発をDockerコンテナ内で行う環境を構築する方法を説明する。

  1. パッケージ管理(scoop)
  2. PowerShellCore
  3. ターミナル(WindowsTerminal)
  4. WSL2
  5. DockerDesktop
  6. VSCode
  7. 開発環境用MySQL+Admin
  8. Docker内PHP開発環境
  9. Docker内Pytho開発環境
  10. Docker内NodeJS開発環境
  11. Docker内Java開発環境
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

1.Docker

なぜdockerを使うのか

「環境構築を楽にするため」
パッケージ、ライブラリ、開発環境構築、実行環境構築などdocekrがあると楽に環境構築ができる

dockerなし

1.インストーラのダウンロード
2.インストーラ起動
3.エラーが出る
4.トラブルシュート
2.インストーラ起動 ・ ・ ・

1回のトラブルシュートではうまくいくことはほとんどない

dockerあり

1.コンテナを起動する

だけで終わり。

コンテナとは

「開発環境、実行環境などの集合」

パソコンやサーバーにコンテナをたくさん置ける。
コンテナの中に、開発環境や実行環境、必要なパッケージやライブラリをインストールしておく。
すると、コンテナの中で作業したり、コンテナを使って、スクリプトを動かしたり、コードを動かしたりできる。

一つコンテナを作れば、そのコンテナを他のメンバーや、開発環境、テスト環境、本番環境における。

コンテナは「Docker image」から作られる。
コンテナから「Docker image」も作れる。
「Docker image」は「Docker file」というテキストファイルから作られる。

最後に

この記事は、かめさん( https://twitter.com/usdatascientist?s=21 )のudemyのdocker講座の( https://www.udemy.com/share/103aTRAEMfeVhaTXoB/ )書き起こしです。

※あくまで、自分のための書き残しとして投稿しているので、講座と異なる部分を含んでいる可能性があります。

かめさんのブログ( https://datawokagaku.com/docker_lecture/ )

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerを利用したCloudStack構築方法

はじめに

CloudStackを理解するために、CloudStackを構築したのですが、そのときに多少つまづいたため、この記事を書くことにしました。
CloudStackを構築する方法は色々ありますが、今回はDockerを利用します。

開発環境

MacBook Pro (Mojave 10.14.6)
Docker (19.03.13)
docker-compose (1.27.4)

CloudStackシミュレータとは

CloudStackシミュレータとは、CloudStackが公式として提供しているDockerイメージです。
シミュレータは管理DB以外が1つのコンテナ内で動作しています。(CloudStackについて理解が浅いため、間違っている場合はご指摘していただけますと幸いです。)

シミュレータのイメージはDocker Hubに登録されているため、今回はそれを利用します。
https://hub.docker.com/r/cloudstack/simulator

実際に動かしてみた

docker pull cloudstack/simulator
docker run --name cloudstack -d -p 8080:8080 cloudstack/simulator

公式通りに動かしてみて http://localhost:8080/client にアクセスしてみましたが、下の画像のようにエラーが発生してしまいました。
スクリーンショット 2020-10-22 2.55.40.png
これだけ見ても何が起きているか分からなかったため、どのようなエラーが発生しているかを確認してみることにしました。

docker run --name cloudstack -p 8080:8080 cloudstack/simulator

ERROR [c.c.u.d.Merovingian2] (main:null) (logid:) Unable to get a new db connection
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.

パッと見だとMySQLに接続できないらしい?ので、色々と調べてみると上記のエラーに関するissueが挙げられていました。

ただ、issueはcloseされていたため、Docker Hubのイメージが古いと思い、Latest releaseから構築することとしました。

ここから本題

ということで、公式リポジトリのLatest releaseを利用していきます。
Dockerに関するファイルはtools/docker配下にあります。

ビルド時にDockerに関するファイル以外も必要となるため、そのままcloneしてください。

Docker-composeを動かします。
おそらく、このコマンドを実行することでCloudStackの管理DBを起動させていると思います。

docker-compose -f tools/docker/docker-compose.yml up -d

次に、Dockerfileからイメージをビルドしますが、cloneしてきたDcokerfileだとpipのエラーが発生するため、そこを修正します。

Dockerfile
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
# CloudStack-simulator build

FROM ubuntu:16.04

MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.13.1.0"

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get -y update && apt-get install -y \
    genisoimage \
    libffi-dev \
    libssl-dev \
    git \
    sudo \
    ipmitool \
    maven \
    openjdk-8-jdk \
    python-dev \
    python-setuptools \
    python-pip \
    python-mysql.connector \
    supervisor

RUN apt-get install -qqy mysql-server && \
    apt-get clean all && \
    mkdir /var/run/mysqld; \
    chown mysql /var/run/mysqld

RUN echo '''sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"''' >> /etc/mysql/mysql.conf.d/mysqld.cnf

COPY tools/docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY . ./root
WORKDIR /root
RUN ls

RUN mvn -Pdeveloper -Dsimulator -DskipTests clean install

# この行を追加してください
RUN pip install --upgrade pip

RUN find /var/lib/mysql -type f -exec touch {} \; && \
    (/usr/bin/mysqld_safe &) && \
    sleep 5; \
    mvn -Pdeveloper -pl developer -Ddeploydb; \
    mvn -Pdeveloper -pl developer -Ddeploydb-simulator; \
    MARVIN_FILE=`find /root/tools/marvin/dist/ -name "Marvin*.tar.gz"`; \
    pip install $MARVIN_FILE

VOLUME /var/lib/mysql

EXPOSE 8080 8096

CMD ["/usr/bin/supervisord"]

イメージを分かりやすくするために、タグ名をCloudStackのバージョンと同じものを指定してビルドします。
ビルドしたイメージを利用してコンテナを立ち上げて、 http://localhost:8080/client にアクセスできれば成功です。
立ち上がるまでに時間がかかるため、正しく動作しているか確認したい場合は-dオプションを外しても良いかもしれません。

docker build -t cloudstack/simulator:4.13.1.0 . -f tools/docker/Dockerfile 
docker run --name cloudstack -d -p 8080:8080 cloudstack/simulator:4.13.1.0

アクセスできたときの画面です。
スクリーンショット 2020-10-22 9.42.00.png

最後に

記事では簡単に紹介していますが、リファレンスが少なかったため色々と試行錯誤していました。
この記事が私と同じようにつまづいている方の助けになれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laradockでもfish shellを使いたい!!

やること

  • laradockで特にファイルをいじらずにlaravelの環境構築をするとデフォルトでzshが選択されているのでfishに変更します。
  • ついでに、config.fishと.vimrcもローカルのものを持ってきます。

対象読者

  • laravelの環境構築をサクッと終わらせてコーディングの学習に集中したい駆け出しエンジニア
  • laradockでfishを使いたいけどdockerに疎い人(fishに行き着く人はだいたいdockerfileイジれる気もしますが...)
  • 他の記事の通りにやるとworkspaceコンテナ内で/var/www/sample-projectのように余計に階層が増えて困っている人

作業

laradockを展開するディレクトリへ移動

cd laradockをインストールしたいディレクトリ

laradockをインストール

git clone https://github.com/Laradock/laradock.git
  • laradockというディレクトリができるはずです。

laradockディレクトリに移動

cd laradock

workspaceディレクトリにconfig.fishと.vimrcをコピー

cp ~/config/fish/config.fish ./workspace
cp ~/.vimrc ./workspace

./workspace/Dockerfileを編集

vim ./workspace/Dockerfile
  • 以下を追記してくだい。
  • 特に追記の場所は決まっていませんが、1388行目の後ろくらいにいれるといい感じになると思います。
  • Dockerfileの他の部分ではif文を書いていますが、この辺が少しわからなかったのでif文は端折っています。詳しい方教えていただけると助かります。
###########################################################################
# Fish:
###########################################################################

RUN apt-get install -y fish
RUN git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
RUN ~/.fzf/install
RUN curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
RUN ["/usr/bin/fish", "-c", "fisher add jethrokuan/fzf"]
RUN cp /root/.fzf/bin/fzf /usr/bin/
COPY config.fish /root/.config/fish/

###########################################################################
# .vimrc:
###########################################################################
COPY ./.vimrc /root/

.envファイルを作成・編集

cp env-example .env
vim .env
  • APP_CODE_PATH_HOST の箇所を APP_CODE_PATH_HOST=../プロジェクト名と編集してください。
  • phpのバージョンを指定したい場合はPHP_VERSION の箇所を編集してください。
    • 直前の行に# Accepted values: 7.4 - 7.3 - 7.2 - 7.1 - 7.0 - 5.6とバージョンが列挙されているのでこの中から指定するようにしましょう。
  • mysqlを使う場合
    • PMA_PORT の箇所を PMA_PORT=8081と編集してください
      • 他のポートと衝突しなければでなければ何でもいいです。
      • ポートとかよくわかんねって方はとりあえず8081にしておけばOKです
    • MYSQL_VERSION の箇所を MYSQL_VERSION=5.7と編集してください。
      • mysqlは8系だとやたらエラーに遭遇したのでこだわりがなければ5.7が無難です。
    • MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORDlaravelに変更してください。
      • ここは自由に指定していただいて大丈夫です。
  • postgresqlを使う場合
    • POSTGRERS_DATABASE, POSTGRES_USER, POSTGRES_PASSWORDlaravelに変更してください。
      • ここも自由に指定していただいて大丈夫です。

コンテナの起動

  • ここまでお疲れさまでした。やっとコンテナを起動です。
  • ここではnginx, mysqlを起動します。必ず現在のディレクトリがlaradock内であることを確認してください。
docker-compose up -d nginx mysql

laravelのインストール

  • 今回は8系を入れます。
  • 他バージョンがいい人はバージョン指定方法を調べてください。
docker-compose exec workspace composer create-project laravel/laravel ./

プロジェクトディレクトリの確認

  • APP_CODE_PATH_HOSTAPP_CODE_PATH_HOST=../プロジェクト名と指定したので、プロジェクトディレクトリが作成されたか確認しましょう。
ls ..
  • また、作成されたディレクトリの中も確認しましょう。
ls ../プロジェクト名

○以下のように表示されればOK

README.md       bootstrap/      config/         phpunit.xml     routes/         tests/
app/            composer.json   database/       public/         server.php      vendor/
artisan*        composer.lock   package.json    resources/      storage/        webpack.mix.js

DBの設定

プロジェクトディレクトリに移動しましょう。

cd ../プロジェクト名

.envを編集

vim .env
  • mysqlを使う場合
    DB_CONNECTION=mysql

  • pgsqlを使う場合
    DB_CONNECTION=pgsql

  • DB_HOST127.0.0.1からlaradock_mysql_1に変更してください。

    • ホスト名はコンテナ名にしないといけません。
    • DBクライアント(mysql workbench, table plus, dbeaverなど)から接続するときは127.0.0.1と指定してください。
  • DB_DATABASE, DB_USER, DB_PASSWORDを先程指定した値に変更してください。

    • 記事の通りにしているならすべてlaravelです。
    • うまく行かない場合はユーザー、パスワードをrootに変えて試してください。

DBの接続確認

laradockディレクトリに戻ります。

cd ../laradock

それではマイグレーションをしてみましょう。

docker-compose exec workspace php artisan migrate

○以下のように表示されればOK
Nothing to migrate.

phpstormからコンテナへの接続

  • こちらの記事からdockerの設定を済ませてください。

  • 以下の画像の左側のContainersからworkspaceを右クリックし、execを選択してください。

  • 新しいコマンドを作成されるように促されるのでfishと入力します。

  • これでfishシェルでワークスペースコンテナで作業できます。
    この画像

最後に

  • わからないことや改善点など気軽にコメントください。
  • 気が向けばお返事します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails6 既存アプリにDockerを導入してみた

この記事の目的

転職を成功させなければ家での居場所がなくなる不安に日々怯え、精神をすり減らしながらなんとか導入できたDocker。苦労は一度きりにするための備忘録w

手順



  1. DBをSplite3からPostgresqlに変更

  2. ファイルを追加

  3. Dockerfile、docker-compose.yml、database.yml、webpacker.ymlを編集

  4. Docker for macをダウンロード

  5. コマンド打つ

DBをSplite3からPostgresqlに変更

Rails6からコマンドで変更できるようになったらしいです。

$ rails db:system:change --to=postgresql

ファイルの追加、編集

アプリのルートデクレクトリに、
Dockerfile
docker-compose.yml
上記2つ追加、編集。

#Dockerfile

FROM ruby:2.7.1 #バージョン合わせる。Gemfileで確認
RUN curl https://deb.nodesource.com/setup_12.x | bash
RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update && apt-get install -y nodejs yarn postgresql-client
RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y postgresql-client --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

WORKDIR /myapp

ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock

RUN gem install bundler
RUN bundle install

ADD . /myapp

↑いろいろエラーが出て、これでいきましたが、まだ警告が出ます。ぴえん

#docker-compose.yml

version: '3'
services:
  db:
    image: postgres
    ports:
      - '5432:5432'
    volumes:
      - postgresql-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=password #任意のパスワードを設定しないとエラーが出ます。
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    tty: true
    stdin_open: true
    depends_on:
      - db
    ports:
      - "3000:3000"
    volumes:
      - .:/myapp # ソースコードの変更がDockerへ即時反映
volumes:
  postgresql-data:
    driver: local
database.yml
#コメントアウト省略
#passwordはdocker-compose.ymlで設定したもの

default: &default
  adapter: postgresql
  encoding: utf8
  host: db
  username: postgres
  password: password 
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: mayby_docker_development

#コメントアウト省略

test:
  <<: *default
  database: mayby_docker_test

#コメントアウト省略

production:
  <<: *default
  database: mayby_docker_production
  username: mayby_docker
  password: <%= ENV['MAYBY_DOCKER_DATABASE_PASSWORD'] %>
webpacker.yml
check_yarn_integrity: false
#default,development共にfalseにしないとダメみたいでした。

Docker for macをダウンロード

公式サイトからダウンロードしてきます。
https://docs.docker.jp/docker-for-mac/install.html

コマンド打つ


長いのでエラーが起きると萎えます。
$ docker-compose build

DBを作成し、マイグレーションです。

$ docker-compose run web rake db:create db:migrate

local:3000で表示されたらとりあえずできたっぽいです。

$ docker-compose up

やっとここまで来たのに表示されない!

単純にローカルホストに拒否されたとブラウザが言っているので、こちらを参考に、

【Rails】rails sのログに「Cannot render console from !」と出たときの対処法

config/environment/development.rb
 config.web_console.whitelisted_ips = '拒否されたIPアドレス'

をしましたが、まだ他にも

SaaS関連で何やらセグメンテーションエラーというものが起きていました。
最後の力でググってみると、

Rails6でセグメンテーションエラーが発生する問題を解決した

という神のようなブログがありました。

assets.rb
# asettsの並列コンパイルの停止(セグメンテーションエラー対策)
Rails.application.config.assets.configure do |env|
  env.export_concurrent = false
end

対策されたgemが出るとのことですが、私にはまだよくわからないのでしばらく様子を見ます。

最後

流行りのDockerですが、
実態のあるものではないので実際に体感しないとよく分かりません。
次はAWSへのデプロイをしてみようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Honkit で PlantUml を使う[Docker]

やること

Honkit の導入記事はいくつかあったが、PlantUml を使えるようにするという記事はあまり見当たらなかったのでおいておく

サンプル

動作するコード
https://github.com/tktcorporation/honkit-uml-sample

Docker 周りの準備

package.json

{
  "name": "honkit_docker",
  "version": "1.0.0",
  "scripts": {
    "serve": "npx honkit serve",
    "build": "npx honkit build",
    "pdf": "npx honkit pdf"
  },
  "dependencies": {
    "gitbook-plugin-uml": "^1.0.3",
    "honkit": "^3.6.6"
  }
}

Dockerfile

FROM honkit/honkit

RUN apt-get update
# PlantUml のために追加インストール
RUN apt-get install -y build-essential openjdk-8-jre graphviz

WORKDIR /doc

COPY ./package.json ./package.json
RUN yarn

COPY . .

CMD [ "npx honkit build" ]

docker-compose.yml

version: "3.7"
services:
  doc:

    build: .
    restart: always
    working_dir: /doc
    volumes:
      - .:/doc:cached
      - /doc/node_modules
    ports:
      - "4000:4000"

コンテナに入る

$ docker-compose build
$ docker-compose run --service-ports doc /bin/bash

以降は特に断りのない限りコンテナ内での作業とする。

Honkit 導入

book.json

{
  "plugins": [
    "uml"
  ]
}

init

$ honkit init

uml を書く

# UML Sample
```uml
@startuml

actor Promoter
actor Entrant

Promoter --> (Create Event)
Promoter -> (Attend Event)

Entrant --> (Find Event)
(Attend Event) <- Entrant

(Attend Event) <.. (Create Member)  : <<include>>

@enduml

serve

$ npx honkit serve

localhost:4000 で plantuml .

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Djangoチュートリアル(ブログアプリ作成)⑦ - フロントエンド完成編

前回、Djangoチュートリアル(ブログアプリ作成)⑥ - 記事詳細・編集・削除機能編では記事個別の詳細、編集、削除画面を作成しました。

今回は template を大幅に調整していきますが、大きく分けると以下のことをやっていきます。

  1. 全ページ共通画面の作成

  2. ナビゲーションバーの作成

  3. 各templateの修正

  4. 不要なtemplateや処理の削除

全ページ共通画面の作成

Django に限らず、ホームページには画面遷移しても共通的に表示される箇所ってありますよね。
Qiita でいえば上部に表示されている、緑色のナビゲーションバーなんかが良い例ですね。

↓これ
image.png
ただ、これをすべての template に毎回書くなんてのは大変ですよね。
一回コードを書いて終わりならまだしも、修正が入ったときのことを考えるともう…。

そこで、Django の便利な機能として共通テンプレートを使います。
簡単にいうと、共通的な部分は一つのファイルにまとめて、
画面ごとに異なる部分は別の template を呼び出して使うということです。

そのために、まずは template フォルダ直下にはじめてファイルを作成します。
今回は /template/base.html というファイルを作成しましょう。

└── templates
    ├── base.html # 追加
    └── blog
        ├── index.html
        ├── post_confirm_delete.html
        ├── post_detail.html
        ├── post_form.html
        └── post_list.html

このファイルに共通の処理を書き、画面ごとに異なる部分は
post_detail.html などのファイルを呼び出していくことにします。

base.html の修正

中身はこのようにしていきます。

base.html
<!doctype html>
<html lang="ja">
<head>
    <title>tmasuyama のブログ</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
</head>
<body>

<div class="container">

    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="{% url 'blog:post_list' %}">トップ</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'blog:post_create' %}">投稿</a>
                </li>
            </ul>
        </div>
    </nav>

    <!-- このblockの中で各templateの記載内容が呼び出される -->
    {% block content %} # 注目!
    {% endblock %}      # 注目!
</div>

<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>

</body>
</html>

このチュートリアルはフロントエンドについて詳細な解説はしませんが、
Bootstrap を使って見た目を整えるために CDN から Bootstrap を呼び出して使えるようにしたり、
ナビゲーションバーを 内で表させるようにしています。
このようにどの画面でも使いたいものは base.html で書くようにします。

注目してほしいのは 「# 注目!」 とメモをした部分です。

    <!-- このblockの中で各templateの記載内容が呼び出される -->
    {% block content %} # 注目!
    {% endblock %}      # 注目!

View に従って template を呼び出す際、各 template はここに格納されていくことになります。
逆にいうと、各 template は各ページに特徴的な部分だけを書いておけばよいのです。

また、呼び出される側の template では親となる template (base.html) を明示してあげる必要があります。
基本的な書き方は次の通りです。

各template
{% extends 'base.html' %} # 親 template の指定

{% block content %} # 中身の記述開始
...各 template 固有の記述...
{% endblock %}    # 中身の記述終了

これで親templateと子templateの役割を明確に分けることが出来るようになりました。
次は親templateで用意するナビゲーションバーについて解説します。

ナビゲーションバーの説明

上述の base.html を使うと以下のようなナビゲーションバーが表示されるようになります。
なお、今回は Bootstrap4 の Cheat Sheat を参考にしています。
https://hackerthemes.com/bootstrap-cheatsheet/#navbar

image.png
トップ を選択すると post_list.html の画面へ遷移し、
投稿 を選択すると post_form.html の画面(新規投稿画面)へ遷移するようにしています。

base.html のうち、ナビゲーションバーを表示させるための部分はここでした。

base.html
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="{% url 'blog:post_list' %}">トップ</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'blog:post_create' %}">投稿</a>
                </li>
            </ul>
        </div>
    </nav>

ここで大事なのは「href="{% url 'blog:post_list' %}"」という部分です。

これまで template ではリンクを記述してきませんでしたが、
上記のようなフォーマットで逆引き用の URL を記述すると
に相当する URL へリダイレクトされるようになります。

※urls.py でいうとこの部分です。
python:urls.py
...
path('post_list', views.PostListView.as_view(), name='post_list'),
...

ここで name='post_list' というように、各URLに名前をつけていたおかげで
template側ではその名前を指定することで、自動でルーティングしてくれるようになります。

各templateの修正

さて、各 template で親 template の指定をしつつ、Bootstrapで見た目の調整をしていきましょう。
完成形を載せていきます。

post_detail.html
{% extends 'base.html' %}

{% block content %}
<table class="table">
    <tr>
      <th>タイトル</th>
      <td>{{ post.title }}</td>
    </tr>
    <tr>
      <th>本文</th>
      <!-- linebreaksbk を入れると改行タグでちゃんと改行して表示されるようになる -->
      <td>{{ post.text | linebreaksbr}}</td>
    </tr>
    <tr>
      <th>日付</th>
      <td>{{ post.date }}</td>
    </tr>
</table>
{% endblock %}
post_form.html
{% extends 'base.html' %}

{% block content %}
<p>{{ post.title }}</p>
<!-- actionにはサーバのどのURLに対して情報を送信する -->
<!-- actionを空欄にすると現在開いている URL = /blog/post_create に値を返すので、views.py の PostCreateView が再度呼び出されることになる -->
<form action="" method="POST">
    <table class="table">
        <tr>
        <th>タイトル</th>
        <td>{{ form.title }}</td>
        </tr>
        <tr>
        <th>本文</th>
        <td>{{ form.text }}</td>
        </tr>
    </table>
    <button type="submit" class="btn btn-primary">送信</button>
    {% csrf_token %}
</form>
{% endblock %}
post_confirm_delete.html
{% extends 'base.html' %}

{% block content %}
<form action="" method="POST">
  <table class="table">
      <tr>
        <th>タイトル</th>
        <td>{{ post.title }}</td>
      </tr>
      <tr>
        <th>本文</th>
        <td>{{ post.text }}</td>
      </tr>
      <tr>
        <th>日付</th>
        <td>{{ post.date }}</td>
      </tr>
  </table>
  <p>こちらのデータを削除します。</p>
  <button type="submit">送信</button>
  {% csrf_token %}
</form>
{% endblock %}
post_list.html
{% extends 'base.html' %}

{% block content %}
<table class="table">
  <thead>
    <tr>
      <th>タイトル</th>
      <th>日付</th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    {% for post in post_list %}
    <tr>
      <!-- 「url 'アプリ名:逆引きURL' 渡されるモデル.pk」 という描き方 -->
      <td><a href="{% url 'blog:post_detail' post.pk %}">{{ post.title }}</a></td>
      <td>{{ post.date }}</td>
      <td>
        <!-- superuserでログインしている時にのみ表示 -->
        {% if user.is_superuser %}
        <!-- HTMLを アプリ名_モデル名_change にすると admin でそのまま編集できる -->
          <a href="{% url 'blog:post_update' post.pk %}">編集</a>
        {% endif %}
      </td>
      <td>
        {% if user.is_superuser %}
          <a href="{% url 'blog:post_delete' post.pk %}">削除</a>
        {% endif %}
      </td>
    </tr>
  {% endfor %}
  </tbody>
</table>

{% endblock %}

なお、最後の post_list.html はいくつか変更を追加で加えました。

ひとつは、一覧に表示させる各記事ごとに詳細、編集、削除のリンクをつけるようにしました。
プライマリキーに基づきリンク先が決まるような場合は 変数名.pk の形でプライマリキーを指定できます。
※templateがviewから変数を受け取る時の名前は post_list となっていますが、
 for文で回しているので post という変数で展開しています。
 そのため post.pk と指定しています。

逆引きする用URLの名前で指定する形は、決まった書き方なので覚えてしまいいましょう。

<a href="{% url 'blog:post_detail' post.pk %}">...

また、今回のチュートリアルではユーザ登録機能を実装していませんが、
誰でも記事の編集や削除をできてしまわないようにぐらいの制限はかけておきましょう。

今回はユーザは superuser しか存在していませんので、
superuser で管理画面 (127.0.0.1:8000/admin) からログインしている場合にのみ
記事の編集および削除のリンクを表示させるようにします。
※厳密にいえば、この状態でもアドレスから直接アクセスすると編集・削除画面には飛べてしまいます。
 この制限も Django で実装することはできます。念の為。

{% if user.is_superuser %} # superuser でログインしているときのみ、if文の中身を表示
  <a href="{% url 'blog:post_update' post.pk %}">編集</a>
{% endif %}

上記では superuser の時でしたが、他にも何かしらのユーザでログインしている時の表示や、
特定のユーザでログインしている時にのみ表示させるということも出来たりします。

不要なtemplateや処理の削除

さて、これまで Hello を表示させるためだけの index.html ページを練習用に残しておきましたが、
これ以上残しておくと管理の手間が増えるため、このタイミングで削除しておきましょう。

└── templates
    ├── base.html
    └── blog
        ├── index.html # これを削除する
        ├── post_confirm_delete.html
        ├── post_detail.html
        ├── post_form.html
        └── post_list.html

urls.py test_urls.py、、views.py、test_views.py も忘れずに編集しておきます。

urls.py
...
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'), # ここを削除
...
test_urls.py
...
class TestUrls(TestCase):

  """index ページへのURLでアクセスする時のリダイレクトをテスト"""
  def test_post_index_url(self): # このメソッドを丸々削除
    view = resolve('/blog/')
    self.assertEqual(view.func.view_class, IndexView)

class TestUrls(TestCase):

  """index ページへのURLでアクセスする時のリダイレクトをテスト"""
  def test_post_index_url(self): # このメソッドを削除
    view = resolve('/blog/')
    self.assertEqual(view.func.view_class, IndexView)
...
views.py
...
class IndexView(generic.TemplateView): # この汎用ビューを削除
    template_name = 'blog/index.html'
...
test_views.py
...
class IndexTests(TestCase): # このテストクラスごと削除
    """IndexViewのテストクラス"""

    def test_get(self):
        """GET メソッドでアクセスしてステータスコード200を返されることを確認"""
        response = self.client.get(reverse('blog:index'))
        self.assertEqual(response.status_code, 200)
...

一気に変更を行ったので、最後にユニットテストを実行してエラーが出ないかを確認しておきましょう。

(blog) bash-3.2$ python3 manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..............E
======================================================================
ERROR: blog.tests.test_urls (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: blog.tests.test_urls
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
    module = self._get_module_from_name(name)
  File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
    __import__(name)
  File "/Users/masuyama/workspace/MyPython/MyDjango/blog/mysite/blog/tests/test_urls.py", line 3, in <module>
    from ..views import IndexView, PostListView
ImportError: cannot import name 'IndexView' from 'blog.views' (/Users/masuyama/workspace/MyPython/MyDjango/blog/mysite/blog/views.py)


----------------------------------------------------------------------
Ran 15 tests in 0.283s

FAILED (errors=1)
Destroying test database for alias 'default'...

エラーが確認されました。
エラーメッセージは区切り文字などを使って表示されているので、どこでエラーが起きているかも置いやすいようになっています。

エラーメッセージを追っていくと、test_urls.pyで import できないものがあり、エラーが起きていることが分かります。

ImportError: cannot import name 'IndexView' from 'blog.views' 

もう一度 test_urls.py を読んでみると、たしかに冒頭で IndexView の読み込みを残してしまっていることが分かりました。

test_urls.py
from django.test import TestCase
from django.urls import reverse, resolve
from ..views import IndexView, PostListView # この行

これを消して、次のようにしてあげます。

test_urls.py
from django.test import TestCase
from django.urls import reverse, resolve
from ..views import PostListView

これでユニットテストをもう一度実行しましょう。

(blog) bash-3.2$ python3 manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
...............
----------------------------------------------------------------------
Ran 15 tests in 0.223s

OK
Destroying test database for alias 'default'...

今度はエラーなくテストが完了しました。
また、テストの数は 15 となっており、前回は 17 だったテストから2つのテストメソッドを減らしたこととも一致していますね。

これまではユニットテストが通るようにした結果しかお見せしませんでしたが、
今回のように一気に複数のファイルで変更を起きたときでも
予めユニットテストを用意しておくと、コマンド一つで問題箇所を特定することができると分かっていただけたかと思います。

これで無事にローカルの Django アプリとしては完成しました!

次回はいよいよ環境の整備というところで、今回作ったアプリを Docker 化していきましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OSやPythonのバージョンに関わらずOpenSeesPyを使う

(モチベーション)

OpenSeesPyを利用しようと思ったところ、環境構築方法がOSによって違っていたり、Pythonバージョンによっては使えなかったり、使えるようになったとしても、VSCodeのインタープリターがOpenSeesPyのメソッドを解釈してくれなかったりと始めるまでに苦労しました。そのため、何かそれらに関わらず簡単に環境構築できる方法を考えました。

この記事について

  • Dockerを使ってOSに関わらず環境構築
  • VSCodeRemote Developmentを使って、Dockerコマンドとか使わなくても簡単環境構築
  • OpenSeesPy?インストールされるようにコード書いといたから、それを使えばOK

OpenSeesPyとは

OpenSeesは、Open System for Earthquake Engineering Simulationの略で、地震時における構造物や地盤の構造解析などで利用されているオープンソースのフレームワークです。OpenSeesPyは、それをPythonで利用するためのインタープリターです。

Dockerとは

Dockerはコンテナ仮想化によって、異なる環境でも同じ環境を構築することができるツールです。構築方法をファイルに記述しておけば、OSはもちろん、指定したバージョンのPythonのインストールやその他のライブラリのインストールなども、それはもうドッカーンと作成して実行してくれます。ドッカーンと。

手順

必要なもの

Docker Desktop
https://www.docker.com/products/docker-desktop

VS Code
https://code.visualstudio.com/

Remote Development(VS Codeにインストール)
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack

Dockerfileを準備

DockerはDockerfileという名前のファイルを準備しておくとそれを元に環境を構築してくれます。今回は以下のように準備しました。主にやっていることは、

  1. Pythonインストール(バージョン3.8。linux環境も一緒に入る)
  2. pipをインストール
  3. pypiの必要パッケージをインストール
# Dockerfile
FROM python:3.8

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

RUN apt-get update
RUN apt-get install -y --no-install-recommends \
    python3-dev \
    python3-pip

ADD . /usr/src/app/
RUN pip install -r requirements.txt

CMD bash

requirements.txtを準備

Dockerfileに記載した通り、 pip install -r requiremennts.txt してパッケージをインストールするので、必要なパッケージを予め書いておきます。今回はOpenSeesPyを始めたいので、openseespyをお忘れなく。(てか、もはやOpenSeesPyに限らない方法なんだが)

# requrements.txt(例)
matplotlib==3.3.2
numpy==1.19.2
openseespy==3.2.2.5
pylint==2.6.0

Dockerfileとrequirements.txtは何かフォルダを作って、その中に入れておきます。

ドッカーン

VS Codeで開いて、VS Codeの左下の青いボタン(以下の図参照)を押します。そして、"Remote-Containers: Open Folder in Container..."を選択し、Dockerfileとrequirements.txtを用意したフォルダ選べば環境の構築完了です!

image.png

と言いたいところですが、このままだとまだOpenSeesPyのメソッドをVS Codeが理解してくれません。
開いた後に、.devcontainerというフォルダと、その中にdevcontainer.jsonというファイルが入っていると思います。それに、以下のように記述を追加しておけば今度こそ完成です!

# devcontainer.json
{
    ...
    "settings": { 
        ...
        "python.linting.pylintArgs": ["--extension-pkg-whitelist=openseespy.opensees"] <- 追加
    },
    "extensions": [
        "ms-python.python" <- 追加
    ]

}

完成したコード

できたものをすでに用意してありますので、差し替えます。(料理番組風)
https://github.com/kakemotokeita/openseespy-docker-vscode

良かったら使ってください。個人的に好みのものも入れてしまっているので、適宜不要なものは消してください。

間違っている点やうまくいかなかった点などあれば優しく教えてください。

ちなみに、OpenSeesは立体の構造解析が可能ですが、質点系の振動解析のみの場合なら、簡単な設定で使えるパッケージを作成しました。良かったら、こちらも使ってください。
https://github.com/adc21/asva

よろしくお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む