LoginSignup
0
0

エンジニア管理ツールでも作る④Nginx環境用意

Posted at

前回

Next.jsとFlaskのアプリを用意しました。

今回の目標

DockerでNginxの環境を作る

image.png

こんな感じでリクエストを振り分けます。

Dockerfileの用意

# web/Dockerfile
FROM  nginx:latest

「Dockerfileいらないやん」と思うでしょう。その通りです。
まあいつかカスタムしたくなるかもしれませんし...

docker-compose.ymlの用意

version: '3'
services:
  api:
    build: api
    image: sk-api
    volumes:
      - ./api:/app
    ports:
      - "8001:8000"
    command: 'gunicorn'
  front:
    build: front
    image: sk-front
    volumes:
      - ./front:/app
    ports:
      - "3001:3000"
    command: 'npm run dev'
  web:
    build: web
    image: sk-web
    volumes:
      - ./web/default.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "10101:80"

/etc/nginx/conf.d/default.confを上書きして設定を反映させます。

ポートは適当に10101です。
最初10080に設定してたんですが、ブラウザから見ようとするとERR_UNSAFE_PORTというエラーになってしまいました。
こんな罠があるんですね。知りませんでした。

Nginxの設定ファイル

# web/default.conf
server {
    listen 80;

    location / {
        proxy_pass http://front:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /api {
        proxy_pass http://api:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

listen 80;は80番ポートで受け付けるという意味です。

location /http://localhost/の設定で、
location /apihttp://localhost/apiの設定です。

proxy_passはどこに飛ばすかの設定です。
http://localhost/http://front:3000
http://localhost/apihttp://api:8000に飛ばします。

proxy_set_headerで色々書いてありますが、
どれもクライアントの情報(IP情報など)をそのまま裏に受け流しています。
この設定がないと、裏のNext.jsから見たクライアント情報が全てこのnginxになってしまします。

Dockerコンテナ同士の疎通

Dockerコンテナは独自のネットワーク空間を持っています。
なのでdocker-compose.ymlports: "10101:80"などを設定しないとホストPCからコンテナへの通信ができません。

コンテナ同士の通信では、コンテナたちが同じネットワークに属していないといけません。

素のDockerを使う場合、ネットワークを作成して、そのネットワークにコンテナを属させて...みたいな操作が必要になります。

Docker Composeを使う場合、この手間がなくなります。
同じdocker-compose.ymlに書かれたservice(コンテナ)たちは勝手に同じネットワークに属してくれます。

docker network ls

を打つと

NETWORK ID     NAME                  DRIVER    SCOPE
330f30e92154   host                  host      local
16d9e5f32225   skill_default         bridge    local

ディレクトリ名_defaultというネットワークが作成されているのが分かります。
(skillとかいう適当な名前をつけていた事がバレる)

さらに細かい情報を見る場合は以下のようなコマンドを打ってみてください。

docker network inspect { NETWORK ID }

割り当てられているIPアドレスやら所属しているコンテナやらが見えると思います。

コンテナが同じネットワークに属している場合、「service名」で対象コンテナにアクセスできます。
なので

proxy_pass http://front:3000;

proxy_pass http://api:8000;

みたいに書くことができるわけです。

動作確認

webコンテナを立ち上げる

docker compose up -d

http://localhost:10101/ にアクセスしてみましょう。

image.png

frontコンテナにつながってますね。


http://localhost:10101/api にアクセスしてみましょう。

image.png

apiコンテナにつながってますね。

CORS問題の解消

CORS (オリジン間リソース共有、Cross-Origin Resource Sharing) という仕組みがあります。
XSS (Cross Site Scripting)攻撃などを防ぐ目的で、
ブラウザが今開いているURLとは違うURLのAPIを使おうとすると怒られます。

今回設定したnginxがない場合、
フロントのlocalhost:8001からバックのlocalhost:3001に対してリクエストを送るので、このCORS問題で怒られます。
解決するにはバック側でCORSの許可をしてやる必要があります。

今回、フロントもバックもlocalhost:10101という同じURLになったので、CORSを考えなくてよくなります。

docker-compsoe.ymlの修正

apiコンテナとfrontコンテナのポートを解放してありましたが、Nginxを経由することでその必要は無くなりました。
なので、portsを削除してやって設定完了です。

version: '3'
services:
  api:
    build: api
    image: sk-api
    volumes:
      - ./api:/app
    command: 'gunicorn'
  front:
    build: front
    image: sk-front
    volumes:
      - ./front:/app
    command: 'npm run dev'
  web:
    build: web
    image: sk-web
    volumes:
      - ./web/default.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "10101:80"

コンテナを再作成しても動作に問題ないことを確認しておきます。

docker compose down
docker compose up -d

次回

DB(MySQL)の用意

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0