20200924のdockerに関する記事は11件です。

Redmineの公式Docker Imageでメール送信エラー"dh key too small"

Redmineの公式Dockerイメージでメール送信エラー"dh key too small"

Redmine公式Dockerイメージを使っていてメール配信がなかなかうまくいかなかった

メール配信のテストを行うと以下のエラーが発生しました。

An error occurred while sending mail (SSL_connect returned=1 errno=0 state=error: dh key too small)

原因

どうやらメールサーバ側のDH鍵が短く、Redmine側のOpenSSLのセキュリティ条件を満たせていない様子。
Redmineのコンテナに入り、OpenSSLの設定(/etc/ssl/openssl.cnf)を調べたらSECLEVEL=2になっていました。
RedmineのコンテナはDebian系のようです。

CipherString = DEFAULT@SECLEVEL=2

対処

仕方がないのでSECLEVEL=1に下げたところメールが配信できるようになりました。
コンテナ内で下記のコマンドを打つことで2から1へ書き換えができます。

# sed -i -e 's/CipherString = DEFAULT@SECLEVEL=2/CipherString = DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

コンテナの外からだったら下記のコマンド

# docker exec -i -t (Redmineのコンテナ) /bin/sh -c "sed -i -e 's/CipherString = DEFAULT@SECLEVEL=2/CipherString = DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf"

おわりに

役に立ちましたらLGTMをお願いいたします。

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

【Docker】function not implemented @ io_fread ~ というエラーの解決方法【超簡単】

まずは解決策からいいます

Dockerデスクトップアプリを再起動するだけ!!

これだけでした、、今までの時間はなんだったんだろう、、
Docker for Windowなら右下のクジラのアイコンを右クリックしてRestartを押せばOKです!(画像参照↓)

スクリーンショット 2020-09-24 202325.png
スクリーンショット 2020-09-24 202344.png

エラーの経緯

githubからcloneしたRailsアプリを動かすために新たしくDocker環境を構築して色々いじっていたら、なぜか他のプロジェクトで正常に動いていたDockerコンテナがいきなり起動しなくなったという感じです。

【環境】
- windows10 Pro
- Rails: 6.0.3.2
- ruby: 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
- Docker for windows
- MySQL 5.7
- nginx:1.15.8

エラー内容

・・・(省略) Function not implemented @ io_fread (ディレクトリやファイル名)

見たことないエラーで焦りました。仮想環境であるDockerコンテナが他のコンテナに影響を与えることなんてあるわけない、、なぜだ、、と思い、Dockerfileをあれこれいじってしまったのが地獄の始まりでした。
原因の切り分けがまったくできていませんでしたね。

最後まで見ていただきありがとうございました。

エラー解決に少しでも役に立てば幸いです!!

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

Dockerで立ち上げたGitlabとGitlab Runnerを疎通させる

前提

さくらVPSで仮想サーバを借り,そのサーバ上でGitlabを運用しています.
Gitlabの立ち上げなどは,公式ドキュメントのGitLab Docker imagesを参考にdocker-composeで立ち上げました.
また,SSLの対応などは 便利なnginx-proxyのイメージがあったので.そちらを使って行おうと思って死闘したのですが,内部nginxを介さずに nginx-proxyから直接pumaサーバに飛ばそうとするのがうまくいかず,現状Gitlab単体で立ち上げという形になっています.単体で立ち上げているので,GitlabのSSLConfiguration(lets-encrypt-integration)を参考に内部でSSL証明証の取得と更新をしています.
これらはすべてdocker-composeのvolumeを指定してローカルホスト側でも保持できるように設定します.

今回はこれらの立ち上げ方法ではなく,Dockerコンテナ間の通信の疎通に関しての記事となります.

Gitlab Runnerの運用

Gitlabの運用に伴いCIを動かしたくなったため,Gitlab Runnnerの追加運用を行うことにしました.
基本的なインストールなどは公式ドキュメントのRun GitLab Runner in a containerに従い行いました.Docker初心者というのもあり,コンテナ間通信はDocker内の同じネットワークにあればいけると思い込んでいたため,いつものごとくdocker network create --driver=bridge --subnet=サブネットの指定 --gateway=ゲートウェイの指定 ネットワーク名でネットワークを作成し,GitlabとGitlab Runnerを同一ネットワークで立ち上げました.

コンテナ間通信と調べるとおそらくローカルホスト間でのpingなどのことを指すのか,“同一のDockerネットワークに入れれば通信ができる”と書かれている記事をたくさん見かけます.しかし,外部向けに公開しているGitlabへのHttp通信などは何者かに弾かれてcurl: (7) Failed to connect to gitlab.example.com port 443: No route to hostとcurlでさえ返ってきませんでした.
Docker初心者すぎてお恥ずかしいのですが,皆さん当たり前かもしれない方法でこの点に関してコンテナ間を疎通を可能できました.そちらを戒め程度に残しておきたいと思います.

補足
gitlab.example.comはホストのグローバルIPにDNSが向いていて,コンテナ間でなければCurlなどは難なく返ってくるという状態でした.

解決策

結果として,ホスト側のファイアウォールが原因で弾かれているようでした.そこで,Dockerネットワークで使用しているネットワークをファイアウォールで通過できるような設定をする必要があることがわかりました.

今回.新しく作成したDockerネットワークは172.31.0.0/16をサブネットとして指定しています.ネットワークの確認に関してはdocker network inspect ネットワーク名で調べることができます.

そのため,172.31.0.0/16のネットワークを通せばいいと思ってこのサブネットに関してファイアウォールのルールを追加しましたが,だめでした.ここで172.0.0.0/8に関してルールを追加すれば良いという記事(Docker - No route to host)を見つけたため,実直にそれを試してみたところ無事に疎通できました.これでGitlabとGitlab Runner間の通信が可能になり,Runnerの登録ができるようになりました.

叩いたコマンドを以下にまとめておきます.もしサブネットが192.168.~~の方はそちらのファイアウォールを突破できるようにしたら良いと思います.(自信ありませんが)

sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=172.0.0.0/8 accept'
sudo firewall-cmd --permanent --zone=public --add-masquerade
sudo firewall-cmd --reload
sudo less /etc/firewalld/zones/public.xml

>
<zone>
  <short>Public</short>
  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="dhcpv6-client"/>
  <masquerade/>
  <!-- ここが追加されてたらGood -->
  <rule family="ipv4">
    <source address="172.0.0.0/8"/>
    <accept/>
  </rule>
</zone>

最後に

まだまだQiita書き慣れず汚い文章で申し訳ありません.Dockerが便利すぎて簡易なテストはDockerで行うようにしています.
Gitlab Runnerを使えるようになったものの,まだまだCIについては勉強不足なので精進したいと思います.

何か間違っていたらご指摘お願いします.

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

Found multiple CRI sockets, please use --cri-socket to select one: /var/run/dockershim.sock, /var/run/crio/crio.sock

Init a kubernetes cluster with cri-socket /var/run/crio/crio.sock, when run kubeadm reset, got these error:

Found multiple CRI sockets, please use --cri-socket to select one: /var/run/dockershim.sock, /var/run/crio/crio.sock

Reason

kubeadm detect known cri sock by finding sock file in fs( https://github.com/kubernetes/kubernetes/blob/8eda21ea3f1c2a95581e8b48b6333d600e7ecda4/cmd/kubeadm/app/util/runtime/runtime.go#L196-L229 ), if you having docker running too, you will get this error.

How to resolve?

Stop docker and delete /var/run/docker.sock:

rm -rf /var/run/docker.sock 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

最小構成の CentOS 8 に SSH 接続可能な Docker コンテナを作ってみる

(2020/09/25)
トラブルシュート部分を下記の記事に分離しました。
SSH 接続可能な Docker コンテナを載せた VM に繋がらなくなった

概要

最近 Docker に少し興味を持っていたのだが、仕事で Docker に触れる機会が今のところないので、自分で勝手に勉強することにした。
Google 先生や世の先人たちは CentOS 7 あたりで構築する記事をたくさん紹介してくれるが、CentOS 8 がリリースされて少し(結構?)経つので、せっかくなら新しいものでということで、試行錯誤を承知の上で少し遊んでみる。1
今回は、SSH 接続が可能なコンテナを作り、ホストからコンテナへの SSH アクセスができることをゴールにする。

環境

  • Windows10 Home (1909) (ホスト)
  • VirtualBox 6.1.4
  • CentOS 8.1.1911 (ゲスト)
  • Docker 19.03.8
  • Docker Compose 1.25.4

手順

VM 起動

デフォルトでインストールすれば色々簡単かもしれないが、とりあえず Minimal(最小構成)でどこまで構築できるか試してみることにした。
CentOS 8 ではフルサイズのイメージを使用し、インストール中に構成を選択する箇所が出てくるのでそこで最小構成を選択。
VirtualBox での構築手順は省略。下記記事などを参考にした。

参考:Virtualbox環境にて、CentOS8を構築する
参考:初見でCentOS8

SSH 接続関連設定

OS がインストールできたら、ホスト側の TeraTerm から SSH 接続可能なところまで持っていく。

まずは VirtualBox 側でポートフォワーディングの設定。
SSH アクセスができればよいのだが、下記のようなイメージで、接続時に2222番ポートを指定すればゲスト VM へ、22222番ポートを指定すればコンテナへアクセスできるようにしたい。

ホスト ーーーー ゲスト ーーーー コンテナ
2222 ーーーー 22
22222 ーーーー 2222 ーーーー 22

そこで、VirtualBox では2222番と22番、22222番と2222番を対応付ける設定を行う。
なお、ゲスト VM の2222番とコンテナの22番の対応付けは、後の Docker 関連の設定にて実施する。
キャプチャ.PNG

ゲスト VM 側の設定に移る。
まずは SSH 接続を許可するようファイアウォールを設定。

# firewall-cmd --add-service=ssh --permanent
# firewall-cmd --reload

ネットワークインターフェースを有効化。

# nmcli connection up enp0s3
# nmcli connection modify enp0s3 connection.autoconnect yes
# nmcli connection show enp0s3

SELinux を無効化し、再起動。

# vi /etc/selinux/config
SELINUX=disabled
# reboot

これで、ホスト側の TeraTerm からゲスト VM に SSH 接続が可能になった。
接続の際はホスト名にIPアドレスを指定(当方環境では192.168.11.4)し、ポートは Virtual Box にてポートフォワーディング設定した通りに指定(今回は2222)すればOK。

Docker 導入

今回はオフライン環境に構築することを前提としてやってみる。
途中まではオフライン環境で構築することを考えていたが、後段の Docker コンテナ起動のところでどうしても外部通信が必要になるので、結局はオンライン環境での作業になってしまった。
そのため、途中まではオフライン向けの無駄な手順を踏んでいるがご容赦を。
(全てオンラインでの手順に書き直すかも)

なお、オフラインでの導入手順は下記記事が参考になった。

参考:docker環境構築 〜オフライン環境で使用するにはどうすれば良いかを考える〜

まず必要資材をホスト側にダウンロード。

Docker 19.03.8
https://download.docker.com/linux/static/stable/x86_64/docker-19.03.8.tgz
Docker Compose 1.25.4
https://github.com/docker/compose/releases/download/1.25.4/docker-compose-Linux-x86_64

WinSCP などでゲスト VM に資材を送り込み、下記のコマンドで展開。

$ tar zxvf docker-19.03.8.tgz
-bash: tar: コマンドが見つかりません

……なるほど、最小構成インストールだとtarコマンドが無いと。
tarが入っていないのはどうなのかと思いつつ、コマンドを導入し、リトライ。

参考:CentOS8 (Minimum) インストールしてとんでもなかったこと一覧

$ sudo yum install tar
$ tar zxvf docker-19.03.8.tgz

Docker Compose はダウンロード資材自体が実行ファイルなので、リネームして所定の位置に置き、実行可能にしてやればよい。

$ sudo mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

この先、いちいちsudoをつけてdockerコマンドを打つのは面倒なので、権限付与。

$ sudo usermod -aG docker $USER

コンテナ起動

コンテナでsshを動かすため、Dockerfiledocker-compose.ymlをゲスト VM のホームディレクトリに作成。
コンテナのイメージファイルには、軽量 OS の Alpine Linux を用いる。
なお、コンテナでsshを常駐させる方法は下記記事を参考にした。

参考:Dockerコンテナでsystemd無しのSSH

Dockerfile
FROM alpine

# ssh ほか導入
RUN set -x && apk update && apk upgrade \
  && apk add --no-cache openssh openrc \
  && apk add --no-cache bash \
  && apk add --update busybox-suid
RUN rc-update add sshd && rc-status
RUN mkdir -p /run/openrc/ && touch /run/openrc/softlevel

# sshd 設定
RUN sed -i 's/^AllowTcpForwarding no/AllowTcpForwarding yes/g' /etc/ssh/sshd_config
RUN sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config

# 一般ユーザ作成
RUN adduser -D test

# パスワード設定
RUN echo 'root:root' | chpasswd
RUN echo "test:test" | chpasswd

# ログイン時のバナーを非表示
RUN echo "" > /etc/motd

# sshd を起動し、そのままの状態にする
CMD /etc/init.d/sshd start && tail -f /dev/null
docker-compose.yml
version: '3.8'

services:
  test:
    build: .
    container_name: test
    hostname: test
    ports:
      - "2222:22" # ゲストVMとコンテナのポートを対応付ける設定
    tty: true

上記ファイルを作成したら、いよいよコンテナを起動。

[centos@dockertest ~]$ docker-compose build
[centos@dockertest ~]$ docker-compose up -d

コンテナが立ち上がったら、ホストから SSH でコンテナにアクセスしてみる。

test:~$

以上で、SSH アクセス可能な Docker コンテナを作ることができた……と思っていた。

問題発生編 に続く)

まとめ

手探りながら、とりあえず SSH 接続可能な Docker コンテナを動かすことができた。
それにしても、Minimal の CentOS 8 にはtarが入らないことにびっくり。どういう経緯で不要と判断されたのだろうか……。


  1. CentOS 8 では Podman という Docker 互換のシステムが標準装備されているようなので、敢えて Docker を使う必要はないのかもしれない。 

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

CentOS 8 で Docker CE(公式) を使う

2020/9/18 に、ようやく 公式に Docker CE の CentOS 8 版がリリースされたようです。
ので、インストール手順をメモ。

なお、パッケージ本体は https://download.docker.com/linux/centos/8/x86_64/stable/Packages/ にあります。

インストール手順

残念ながら Podman は Docker CE と共存できないので、削除しておく必要があります。

$ sudo rpm -e podman-docker

以下手順で Docker CE をインストールします。

$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
$ sudo dnf install docker-ce
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

爆速PythonフレームワークFastAPIをMySQLに繋いでRESTfulなAPIを作成してみた。

FastAPI とは?

68747470733a2f2f666173746170692e7469616e676f6c6f2e636f6d2f696d672f6c6f676f2d6d617267696e2f6c6f676f2d7465616c2e706e67.png

FastAPIとはpython3.6以上を対象とした、APIを作成するためのモダンで処理速度が爆速なフレームワークです。

主な特徴としては

  • 速さ: 非常にハイパフォーマンス。NodeJSやGoに匹敵する処理速度を誇る(StarletteとPydanticのおかげもあり)。Pythonの数あるフレームワークのうち最も処理速度が速いフレームワークの一つ。

  • コードの簡素化: コードの書く速度を約2~3倍から上昇させる。(*)

  • バグの少なさ: 約40%ほどの人為的コードバグを減らすことが可能。(*)

  • 直感的に書ける: エディターのサポートも充実、補完も効きます。デバッグにかかる時間を減らすことが可能。

  • 簡単: 簡単に書け、理解しやすいように設計されている。ドキュメント読むのに時間がたくさんかかる心配もない。

  • 短い: コードの重複を避けることができる。渡す引数を変えるだけで様々な機能を提供する関数を備えている。

  • 堅実: 本番環境でも開発環境と差異のないコードを使える。

  • Swaggerの提供: 作成したAPIはデフォルトで備えているSwaggerをもとに自動でドキュメント化され、各処理を実行できる。

(*)FastAPI制作チーム調べ、だそうです。

とりあえずサーバーを立ち上げてみる

「コードは言葉より物を言う」と言うことで、早速使っていきたいと思います。

まずは適当にフォルダを作り

mkdir fastapi-practice

必要なパッケージをインストールします。

pip install fastapi sqlalchemy uvicorn mysqlclient

グローバルインストールが嫌な方はpoetryなどを使ってインストールしてください(このあとでどのみちpoetry使います)。

FastAPIを動かすために必要な以下のファイルを作成します

touch main.py

そして以下の様にコードを記述していきます。

main.py
from fastapi import FastAPI
from starlette.requests import Request

app = FastAPI()


def index(request: Request):
    return {'Hello': 'World'}

app.add_api_route('/', index)

なんとこれだけでサーバーが立ち上がってしまいます。

uvicorn main:app

と打つだけでサーバーが立ち上がったはずです。
http://localhost:8000/
をブラウザで表示してみると{"Hello":"World"}と表示されているはずです。

爆速ですね、FastAPI。
しかもSwaggerによりAPIの仕様も自動で作成されています!!(驚き!)
http://localhost:8000/docs
を表示してみてください。お洒落なUIで仕様書が作られているはずです。

タブを開いてTry it outのボタンを押すと実際にリクエストを送り、レスポンスを確認することだってできてしまいます!(感動!!)

スクリーンショット 2020-09-24 14.05.22.png

ちなみに
http://localhost:8000/redoc
も自動で作られておりさらに詳細なドキュメントを簡単に作ることもできてしまいます!(凄すぎ!!!)

実際に使ってみる (docker環境構築編)

それではリアルケースを想定したFastAPI + MySQLでRESTfulなAPIを作成してみましょう。

FastAPIはdockerで簡単に環境構築できるのでmysqlとFastAPIをそれぞれ今時っぽくコンテナ内で動かし、通信させる様にしてみます。

まずはフォルダ内にdocker-compose.ymlとdocker-sync.yml, Dockerfileを作成します。

touch docker-compose.yml docker-sync.yml Dockerfile

dockerの詳しい使い方の説明はここでは省きますが、Dockerfileにコンテナを作成するための情報、docker-compose.ymlに作成されたコンテナ上で走らせるコマンド、docker-sync.ymlでローカルの開発環境とdockerコンテナ内のファイルをリアルタイムで同期するためにコードをつらつらと書いていきます。

docker-syncの使い方は他の方が書いてくださった以下の様な記事が参考になるかと思うので読んでみてください。
docker-syncは使わなくてもできますが、同期速度を爆速!にするために私は使ってます。

https://qiita.com/Satoshi_Numasawa/items/278a143aa41735e1b0da

それではDockerfileからコードを書いていきます。

Dockerfile
FROM python:3.8-alpine
RUN apk --update-cache add python3-dev mariadb-dev gcc make build-base libffi-dev libressl-dev
WORKDIR /app
RUN pip install poetry

パッケージ管理にはpoetryを使います。
パッケージ管理にはpipenvやpyflowなどもあるのでここは好みですかね...?

https://qiita.com/sk217/items/43c994640f4843a18dbe
こちらの記事に各パッケージマネージャーが分かりやすくまとめられています。
気になる方は是非一読してみてください。

続いてdocker-sync.yml

docker-sync.yml
version: "2"
options:
  verbose: true
syncs:
  fastapi-practice-sync:
    src: "."
    notify_terminal: true
    sync_strategy: "native_osx"
    sync_userid: "1000"
    sync_excludes: [".git", ".gitignore", ".venv"]

そしてdocker-compose.ymlです

docker-compose.yml
version: "3"
services:
  db:
    image: mysql:latest
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_DATABASE: fastapi_practice_development
      MYSQL_USER: root
      MYSQL_PASSWORD: "password"
      MYSQL_ROOT_PASSWORD: "password"
    ports:
      - "3306:4306"
    volumes:
      - mysql_data:/var/lib/mysql
  fastapi:
    build:
      context: .
      dockerfile: "./Dockerfile"
    command: sh -c "poetry install && poetry run uvicorn main:app --reload --host 0.0.0.0 --port 8000"
    ports:
      - "8000:8000"
    depends_on:
      - db
    volumes:
      - fastapi-sync:/app:nocopy
      - poetry_data:/root/.cache/pypoetry/

volumes:
  mysql_data:
  poetry_data:
  fastapi-sync:
    external: true

docker-compose.ymlでミソなのが永続化するデータとその場かぎりのデータをうまく使い分けることです。
永続化しないデータはdocker-compose downするたびにリセットされてしまいます。

今回のケースだとmysql内のデータ、poetryでインストールしたパッケージは永続化させ、コンテナを立ち上げる度にmysql内のデータが空になったりパッケージをダウンロードしなくていい様にします。
また書いていくコードはdocker-syncを使って同期させたいのでfastapi-practice-sync:/app:nocopyを記述して勝手に同期されるのを防ぎます。

MySQLもdockerから最新のイメージをpullして構築していきます。

ここまででdockerのセットアップは終了です。

実際に使ってみる(FastAPI設定編)

まずはFastAPIに必要なパッケージをインストールするpoetryのセットアップです。

poetry init

をターミナルで叩きます。
そうすると対話形式でセットアップが始まりますのでyesかnoを連打しましょう。(基本デフォルトの設定で問題ないのでEnter連打でも問題ない...と思います)

そうするとpyproject.tomlというファイルが作成されたかと思います。

ここにパッケージの依存情報が追記されていくのでpoetryを使ってFastAPIを立ち上げるのに必要なパッケージをインストールしていきましょう。

poetry add fastapi sqlalchemy uvicorn mysqlclient

こちらを入力しパッケージのインストールが終わるのを待ちます。
終了したら、pyproject.tomlを開いてみるとインストールされたパッケージの情報が記載されていることがわかります。

pyproject.toml
[tool.poetry]
name = "fastapi-practice"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.61.1"
sqlalchemy = "^1.3.19"
uvicorn = "^0.11.8"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

そうしたらあとはdocker-compose buildを打ち、イメージをビルドしてdocker-sync-stack startを入力するだけです!

*docker-sync-stack startdocker-sync startdocker-compose upを同時に実行するコマンドです。ログもよしなに出してくれるので便利です。

新たにパッケージをインストールする際は、まずはローカルでpoetry addでパッケージをインストールしてdockerコンテナを再起動させればコンテナ内にも同期されるはずです!

マイグレーションをする

お次はDB(MySQL)と連携させていきます。

今回はCRUDの勉強といえばTodoリストの作成!なのでTodoテーブルを定義しマイグレーションをかけていくことにします。

Todos Table

column datatype
id integer
title string
content string
done boolean

この様な構成のテーブルをマイグレーションしていきます。

まずはデータベースを定義するファイルを作り

touch db.py

以下の内容を書き込んでいきます。

db.py
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker, scoped_session

user_name = "root"
password = "password"
host = "db"
database_name = "fastapi_practice_development"

DATABASE = f'mysql://{user_name}:{password}@{host}/{database_name}'

engine = create_engine(
    DATABASE,
    encoding="utf-8",
    echo=True
)

Base = declarative_base()

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


class Todo(Base):
    __tablename__ = 'todos'
    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(30), nullable=False)
    content = Column(String(300), nullable=False)
    done = Column(Boolean, default=False)


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


def main():
    Base.metadata.drop_all(bind=engine)
    Base.metadata.create_all(bind=engine)


if __name__ == "__main__":
    main()

FastAPIはsqlalchemyというPythonの中で最もよく利用されるORM(Object-Relation Mapping)の一つを使ってデータベースとPythonのオブジェクトを関連付けるのが主流みたいです。

これを書いたらdockerのコンテナ内に入り、マイグレーションをかけていきます。

docker-sync-stack start

でコンテナを立ち上げ同期モードにし、

docker container ls

で立ち上がっているコンテナリストをみます。
そしたら、

docker exec -it {コンテナ名} sh

を叩き、コンテナの中に入ります。
そして、以下のコマンドでマイグレーションをかけていきます。

poetry run python db.py

そうすると無事マイグレーションが走りテーブル作成に成功したのではないでしょうか!

そしたら次はCRUD処理をFastAPIで書いていきます。

FastAPIでCRUD処理を書こう

拡張性を意識してFastAPIに内蔵されているinclude_routerという機能を使い、ファイルを分割していきます。

mkdir routers

と打ち、

touch routers/todo.py

というファイルを作ります。
こちらにCRUD処理を書いていきます。

routers/todo.py
from fastapi import Depends, APIRouter
from sqlalchemy.orm import Session
from starlette.requests import Request
from pydantic import BaseModel
from db import Todo, engine, get_db

router = APIRouter()


class TodoCreate(BaseModel):
    title: str
    content: str
    done: bool


class TodoUpdate(BaseModel):
    title: str
    content: str
    done: bool


@router.get("/")
def read_todos(db: Session = Depends(get_db)):
    todos = db.query(Todo).all()
    return todos


@router.get("/{todo_id}")
def read_todo_by_todo_id(todo_id: int, db: Session = Depends(get_db)):
    todo = db.query(Todo).filter(Todo.id == todo_id).first()
    return todo


@router.post("/")
def create_todo(todo: TodoCreate,  db: Session = Depends(get_db)):
    db_todo = Todo(title=todo.title,
                   content=todo.content, done=todo.done)
    db.add(db_todo)
    db.commit()


@router.put("/{todo_id}")
def update_todo(todo_id: int, todo: TodoUpdate, db: Session = Depends(get_db)):
    db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
    db_todo.title = todo.title
    db_todo.content = todo.content
    db_todo.done = todo.done
    db.commit()


@router.delete("/{todo_id}")
def delete_todo(todo_id: int, db: Session = Depends(get_db)):
    db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
    db.delete(db_todo)
    db.commit()

この様にしてざっとCRUD操作を書いていきました。
@routerの後にリクエスト名を書き、動作対象のURLを書くだけです。

そしたらこちらを読み込める様にmain.pyも編集していきます。

main.py
from fastapi import FastAPI
from routers import todos

app = FastAPI()


app.include_router(
    todos.router,
    prefix="/todos",
    tags=["todos"],
    responses={404: {"description": "Not found"}},
)

prefixはurlのパスを作ってくれます。tagsはdocsを見やすい様グルーピング化してくれます。

そうして
http://localhost:8000/docs
に接続すると以下の様になっているはずです!

スクリーンショット 2020-09-24 14.53.20.png

タブを開いてポチポチボタンを押してCRUD処理を試してみてください!

このままだとフロントエンドから呼ぶ際CORSエラーが起きるので別アプリから呼ぶ際は以下のCORSの処理を追記してみてください。

main.py
# 追記
from starlette.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

まとめ

FastAPIいかがだったでしょうか?
こんなにも少ないコード量でAPIが作成できてしまうのがとても魅力的ですね。
Pythonでマイクロサービスを作成する際とても相性が良さそうです。

Qiita初投稿だったため何か分かりづらい点あったら質問くださいませ!
これからはなるべくQiitaにもアウトプットしていきたい...です(頑張る

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

ghcr.ioのpullで引っかかった人

ghci.ioを使用してdocker-composeイメージをPullしている記事が見当たらなく
よくわからなかったのでそのメモを記載する。

用意するしたもの

以下のようなフォルダ構成です。

repository/
 ├ project/
 │ ├ sample/
 │ │ ├ __init__.py
 │ │ └ add.py
 │ └ test/
 │   ├ __init__.py
 │   └ test_add.py
 ├ docker-compose.yml
 ├ Dockerfile
 └ requirements.txt

ghcr.ioにイメージをpushするには、
docker-compose.ymlにイメージの指定をする事。
以下のような感じで

docker-compose.yml
#...
service:
    python:
        build: .
        image: ghcr.io/<Githubユーザー名>/<レポジトリ名>/<イメージ名>:<tag>
#...

Push方法

pushはdocker-composeで行えるみたい

docker-compose up -d #イメージの作成
docker-compose push #イメージをPushする

Pull方法

ここでかなり躓いた
Pullではdockerコマンドで行うみたい

自分はずっとdocker-compose pullがうまくいかなかった。

docker pull ghcr.io/...

上記のコマンドを実行後にdocker-compose up -dをやってもビルドは行われないはず

だれもこれ引っかからないのか。。。

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

Dockerが使用しているディスク量を把握する方法

コマンド

docker system df

出力例

TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              20                  11                  7.692GB             4.48GB (58%)
Containers          19                  19                  3.805GB             0B (0%)
Local Volumes       5                   3                   147.3MB             48.74MB (33%)
Build Cache         0                   0                   0B                  0B
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナが使用しているディスク量をコンテナ毎に表示する方法

コマンド

docker ps --size

出力例

CONTAINER ID        IMAGE                               COMMAND                  CREATED             STATUS              PORTS                                                            NAMES                            SIZE
a6c67c928bb1        docker-compose_inflionserver        "air -c .air.d/.infl…"   2 weeks ago         Up 25 hours         0.0.0.0:50051->50051/tcp                                         docker-compose_inflionserver_1   692MB (virtual 1.55GB)
afbb8b3f5759        docker-compose_broker               "air -c .air.d/.brok…"   2 weeks ago         Up 25 hours                                                                          docker-compose_broker_1          647MB (virtual 1.5GB)
a098f7b7c0ca        docker-compose_monitor              "air -c .air.d/.moni…"   2 weeks ago         Up 25 hours                                                                          docker-compose_monitor_1         647MB (virtual 1.5GB)
5e8cbcf83ab7        docker-compose_syncer               "air -c .air.d/.sync…"   2 weeks ago         Up 25 hours                                                                          docker-compose_syncer_1          647MB (virtual 1.5GB)
242a1d4df552        docker-compose_consumer             "air -c .air.d/.cons…"   2 weeks ago         Up 25 hours                                                                          docker-compose_consumer_1        492MB (virtual 1.35GB)
6400d22f6122        docker-compose_collector            "air -c .air.d/.coll…"   2 weeks ago         Up 25 hours                                                                          docker-compose_collector_1       492MB (virtual 1.35GB)
2ae65278bb7d        docker-compose_jobserver            "air -c .air.d/.jobs…"   2 weeks ago         Up 25 hours         0.0.0.0:50052->50051/tcp                                         docker-compose_jobserver_1       407MB (virtual 1.26GB)
5df246937368        nsqio/nsq                           "/nsqadmin --lookupd…"   2 weeks ago         Up 25 hours         4150-4151/tcp, 4160-4161/tcp, 4170/tcp, 0.0.0.0:4171->4171/tcp   docker-compose_nsqadmin_1        0B (virtual 65.6MB)
3f71a287725c        nsqio/nsq                           "/nsqd --lookupd-tcp…"   2 weeks ago         Up 25 hours         4160-4161/tcp, 0.0.0.0:4150-4151->4150-4151/tcp, 4170-4171/tcp   docker-compose_nsqd_1            31B (virtual 65.6MB)
84970e354c8e        nsqio/nsq                           "/nsqlookupd"            2 weeks ago         Up 25 hours         4150-4151/tcp, 4170-4171/tcp, 0.0.0.0:4160-4161->4160-4161/tcp   docker-compose_nsqlookupd_1      0B (virtual 65.6MB)
e150fb69b286        postgres:12.1                       "docker-entrypoint.s…"   2 weeks ago         Up 25 hours         0.0.0.0:5433->5432/tcp                                           docker-compose_db_1              63B (virtual 394MB)
db79c1565342        timescale/timescaledb:latest-pg11   "docker-entrypoint.s…"   2 weeks ago         Up 25 hours         0.0.0.0:5434->5432/tcp                                           docker-compose_timescale_1       63B (virtual 178MB)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Manjaro に Docker 環境をインストール

はじめに

Raspberry Pi 4 にインストールした Manjaro に Docker を入れて何かサーバを立てよう。
初めてのArch系で、恥ずかしながら緊張しているよ。

確認環境
$ lsb_release -rd
Description:    Manjaro ARM Linux
Release:        20.09

Docker

インストール

$ sudo docker -S docker
$ docker --version
Docker version 19.03.12-ce, build 48a66213fe

一般ユーザに実行権限を与える

$ sudo usermod -aG docker `whoami`

サービスの有効化

再起動無しで systemctl start docker したかったが、全然起動してくれなかった。
systemctl enable docker して再起動したらあっさりいけたので、これで良しとする。

$ sudo systemctl enable docker
$ sudo reboot

Docker Compose

インストール

$ sudo docker -S docker-compose
$ docker-compose --version
docker-compose version 1.27.3, build unknown

おわりに

結構パッケージ充実してんだね。

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