20210403のdockerに関する記事は9件です。

Swaggerについて調べてみた(Dockerバージョン)

前回Swaggerについて調べて実際に使ってみました。
前回はwebからyamlファイルを生成し作成する方法でしたが、今回はDockerを使った方法を試してみます。

前回と同じくまだDockerについて浅い知識しかないのでご指摘などありましたらご連絡いただけますと幸いです。

前回の記事は以下です。
Swaggerについて調べてみた

今回参考にさせていただいた記事は以下です。ありがとうございます!
UI開発にSwaggerで作ったmockサーバーを使う
Swaggerの概要をまとめてみた。

DockerでSwagger Editorを立ち上げる

DockerHubにあるイメージをpullします。
以下が公式のイメージです。
swaggerapi/swagger-editor

スクリーンショット 2021-04-03 22.00.06.png

上記の画像にあるようにコマンドを実行していきます。

$ docker pull swaggerapi/swagger-editor
$ docker run -d -p 80:8080 swaggerapi/swagger-editor

成功すると上記の場合localhostで下記のようにSwagger Editorが開きます。

スクリーンショット 2021-04-03 22.05.26.png

ここで編集をしていくということですね。

mockサーバーを作成する

こちらもDockerHubにあるイメージをpullします。
以下が公式のイメージです。
swaggerapi/swagger-codegen-cli

スクリーンショット 2021-04-03 22.00.59.png

上記の画像にあるようにコマンドを実行していきます。

$ docker pull swaggerapi/swagger-codegen-cli

HTMLでUIを表示する

localhostで開いているSwagger Editorで下記の画像のように操作をします。
Generate Serverから開発環境に合わせたものを選びます。
今回私はnodejs-serverを選択しました。

スクリーンショット 2021-04-03 22.44.03.png

ファイルがダウンロードされたら、ダウンロードしたディレクトリまで移動しましょう。

$ cd nodejs-server-server

そして以下のコマンドを入力します。

$ npm install
$ node index.js

そうすると私の場合は以下のような表示が出ます。

Your server is listening on port 3000 (http://localhost:3000)
Swagger-ui is available on http://localhost:3000/docs

私はyamlにhost: localhost:3000と指定した為、上記のような表示になるわけです。
そして記載されているようにUIを開くにはhttp://localhost:3000/docsを開いてあげればOKです。

スクリーンショット 2021-04-03 22.43.21.png

できました!

DockerやAPIのこと理解できていないの悔しいので勉強します...

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

デプロイしたAWS(EC2)に外部から攻撃を受けているらしく AWSからメールがきて怖すぎた話

勉強のためにWebアプリをEC2にデプロイしてAPIを叩いたりしてたら、突然EC2に入れなくなった。

とりあえずまあいっかと放置していたら・・・・・・

ある日こんなメールがAWSから届いた

Hello,
We've received a report(s) that your AWS resource(s)
has been implicated in activity which resembles scanning remote hosts on the internet for security vulnerabilities. Activity of this nature is forbidden in the AWS Acceptable Use Policy (https://aws.amazon.com/aup/). We've included the original report below for your review.
Please take action to stop the reported activity and reply directly to this email with details of the corrective actions you have taken. If you do not consider the activity described in these reports to be abusive, please reply to this email with ?details of your use case.
If you're unaware of this activity, it's possible that your environment has been compromised by an external attacker, or a vulnerability is allowing your machine to be used in a way that it was not intended.

上記訳

こんにちは、
AWSリソースに関するレポートを受け取りました
インターネット上のリモートホストのセキュリティの脆弱性のスキャンに似たアクティビティに関係しています。 この種のアクティビティは、AWSの利用規定(https://aws.amazon.com/aup/)で禁止されています。 レビュー用に、以下の元のレポートを含めました。
報告された活動を停止するための措置を講じ、講じた是正措置の詳細をこの電子メールに直接返信してください。 これらのレポートに記載されている活動が悪用されていると思わない場合は、このメールにユースケースの詳細を添えて返信してください。
このアクティビティに気付いていない場合は、外部の攻撃者によって環境が侵害されているか、脆弱性により、意図しない方法でマシンが使用されている可能性があります。

つまり
「このEC2に報告が入ったで。なんかこのEC2で悪用しているんちゃうか?攻撃されているかもしれんがな。
とりあえずなにしたか急いで返信してくれや」

とのこと。

訳もわからずとりあえずEC2を一旦停止

そして、AWSに急ぎ以下の内容を返信
(日本語と英語を書いた。しかしたら日本語で対応してくれる可能性があるため)

こちら身に覚えがないため、一度インスタンスを停止いたしました。

報告されたアクティビティ:ポートスキャン
とのことですが、具体的な情報が欲しいです。

I'm sorry. The reply was delayed.
I don't remember this, so I stopped the instance once.

Reported activity: Port scan
However, I would like specific information.

そしたら以下の返信が帰ってきた

※(英語でめちゃくちゃ長文がきたので日本語に簡易的に訳したのを載せます)

このインスタンスは起動したら暴れる(目的は知らんがポートスキャンしてるので違反している)から終了しろってこと。
暴れる原因に心当たりがないなら誰かに悪用されている事が考えられ、それはあなたの責任なのでしっかりしてください。
こういった事象を防ぐために色々用意してるからちゃんと調べて使ってね。
で、このインスタンスを復活したいなら
このインスタンスはおそらく完全にクリーンには出来ないので同じものを別に0から作ってね。
よろしく

EC2に入って中のログをしらべたところ、、

知らないIPからの接続を大量に確認!!
中国からアクセスがあった模様
kthreaddiというアプリがめちゃくそCPUを食ってて一瞬で使用率が100%に
(ビットコインをマイニングするツールらしい)

結論+対応策

勉強用のEC2だったのでまあまた立てれば良いと思い、インスタンスを終了しました。

対応策
セキュリティグループを絞る
ファイアウォールを入れて守る

ウイルスが入ってしまうともうEc2のCPUが暴れ続けるらしい

みなさんもお気をつけて!!では!!!

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

Rails6・Docker・MySQLによる環境構築

無事環境構築できたものを自分用に備忘録として残しておく(適宜修正予定)

プラスでよく使うものも込みでまとめておく。
・Bootstrap導入
・Git / Heroku へPush

ファイル用意

ディレクトリを作成し、その中に以下のファイルを用意
Dockerfile
docker-compose.yml
Gemfile
Gemfile.lock
entrypoint.sh

これより以下のファイル内のmyappは自分が作成したディレクトリ名に置き換える

Dockerfile
FROM ruby:2.7.1

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && apt-get install -y nodejs yarn
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

Rails5との変更点は、webpacker導入によるyarnnodeのインストール
credentials:editを使う予定の場合は、build時点で設定すると良さそう。
RUN apt-get install -y vim

Gemfile
source 'https://rubygems.org'
gem 'rails', '6.0.3'
Gemfile.lock
# 空のままで
entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local

アプリ作成

このコマンドで最後webpackerがインストールされて完了

$ docker-compose run web rails new . --force --no-deps --database=mysql

アプリ生成したら、buildする。最後Successfully ~~と出る

$ docker-compose build

DB作成

config/database.ymlを以下のように変更
また、ここまでの時点でmyappが適切に書き変わっているため、config/database.ymlでは修正する必要は無し。

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("MYSQL_USERNAME", "root") %>
  password: <%= ENV.fetch("MYSQL_PASSWORD", "password") %>
  host: <%= ENV.fetch("MYSQL_HOST", "db") %>

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>

DBを作成する

$ docker-compose run web rake db:migrate

Dockerを起動する

$ docker-compose up

http://localhost:3000にアクセスし、お馴染みのページが表示されれば無事成功。

Bootstrap導入

必要なものをインストール(バージョンは指定しなくても。)

$ yarn add bootstrap@4.4.1 jquery@3.5.1 popper.js@1.16.1

config/webpack/environment.jsに追記

config/webpack/environment.js
const { environment } = require('@rails/webpacker')

const webpack = require('webpack')
environment.plugins.append('Provide', new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default']
}))

module.exports = environment

app/javascript/packs/application.jsに追記

app/javascript/packs/application.js
require("bootstrap/dist/js/bootstrap")

application.cssの拡張子cssをscssに変更

最後にapp/assets/stylesheets/application.scssに追記

app/assets/stylesheets/application.scss
/*
 *= require_tree .
 *= require_self
 */

@import "bootstrap/scss/bootstrap";

bootstrap jquery popper.jsをインストールしてから以上の記述だと、Herokuにデプロイした際にも適用された。

--

しかし以下のやり方だと、Herokuで適用されなかった。一応残しておく
インストールしたファイルをwebpackerの管理下に加える

app/javascript/packs/application.js
~省略~
import "bootstrap"
import "bootstrap/scss/bootstrap.scss"

--

正常に適用されているか確認するために、トップページを用意する。

$ rails g controller welcome index

ルーティングを設定

config/routes.rb
Rails.application.routes.draw do
  root "welcome#index"
end

viewを記述

app/views/layouts/application.html.erb
~省略~
  <body>
    <header class="navbar navbar-expand-sm navbar-light bg-light">
      <div class="container">
        <%= link_to "サービス名", root_path, class: "navbar-brand" %>
      </div>
    </header>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>

適切に記述出来ていれば、bootstrapが適用される。

GitへPush

GitHubに登録している名前とメールアドレスを設定

$ git config --global user.name "自分の名前"
$ git config --global user.email "自分のメアド"

パスワード保持の時間設定(1日)

$ git config --global credential.helper "cache --timeout=86400"

Gitリポジトリ初期化

$ git init
$ git add -A
$ git commit -m "コミットメッセージ"

GitHubページで新規リポジトリ作成

そしてPushする

$ git remote add origin https://github.com/GitHubアカウント名/プロジェクト名.git
$ git push -u origin master

HerokuへPush(失敗談込み)

Herokuをインストールする。しかしここで問題発生。以前までCloud9で開発していたので、下のコマンドでインストールしていた。

$ source <(curl -sL https://cdn.learnenough.com/heroku_install)

そして上のコマンドを実行し、versionを確認すると、下のようになり上手くいかず。

$ heroku -v
/usr/local/heroku/bin/heroku: line 44: /usr/local/heroku/bin/node: cannot execute binary file

最終的には下記のように行いインストールに成功

まず、アンインストール

$ rm -rf /usr/local/heroku /usr/local/lib/heroku /usr/local/bin/heroku ~/.local/share/heroku ~/Library/Caches/heroku

次に以下のコマンドでインストール

$ brew tap heroku/brew && brew install heroku

そしてもう一度versionを確認

$ heroku -v
heroku/7.51.0 darwin-x64 node-v12.21.0

気をとりなおして、Herokuにログインする。

$ heroku login --interactive

アプリケーション作成

$ heroku create

Herokuにデプロイする

$ git push heroku master

アプリケーション名変更

$ heroku rename アプリケーション名

参考にした記事

https://qiita.com/me-654393/items/ac6f61f3eee66380ecd7
https://qiita.com/nsy_13/items/9fbc929f173984c30b5d
https://qiita.com/shingokubota/items/3562bf4996468899613c
https://qiita.com/take18k_tech/items/a36d77316e32a6696205

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

【Rails6, Docker】エラー対処法:ActiveRecord::ConnectionNotEstablished

docker上で起動した、Railsで作成したアプリケーションで、ActiveRecordを使ってDBにアクセスしようとするとエラーが発生する。

ActiveRecord::ConnectionNotEstablished (could not translate host name "db" to address: nodename nor servname provided, or not known)

原因

Docker経由のRailsコンソールではなく、ローカルのRialsコンソールで操作していた。

対処法

Dockerコンテナに入ってから、Rialsコンソールを起動する

#コンテナ名の確認
$ docker ps
CONTAINER ID   IMAGE                       COMMAND                  CREATED        STATUS        PORTS                                            NAMES
588188913f4c   rails6-docker-alpine_web    "bin/rails s -p 3000…"   3 hours ago    Up 3 hours    0.0.0.0:3000->3000/tcp                           rails6-docker-alpine_web_1
6a965250e960   postgres:11.1-alpine        "docker-entrypoint.s…"   20 hours ago   Up 3 hours    5432/tcp                                         rails6-docker-alpine_db_1

railsアプリケーションはrails6-docker-alpine_web_1

コンテナに入る: docker exec -it <コンテナ名> sh
(railsの場合はsh。 laravelなどはbash。)

#コンテナ内に入る
$ docker exec -it rails6-docker-alpine_web_1 sh

#railsコンソールの起動
/usr/src/app # rails c
Running via Spring preloader in process 130
Loading development environment (Rails 6.1.3.1)
irb(main):001:0>

#> 
irb(main):004:0> User.find(1)
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "aaabbb", created_at: "2021-04-03 07:35:30.551136000 +0000", updated_at: "2021-04-03 07:53:48.907671000 +0000">

データ取得に成功。


ActiveRecordとは?

DBの種類に関係なく、Modelを経由してDBと通信する便利機能。
MySQL, sqlite3, postgresなどどのDBとでも通信できる。

使い方は、Railsコンソールに入って、モデル名.メソッドとする。


例: ActiveRecord経由でDBにデータ追加

Userというモデルと通信する場合は以下のようになる。

#インスタンス作成し変数に格納
irb(main):019:0> user = User.new(name: 'tanaka')

#DBに保存
irb(main):021:0> user.save

#DBのデータ呼び出し
irb(main):022:0> User.all
  • モデル名.new: インスタンスの生成
  • モデル名.save: DBに保存
  • モデル名.all: すべてのデータを抽出



▼実際のターミナル

irb(main):019:0> user = User.new(name: 'tanaka')
=> #<User id: nil, name: "tanaka", created_at: nil, updated_at: ...

irb(main):021:0> user.save
  TRANSACTION (0.5ms)  BEGIN
  User Create (0.9ms)  INSERT INTO "users" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["name", "tanaka"], ["created_at", "2021-04-03 08:05:56.412011"], ["updated_at", "2021-04-03 08:05:56.412011"]]
  TRANSACTION (2.2ms)  COMMIT
=> true

irb(main):022:0> User.all
  User Load (0.6ms)  SELECT "users".* FROM "users" /* loading for inspect */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1, name: "aaabbb", created_at: "2021-04-03 07:35:30.551136000 +0000", updated_at: "2021-04-03 07:53:48.907671000 +0000">, #<User id: 4, name: "tanaka", created_at: "2021-04-03 08:05:56.4120
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【メモ】Dockerのビルドキャッシュを削除する

  • 製造業出身のデータサイエンティストがお送りする記事
  • 今回はメモとして、Dockerでビルドキャッシュを削除する方法を残しておきます。

発生した事象

Dockerfileをbuildしていて、急に今まで問題なかったのにエラーが出たため、ストレージ容量を確認したらビルドキャッシュの容量が多く、削除したら問題が解決したのでメモとして残しておきます。

ストレージ容量の確認方法

下記コマンドで確認できます。

docker system df

実際に出力された結果は下記です。
Build Cacheが異常に大きいです。

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          2         2         5.142GB   0B (0%)
Containers      2         0         1.688MB   1.688MB (100%)
Local Volumes   0         0         0B        0B
Build Cache     88        0         21.07GB   21.07GB

ビルドキャッシュを削除する

下記コマンドで実行できます。

docker builder prune

その後、ストレージ容量を確認した結果は下記です。
Build Cacheが小さくなっております。

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          2         2         5.142GB   0B (0%)
Containers      2         0         1.688MB   1.688MB (100%)
Local Volumes   0         0         0B        0B
Build Cache     20        0         0B        0B

無事に解決して良かったです。

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

Rails 6.1・React・Docker・MySQLで環境構築

前書き

2021年3月からE2Eテストの自動化を担当し、初めて仕事でコードを書いている。
テスト対象のアプリケーションのapiがRails、フロントがReactで作られているので、
興味本意でプライベートで何か作ってみることにした。
(職場でテストコードをJSで書くので、JSに慣れるという意味合いもある。)

早速、Dockerで環境構築してみたので、備忘として残す。

環境

・macOS Big Sur 11.2.3
・Ruby 3.0
・Rails 6.1.3.1
・Docker 20.10.5
・docker-compose 1.28.5
・Mysql 8.0

手順

全体をざっくりと説明すると以下の通り。

1.ファイルを全て準備する
2.docker-compose buildする
3.railsとreactの各種コマンド実行
4.docker-compose upする

1.ファイルを全て準備する

最終的に、以下のような構造になる。

spa-chat
|-- docker-compose.yml
|-- api
    |-- entrypoint.sh
    |-- Gemfile
    |-- Gemfile.lock
    |-- Dockerfile
|-- front
    |-- Dockerfile

Rails関連

Gemfile

Gemfile
source 'https://rubygems.org'
gem 'rails', '~>6'

Gemfileには、使いたいRailsのバージョンを記入。
この場合、Rails6系の最新のバージョンを採用。

Gemfile.lock

touch Gemfile.lock

空のGemfile.lockを作成。

entrypoint.sh

entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

Dockerfile

Dockerfile
FROM ruby:3.0
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  && apt-get update -qq \
  && apt-get install -y nodejs yarn \
  && mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

Dockerfileについては、Rails5系とRails6系で書き方が異なるので注意が必要。
Rails6系では、JavascriptコンパイラがWebpackerになったことに起因する。

React関連

Dockerfile

Dockerfile
FROM node:15.13.0-alpine
RUN mkdir /myapp
WORKDIR /myapp

docker-compose.yml

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  api:
    build: ./api
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ./api:/myapp
      - gem_data:/usr/local/bundle
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
  front:
    build: ./front
    command: yarn start
    ports:
      - '8000:3000'
    volumes:
      - ./front:/myapp
    depends_on:
      - api

volumes:
  mysql-data:
  gem_data:
    driver: local

2.docker-compose buildする

各種ファイルを揃えたので、イメージをbuild。

docker-compose build

3.RailsとReactの各種コマンド実行

コマンドを実行し、必要なファイルを揃えていく。

React


ローカルで立ち上げる時と同じような感じで、以下のコマンドを実行。
docker-compose run front npx create-react-app front

※原因は突き止められなかったが、フロント用のDockerfileを置いたfrontディレクトリに、
さらに別のfrontディレクトリが作成され、その配下に各種フォルダが作成された。
なので、Dockerfileと同じ階層に、先程のコマンドで作成したフォルダを移動する必要がある。
(移動させないと、ブラウザからフロントにアクセスできない。)

アドバイスいただけますと幸いです。

Rails

まず、以下のコマンドを実行。

docker-compose run api rails new . --force --no-deps --database=mysql --skip-test --webpacker --api

apiモードでrails new。
RSpecでテストコードを書くので、testディレクトリは作成しない。

次に、config/database.ymlを編集。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("MYSQL_USERNAME", "root") %>
  password: <%= ENV.fetch("MYSQL_PASSWORD", "password") %>
  host: <%= ENV.fetch("MYSQL_HOST", "db") %>

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>

そして、データベースを作成。

docker-compose run api rake db:create

4.docker-compose upする

準備が整ったので、コンテナを起動。

docker-compose up -d

localhost:8000で見慣れたReactの画面が表示。
image.png

localhost:3000で見慣れたRailsの画面が表示。
image.png

参考にしたサイト

https://qiita.com/nsy_13/items/9fbc929f173984c30b5d
Rails側の設定を書くときにとても参考になりました。

https://nakatanorihito.com/programming/docker-rails-api-react-postgresql/
React側の記述や、ディレクトリ構造を参考にしました。
docker-compose.ymlは上記2サイトをどちらも参考にしています。

https://docs.docker.com/compose/rails/
docker docsに記載がある、Railsの環境構築方法。
Rails5系を使うことを前提に書かれている。

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

WSL2/Dockerのトラブル治療室

初めに

システム治療家もやっている @CinTAKE です。

WSL2は新しいツールであるため、未知の問題が発覚したり、既知であるが対処法が固まっておらず未修正のままの問題がある。その中から重大なものを取り上げ、原因や治療法を解説する。

事例と治療法

マシンのメモリーを使い果たしてしまって、WSL2以外のアプリが動かなくなる

前提

  • 発生時期:2021年卯月
  • バージョンおよび確認方法:下記に記載
  • マシンスペック:下記に記載
[WSL]
10.0.19041.867
[Windows]
WindowsProductName WindowsVersion OsHardwareAbstractionLayer
------------------ -------------- --------------------------
Windows 10 Pro     2009           10.0.19041.844
[CPU]
CsNumberOfLogicalProcessors CsNumberOfProcessors CsProcessors
--------------------------- -------------------- ------------
                          8                    1 {Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz}
[Nemory]
CsTotalPhysicalMemory
---------------------
          21327122432
# 情報取得:PowerShellにて、以下のコマンドを実行
(Get-Command wsl).FileVersionInfo.ProductVersion
Get-ComputerInfo | select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
Get-ComputerInfo -Property "*processor*"
Get-ComputerInfo -Property CsTotalPhysicalMemory

現象

  • マシンのメモリがほぼ(98%)使い果たされてしまう。1
  • 「Vmmem」というプロセスが80%近いメモリーを使用している。2

原因

以下の記事に書いてあった。 @yoichiwo7 さん、ありがとう。
結論から言うと、WSL初期設定とLinuxのメモリー利用方針の相互作用で発生していた。

  • デフォルト設定のWSLは、メモリーを自動拡張して使用し、上限は80%
  • Linux側はメモリーの空きをファイルキャッシュなどに割当てる
  • 完全なフリーエリアが極小となり、マシンメモリを使い果たす

治療

対症療法ではあるが、治療法も記事にあり、メモリー自動拡張をやめ、さらにSWAPも無効にするとよいとのこと。以下のように、「.wslconfig」というWSL設定ファイルを作成・修正する。

sakura $ENV:Userprofile/.wslconfig

以下がファイルの内容。物理メモリー(20G)の60%程度を指定し、swapは0とした。

[wsl2]
memory=6GB
swap=0

結果と予防

メモリー使用量は劇的に減り、初期状態での「Vmmem」は約2.2Gのみとなった。VSCodeでDocker開発した場合でも、9G程度であり、食い尽くすことはなくなった。
このままだと、複数コンテナを起動するときに、メモリー不足になることも想定できる。定期的にモニターしておいて、リソースプランニングすればいいのだが、適当なツールが思いつかず、当面はタスクマネージャを手動で起動て監視し、割当量をを調整することとする。

bashでスクリプトが異常動作する

前提

  • 発生時期:2021年卯月
  • バージョンおよび確認方法:下記に記載
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
. . . . .

Linux LAPTOP-4SVL7A92 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
. . . . .
# 情報取得:bashにて、以下のコマンドを実行
bash --version
uname -a
cat /etc/os-release

現象

bashスクリプトを実行すると、以下のようなエラーとなる。

: No such file or directory

原因

「set -xe」で実行するも原因特定できず、別のスクリプトを試していると、以下のようなエラーが出た。

bash: /usr/bin/systemctl: /usr/bin/bash^M: bad interpreter: No such file or directory

改行コードが問題であった。

治療

Visual Studio Codeの設定を変更し、改行コードをLinuxと同じLFにする。34
Gitの設定も変える。(デフォルトではテキスト系の書類はpullするときに改行コードがOS標準に変換される)5

結果と予防

無事動作するようになった。改行コードや行末の余分はスペースを表示する拡張機能を入れることで可視化し、再発防止に役立てる。

終りに

困ったときほど、成長するチャンス。

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

テンプレート

## 事象のタイトル
### 前提
- 発生時期:
- バージョンおよび確認方法:
- (マシンスペック:)
### 現象
### 原因
### 治療
### 結果と予防
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker desktop (Windows10) でローカルにMastodonサーバを立ててみる

前提

この記事で紹介するやり方はあくまで仮の環境であり、実際に稼働させるには問題が多いので本番として運用したい方には役に立たない。
「Mastodonサーバを立ててみたい」という好奇心を満たすためだけに推奨される方法である。

環境

OS: Windows 10 Home 64bit バージョン 20H2
Docker:  Docker desktop for Windows バージョン v20.10.5
WSL2用ディストリビューション: Ubuntu 18.04 LTS
ngrok: バージョン 2.3.38
Mastodon: バージョン v3.2.2

docker-compose.yml の編集

  1. Mastodonのリポジトリからdocker-compose.yml.env.production.sampleをコピーしてくる。
  2. 環境変数設定ファイルである.env.production.sample.env.productionにリネームする。
  3. ローカルビルドはしないので、web、streaming、sidekiqからbuild: .の行をコメントアウトする。 また、image: tootsuite/mastodon:v3.2.2のようにバージョンを固定しておく(実運用する場合は定期的に書き換えてバージョンアップ)。
  4. DB、Redis、Mastodon各サービスのDockerイメージを取得する。

    docker-compose pull
    
  5. dbセクションのvolumes以下に次の行を追加する。既存のhealthcheck項目はコメントアウトする。YOUR_PASSWDは任意のパスワードに変更すること。また、インデントをvolumeshealthcheckをそろえるようにすること。

    docker-compose.yml
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "mastodon", "-D", "mastodon_production"]
    environment:
      POSTGRES_USER: mastodon
      POSTGRES_DB: mastodon_production
      POSTGRES_PASSWORD: YOUR_PASSWORD
    

.env.production の編集

  1. LOCAL_DOMAIN=mstdn.example.comなどの適当な値に変更する。
  2. REDIS_HOST=redisに変更する。
  3. DB_HOSTDB_PASSの値をdocker-compose.ymlに合わせる。

    .env.production
    DB_HOST=db
    DB_PASS=YOUR_PASSWORD
    
  4. 全文検索エンジンをOFFにする。ES_ENABLED=false

  5. セッション用と二要素認証用の2つのシークレット(文字列)を生成する。 標準出力にランダム文字列が吐き出されるのでコピーして各変数の値として張り付ける。
    2つのコマンドは同じもので、出力だけが毎回異なる。

    シークレットの生成
    # SECRET_KEY_BASE 用
    docker run --rm tootsuite/mastodon:v3.2.2 bundle exec rake secret
    
    # OTP_SECRET 用
    docker run --rm tootsuite/mastodon:v3.2.2 bundle exec rake secret
    
  6. Web Pushの公開鍵・秘密鍵を生成する。標準出力に.envの形式で吐き出されるのでコピーする。

    公開鍵・秘密鍵の生成
    docker run --rm --env-file ./.env.production tootsuite/mastodon:v3.2.2 bundle exec rake mastodon:webpush:generate_vapid_key
    
    # 出力例
    VAPID_PRIVATE_KEY=MxV1BSLJIAI2d4rJDGAOev-f18VpUrneQn0zCT_AEAI=
    VAPID_PUBLIC_KEY=BEbArD8WnodlZRpq0jCW_FWuz8gPXMnSmK2U5FjBEuLU4pLMcm-BBM-L8W0qGQIcvIU9ZsNrHOVSkPbAmVHqRCk=
    
  7. メールアドレス検証・通知などに使うメールサーバ(SMTPサーバ)を設定する。
    今回は自分のGoogleアカウントを使用する。 Googleアカウントの二段階認証が有効になっていることを確認し、 Googleアカウント設定からメールに使用するアプリパスワードを生成しておく。

    .env.production
    SMTP_SERVER=smtp.gmail.com
    SMTP_PORT=587
    SMTP_LOGIN=YOUR_NAME@gmail.com
    SMTP_PASSWORD=YOUR_APP_PASSWORD
    SMTP_FROM_ADDRESS=YOUR_NAME@gmail.com
    
  8. オブジェクトストレージ接続機能はひとまず無効化しておく。S3_ENABLED=false

コマンド実行

DBの初期化と静的ファイル生成

初期化
docker-compose run --rm web rails db:migrate
docker-compose run --rm web rails assets:precompile

# いったん終了
docker-compose down   

# 永続化指定して起動
docker-compose up -d  

db:migrateでエラーが出て失敗するときは、一度docker-compose pullコマンドを実行してからdb:migrateしなおすとうまくいくことがある。

アカウントの作成

以下のコマンドで管理者アカウントを登録する。
この例ではhogeユーザを管理者として作成し、ログインメールアドレスはhoge@example.com、パスワードはこのコマンドの出力結果となる。

アカウントの作成
docker-compose run --rm web bundle exec bin/tootctl accounts create hoge --email hoge@example.com --confirmed --role admin

ローカルのインスタンス(Mastodonサーバ)にアクセスできるようにする

このままではhttpsの暗号化設定ができておらず、しかもデフォルトでhttpでのアクセスはhttpsにリダイレクトされてしまい、アクセスしてもエラー画面が表示されログインできない。
そこでngrokコマンドを使う。Windows10の場合はここからダウンロードする。
以下のコマンドを実行し、起動しているローカルのMastodonへのURLを表示させる。このURLはngrokを停止するまで有効で、ngrokを起動しなおしたらURLが変わるようだ。

ngrokの実行
# 今dockerで起動しているMastodonの待ち受けポートが3000なので「http 3000」とする
ngrok http 3000   

ngrokが表示しているhttps://で始まるURLにアクセスするとローカルのDockerで立てたMastodonにログインできる。ただし、ログイン後数分はサーバとの通信が多すぎて429エラーが出てしまい、投稿に失敗する。(ngrokによる制限?)
初投稿はログイン後数分経ってからでないとできなかった。

参考

Mastodonをdocker-composeで立てる(Ubuntu 18.04) - えやみぐさ

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

VS Code Remote DevelopmentとDocker-ComposeとFastAPI

1. VS Codeの設定

1.extentions から「Remote Development」をインストールする
image.png

2. DockerとFastAPIの作成

ディレクトリ構成図

.
├── docker-compose.yml
├── Dockerfile
├── main.py
└── requirements.txt 
Dockerfile
FROM python:3.8-alpine

WORKDIR /workspace

COPY requirements.txt .

RUN apk add --no-cache build-base \
 && pip install --no-cache-dir --trusted-host pypi.python.org -r requirements.txt \
 && apk del build-base

COPY main.py .

EXPOSE 8080

docker-compose.yml
version: "3.0"

services:
  api:
    container_name: "fastapi_app"
    build: .
    image: fastapi
    restart: always
    tty: true
    ports:
      - 8080:8080
requirements.txt
fastapi
uvicorn[standard]
main.py
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    user_id: int
    name: str

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.post("/user/")
def create_user(user: User):
    return {"res": "ok", "ID": user.user_id, "名前": user.name}

3. devcontainer を作成

  1. 左下の「Open a Remote Window」をクリックして、「Remote-container: Add Development Container Configuration Files...」を選択する
    image.png

  2. docker-compose.yml からVS Codeの設定ファイルを作成する為「From 'docker-compose.yml'」を選択する
    image.png

  3. 拡張機能をコンテナにインストールする為、.devcontainer/devcontainer.json の extensions に 「ms-python.python」 の拡張機能を指定する

devcontainer.json
{
"extensions": [
        "ms-python.python"
    ]
}

コンテナを起動

  1. 左下の「Open a Remote Window」をクリックして、「Remote-Containers: Open Folder in Container」を選択する image.png

FastAPIサーバーを起動

uvicorn main:app --reload --host 0.0.0.0 --port 8000

image.png

動作確認

参照

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