プログラミング

Docker + DjangoでGraphQLサーバを立てる

2023年3月8日

スマホアプリ開発を行う際にバックエンドをFirebaseのみで実装するのは流石に無理があると感じたので、APIは自前で実装することにしました。

Dart以外ではPythonが得意なのでフレームワークはDjangoを使用し、APIスキーマはGraphQLを採用し、Dockerで仮想環境を構築して開発を行います。

環境

OS ... macOS Ventura 13.1

エディタ ... VSCode

Dockerをインストール

Mac環境への導入方法の詳細は記載されているサイトがたくさんあるので、ここでは簡単に説明します。

  1. Docker Hubに登録して、Dockerアカウント登録をします。
  2. Docker Desktop for Macのページから、ダウンロードボタンをクリックしてDocker Desktopのインストーラをダウンロードします。
  3. ダウンロードしたDocker Desktopインストーラを開きます。
  4. インストーラの指示に従って、Docker Desktopをインストールします。
  5. インストールが完了したら、Docker Desktopを起動します。

Docker自体の説明については割愛します。

よく使うDockerコマンド

コマンド説明
docker build -t <イメージ名> .Dockerfileからイメージをビルドする
docker run <オプション> <イメージ名>イメージからコンテナを作成して実行する
docker ps現在実行中のコンテナを表示する
docker ps -a実行中のコンテナと停止中のコンテナを含め、すべてのコンテナを表示する
docker stop <コンテナID>指定されたコンテナを停止する
docker rm <コンテナID>指定されたコンテナを削除する
docker imagesローカルに保存されているイメージの一覧を表示する
docker rmi <イメージID>指定されたイメージを削除する
docker builder pruneビルド時に生成されたキャッシュの削除

よく使うdocker-composeコマンド

コマンド説明
docker-compose buildDocker Composeファイルで定義されたサービスのイメージをビルドする。
docker-compose runDocker Composeファイルで指定されたサービスを実行してコマンドを実行する。
docker-compose execDocker Composeファイルで指定されたコンテナ内でコマンドを実行する
docker-compose upDocker Composeファイルで指定されたコンテナをビルドして開始する
docker-compose downDocker Composeファイルで指定されたコンテナを停止して削除する
docker-compose psDocker Composeファイルで指定されたコンテナの状態を表示する
docker-compose logsDocker Composeファイルで指定されたコンテナのログを表示する

dockerとdocker-composeの違い

Dockerとdocker-composeは、両方ともコンテナ化されたアプリケーションの開発やデプロイに使用されますが、異なる目的を持っています。

Dockerは、単一のコンテナを管理するために使用されます。Dockerイメージを使用してアプリケーションを定義し、それを単一のDockerコンテナとして実行します。

一方、docker-composeは、複数のコンテナを管理するために使用されます。Docker Composeファイルを使用して、複数のDockerコンテナを定義し、それらを一緒に実行します。

例えばWebアプリケーションを考える場合、DockerはWebサーバーのみをコンテナとして実行するために使用されます。一方、docker-composeは、Webサーバー、データベースサーバー、およびキャッシュサーバーなどの複数のコンテナを定義し、それらを一緒に実行するために使用されます。

Docker ComposeでDjangoをセットアップする

任意のディレクトリに、Djangoのプロジェクトファイルを作成します。

$ mkdir django-graphql-sample
$ cd django-graphql-sample

プロジェクトファイル内に、以下の3つのファイルを作成します。

% touch Dockerfile
% touch requirements.txt
% touch docker-compose.yml
% ls
Dockerfile         docker-compose.yml requirements.txt

Dockfile

Docker imageの設計図を記述します。

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

requirements.txt

pipでインストールするライブラリとバージョンを記述します。

バージョンはブログ執筆時点(2023/03/06)の最新バージョンとなります。

Django==4.1.7
psycopg2==2.9.5
graphene_django==3.0.0

docker-compose.yml

docker-composeでビルドするサービスの情報を記述します。

今回はdb, pgAdmin, webの3つを使用します。

version: "3"

services:
  db:
    image: postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432"
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  pgadmin4:
    image: dpage/pgadmin4
    ports:
        - 8888:80
    volumes:
        - pgadmin4_data:/var/lib/pgadmin
    environment:
        PGADMIN_DEFAULT_EMAIL: [メールアドレス]
        PGADMIN_DEFAULT_PASSWORD: [パスワード]
    depends_on:
      - db
  web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
volumes:
  postgres_data:
  pgadmin4_data:

Dangoプロジェクトを作成

docker-compose.ymlで定義されたサービスのイメージをビルドし、

$ docker-compose build

djangoプロジェクトを作成するコマンドを実行します。

$ docker-compose run web django-admin startproject project .

実行後、django-graphql-sample内にprojectディレクトリとmanage.pyが作成されます。

アプリケーションを作成

サンプルアプリケーションを作成します。

$ docker-compose run web django-admin startapp app

実行後、django-graphql-sample内にappディレクトリが作成されます。

settings.pyに設定情報を追加

project/settings.pyに、サンプルアプリとgraphene_djangoやDBの設定情報を追記します。

INSTALLED_APPS = [
    'graphene_django',
    'app',
]

GRAPHENE = {
    'SCHEMA': 'project.schema.schema'
}

# デフォルトのデータベース接続情報はsqliteとなっているので、postgresへの接続情報に書き換えます。
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'db',
        'PASSWORD': 'postgres',
        'PORT': 5432,
    }
}

モデルを定義

app/models.pyにモデルを定義します。

from django.db import models

class Fruit(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=255, blank=True, null=True)
    color = models.CharField(max_length=255, blank=True, null=True)
    created = models.DateTimeField(blank=True, null=True)

    def __str__(self):
       return self.name

スキーマを定義

appとprojectのそれぞれにscheme.pyを作成し、スキーマを定義していきます。

import graphene
from graphene_django.types import DjangoObjectType
from app.models import Fruit

class FruitType(DjangoObjectType):
    class Meta:
        model = Fruit

class Query:
    fruit= graphene.Field(FruitType, id=graphene.Int())
    all_fruits = graphene.List(FruitType)

    def resolve_fruit(self, info, **kwargs):
        id = kwargs.get('id')

        if id is not None:
            return Fruit.objects.get(pk=id)
        return None

    def resolve_all_fruits(self, info, **kwargs):
        return Fruit.objects.all()

import graphene
from app.scheme import Query

class Query(Query, graphene.ObjectType):
    pass

schema = graphene.Schema(
    query=Query,
)

GraphQLのエンドポイントを追加

project/urls.pyにエンドポイントを追加します。

from django.contrib import admin
from django.urls import path
from graphene_django.views import GraphQLView
from project.scheme import schema

urlpatterns = [
    path('admin/', admin.site.urls),
    path('graphql/', GraphQLView.as_view(graphiql=True, schema=schema)),
]

ここまででDBの情報の記述は完了したので、マイグレーションを行います。

$ docker-compose run web python manage.py makemigrations
$ docker-compose run web python manage.py migrate

コンテナをビルドする

ここまででセットアップは完了したので、コンテナをビルドして動作確認を行います。

$ docker-compose up

動作確認

pgAdminでDBサーバを作成

pgAdminにアクセスし、DBサーバを構築します。

http://localhost:8888/ にログイン後

docker-compose.ymlのPGADMIN_DEFAULT_EMAILPGADMIN_DEFAULT_PASSWORD に記載した内容でログイン

ログイン後の画面

新しいサーバを追加 をクリック

Generalにサーバの名前を記述

接続には、project/settings.pyに記載したホスト名やポート番号、ログイン情報を記述します。

保存を押下しサーバを追加します。

DBサーバに初期データを登録

確認用にサーバにデータを登録します。

app/fixtures/data.jsonを用意し、登録するデータを記述します。

[
  {
    "model": "app.Fruit",
    "pk": 1,
    "fields": {
      "name": "apple",
      "color": "red"
    }
  },
  {
    "model": "app.Fruit",
    "pk": 2,
    "fields": {
      "name": "banaan",
      "color": "yellow"
    }
  },
  {
    "model": "app.Fruit",
    "pk": 3,
    "fields": {
      "name": "strawberry",
      "color": "red"
    }
  }
]

一度コンテナを停止し、データの読み込みコマンドを実行後再度コンテナを起動します。

$ docker-compose down
$ docker-compose run web python manage.py loaddata data
$ docker-compose up

再度pgAdminにアクセス後テーブルを確認すると、読み込んだデータが登録されていることが確認できます。

GraphQLでQueryを発行する

http://localhost:8000/ にアクセスしqueryを発行するとデータを取得することができます。

最後に

今回はDockerを使ってDjangoでGraphQLサーバを立てる方法についてまとめました。

ローカルで環境を用意するとWebサーバやDBを別々で管理しないといけないところを、仮想環境を構築して一括管理できて便利ですね。

今後もバックエンド開発関連の記事を執筆予定ですので、ぜひご覧ください!

参考

https://qiita.com/takos/items/c04ac2a64d519894ee13

https://www.ninton.co.jp/archives/5526

  • この記事を書いた人
  • 最新記事

おみ

プログラミング学習やキャリアのことを発信していきます。【経歴】1999年生まれ。専門学校卒業後、大手企業やベンチャー企業でSEとして勤務。現在は某メガベンチャーでFlutterエンジニアとして働いています。

-プログラミング
-, , , , ,