1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

初学者によるDocker理解まとめ③ 〜nginxを使ってAPIをproxyするまで〜

Last updated at Posted at 2020-10-23

はじめに

ようやくDockerを学び始めたので自分の理解をまとめておく。
前回 => https://qiita.com/theFirstPenguin/items/58e6bc5acf90dc497cb0
次回 => https://qiita.com/theFirstPenguin/items/b5f6ed253bed95fbec5a

今日の学びをメモ

ローカルPC上でnode.jsでexpressを実行するコンテナとnginxを実行するコンテナを立ち上げる。そしてnginxを経由してexpressのAPIを叩く。たったこれだけをdocker-composeを使ってやってみた。

前回までと今回の違い

前回ではexpressのコンテナにアクセスするためにportを指定する必要があった。

curl http://localhost:3000
Hello

スクリーンショット 2020-10-22 22.22.35.png

今回はnginxのproxy機能を用いて、portを指定せずexpressのコンテナにアクセスできるようにした。

curl http://:localhost
Hello

スクリーンショット 2020-10-23 8.32.39.png

開発の全体像

cd ~
mkdir sample

sampleディレクトリの中で開発する。ディレクトリの中身はこんな感じになる。
appディレクトリとwebディレクトリがそれぞれexpressとnginxのコンテナとなる。
スクリーンショット 2020-10-23 8.24.02.png

index.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
  res.send('Hello').status(200);
});

app.listen(3000, () => {
  console.log('Listening on port 3000');
});

expressバックエンドのDockerfileの準備

FROM node:alpine

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .
# package.jsonをコピー後にnpm installするという作業をビルドの度に毎回やりたくない。
# そのため、上記を終わらせてから COPY. .をやる。
# そうすればコードを変えた部分だけビルドが実行される。

EXPOSE 3000
CMD [ "node", "index.js" ]

nginx.confの準備

nginxコンテナの中の、localhostの80port(つまりhttpのデフォルトport)の全てのエンドポイント(/)に来たリクエストをhttp://app:3000にproxyする。
Dockerの管理下において、appコンテナのドメインがappになっていることに注目。
ちなみに、この設定ファイル名はnginx.confで固定とのこと。配置場所はwebディレクトリ以下であれば特に気にしない。

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 1024;
}

http {
	# Weather Report Reverse Proxy
         server {
            listen 80;
            server_name localhost 127.0.0.1;

            location / {
                proxy_pass          http://app:3000;
                proxy_set_header    X-Forwarded-For $remote_addr;
            }

        }
}

docker-compose.ymlの準備

docker-compose.yml
version: '3'
# 何も考えず3を指定
services:
  app:
    build:
      context: ./app
      # docker-compose.ymlから見て./appにあるDockerfileにしたがってビルドする
    container_name: express-app
    # 一応コンテナ名をつける
    ports:
      - '3000:3000'
      # docker run -p 3000:3000 app と一緒
    volumes:
      - './app:/usr/src/app'
      # ローカルPCの./appフォルダと、コンテナ内の ~/usr/src/appフォルダを同期させる。
      # docker exec -it express-app sh で確認できる

  web:
    image: nginx:latest 
    #nginx:alpilneだとエラーが起きるので、一応最新版で対応。
    container_name: nginx-web
    ports:
      - '80:80'
    volumes:
      - './web/reverse_proxy/nginx.conf:/etc/nginx/nginx.conf'
      # ローカルPCの./web/reverse_proxy/nginx.confと、コンテナ内の ~/etc/nginx/nginx.confを同期させる。
      # ~/etc/nginx/nginx.confは場所指定。
    links:
      - app
    depends_on:
      - app
      # appコンテナが起動しないと機能しない、という依存関係を明記。

docker-compose up して終わり

docker-compose upすればコンテナが立ち上がります。
ローカルPCからcurlコマンドを打てばappコンテナから返事が帰ってきます。最初の図の通りです。

curl http://localhost
Hello

ちなみに直接appコンテナにもアクセスできます。当然ですが。

curl http://localhost:3000
Hello

最後に

初歩中の初歩をまとめました。
ちなみに、自分は何度やってもnginxがうまく起動せず絶望しかけましたが、docker psをするとk8s_controller_ingress-nginx-controllerという謎のコンテナ(というかkubernetesのingressだと思われる)がdocker stopしても止まらないことに気付きました。kubernetesを再起動すると直ったので、仮にそんな状況があれば試すのもいいかと思います。

スクリーンショット 2020-10-23 9.33.31.png

ありがとうございました。

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?