ksino's diary

覚えたことを忘れないように、小さなことでも書いていく。

WARファイルをDocker上のTomcatにデプロイする

やること

手順

作業ディレクトリを準備する
$ mkdir tomcat_test
$ cd tomcat_test

デプロイするWARファイルを作業ディレクトリに配置する

$ ls
sample.war
Dockerfileを作成する

現在のディレクトリに以下内容のDockerfileを作成する。

FROM tomcat:10.1

COPY sample.war $CATALINA_HOME/webapps
イメージをビルドする
$ sudo docker build -t tomcat_test .
Sending build context to Docker daemon  7.168kB
Step 1/2 : FROM tomcat:10.1
10.1: Pulling from library/tomcat
Digest: sha256:dd920d167352e9e21b297dbe08c54ca35c445c100f38bf9be9a8fa85c9196e7f
Status: Downloaded newer image for tomcat:10.1
 ---> 1dad8c5497f9
Step 2/2 : COPY sample.war $CATALINA_HOME/webapps
 ---> Using cache
 ---> aa99b9252ca9
Successfully built aa99b9252ca9
Successfully tagged tomcat_test:latest
コンテナを起動する
$ sudo docker run -itd -p 8080:8080 --name tomcat_test tomcat_test:latest
d5aa87d12aa48c6f17f2553698f72b93ce2845a26dbb90b598e636acbaa1f9c7
$ sudo docker ps
CONTAINER ID   IMAGE                COMMAND             CREATED         STATUS         PORTS
                     NAMES
d5aa87d12aa4   tomcat_test:latest   "catalina.sh run"   4 seconds ago   Up 3 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   tomcat_test
動作確認

ブラウザを開き、下記URLを開く。

http://localhost:8080/sample

WSL2のUbuntu 22.04.1 LTSでDockerが起動しない

やったこと

以下を参考にDockerをインストールした。
docs.docker.com
sudo docker run hello-world
してみたもののDockerが起動しない。

調べたこと

/var/log/docker.log
failed to start daemon: Error initializing network controller: error obtaining controller instance: unable to add return rule in DOCKER-ISOLATION-STAGE-1 chain:  (iptables failed: iptables --wait -A DOCKER-ISOLATION-STAGE-1 -j RETURN: iptables v1.8.7 (nf_tables):  RULE_APPEND failed (No such file or directory): rule in chain DOCKER-ISOLATION-STAGE-1
 (exit status 4))

こんなログが出ていたのでググってみると、どうもDockerが新しいiptablesに対応していないとかで、古いものに切り替えれば良いらしい。

対応したこと

以下のコマンドを実行するとiptablesのリストが出てくるので、"iptables-legacy"を選ぶ。

$ sudo update-alternatives --config iptables

DjangoでREST API的なものをつくる

概要

  • Django REST frameworkは使わない
  • セキュリティは無視
  • POST
  • Jsonで数値を2つ送り、加算結果をJsonで返す

手順

プロジェクトを作る

$ django-admin startproject restproject

アプリを作る

$ python3 manage.py startapp calc

ソースを編集する

restproject/restproject/settings.py
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "calc.apps.CalcConfig",  # ★追加
]
restproject/restproject/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("calc.urls")),  # ★追加
]
restproject/calc/urls.py (新規作成ファイル)
from django.urls import path
from . import views

urlpatterns = [
    path("add/", views.add),
]
restproject/calc/views.py
from django.http.response import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json


@csrf_exempt
def add(request):
    if request.method == "GET":
        return JsonResponse({})

    req_json = json.loads(request.body)
    num1 = req_json["num1"]
    num2 = req_json["num2"]

    sum = num1 + num2
    res_json = {"sum": sum}
    return JsonResponse(res_json)

動作確認

Postmanで動作確認

1つのホストで複数のDjangoプロジェクトを動かす

やりたいこと

  • 1つのホストで複数のDjangoプロジェクトを動かしたい。
  • 動作環境は Gunicorn + nginx とする。
  • セキュリティは考慮しない。

方針

  • Gunicornをプロジェクトごとにポートを変えて起動する
  • nginxのリバースプロキシ設定で、URLごとに接続先gunicornのポートを振り分ける

動作検証用Djangoプロジェクト

プロジェクト site1, アプリケーション hello

hello/views.py
from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello !")
site1/urls.py
urlpatterns = [
  path("admin/", admin.site.urls),
  path("", hello)
]
site1/settings.py
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "hello", # ★追加
]

プロジェクト site2, アプリケーション world

world/views.py
from django.http import HttpResponse

def world(request):
    return HttpResponse("World !")
site2/urls.py
urlpatterns = [
  path("admin/", admin.site.urls),
  path("", world)
]
site2/settings.py
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "world", # ★追加
]

Gunicornの起動

site1とsite2でポートを変えて起動する。

$ gunicorn --bind localhost:8001 site1.wsgi
$ gunicorn --bind localhost:8002 site2.wsgi

nginxの設定

$ sudo vim /etc/nginx/conf.d/site.conf

/site1 をポート8001に、/site2 をポート8002に結びつける。

server {
        listen 80;

        location /site1 {
                proxy_pass http://localhost:8001;
        }
        location /site2 {
                proxy_pass http://localhost:8002;
        }
}

※↓環境次第ではいらないかも(WSLのUbuntu 20.04LTSでは必要だった)

$ sudo rm /etc/nginx/sites-enabled/default

nginxリロード

$ nginx -s reload

ブラウザで表示確認