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

Docker-composeでNext.js + Go (+ nginx) のWebアプリを動かしてみた

Last updated at Posted at 2025-01-28

この記事は

  • ローカル環境で開発したNext.jsとGoによるWebアプリをDockerコンテナ上で動作するように移植する方法
  • Docker-composeを用いた際のnginxのリバースプロキシの方法

について述べる

あらすじ

以前,個人開発で作成したNext.jsとGoで書いたバックエンドの組み合わせで動作するWebアプリ(ファイルアップローダー)を,実運用するにあたって,Dockerコンテナに移植して,Docker-composeで一発動作するようにしようと思い立った.なので,ゴニョゴニョやったことをまとめる.

前提

  • ファイルアップローダーはGithubにあるので,それをクローンしてきて勝手にセッティングしてほしい

  • フロント側から,バックへfetchする動作があるが,それも1つのドメインで統一して処理できるようにしたい.(Cloudflare tunnnelを使いたい)

    • ということで,nginxのリバプロでなんとかする

やったこと

まずそれぞれについてDockerfileを作成した.

作ったDockerFile

フロント側(Next.js)

imageは,node.jsの公式イメージを使用した.まず,githubからリポジトリをクローンしてきて,next.jsのルートディレクトリにWORKDIRを設定する.

その後,環境変数を設定するために,.env.localをルートディレクトリ直下にコピーする.そして,npm installで依存関係をインストールし,npm run buildでビルドしておく.ちなみに,.env.localは実行のたびに読み込まれる.
(参考: https://zenn.dev/aktriver/articles/2022-04-nextjs-env )

下記に,Dockerfileの例を示す.EXPOSEはnextで指定されるアクセスポートを設定しておく.

FROM node:23.6

WORKDIR /node
EXPOSE 3000

RUN git clone https://github.com/syou551/dirShareApp.git 

WORKDIR /node/dirShareApp/front/dir-share

COPY ./.env.local .
RUN npm install\
    && npm run build

バック側(Go)

imageは,Goの公式のものを用いた.フロント側と同様にリポジトリをクローンして,バック側のディレクトリに移動する.その後,依存モジュールをgo mod tidyでインストールし,その後ビルドする.
ちなみに,go.modがないと怒られてビルドできないので,開発段階でgo mod initを忘れないようにしよう.(参考: https://qiita.com/TakanoriVega/items/6d7210147c289b45298a )

FROM golang:1.23

WORKDIR /go/src

EXPOSE 80

RUN git clone https://github.com/syou551/dirShareApp.git

WORKDIR /go/src/dirShareApp/back

RUN go mod tidy\
    && go build main.go handler.go

nginx

imageはnginxの公式のものを使った.Dockerfileは単に設定ファイルをコピーしているだけである.

FROM nginx:latest

COPY ./nginx.conf /etc/nginx/conf.d/default.conf

本題は,設定ファイルである.リバースプロキシのための基本的な設定は同様であるが,今回はdocker-composeで動かすことを念頭において設定をする.

Dockerでは,docker composeをすると,Networkを明示的に記述しない限りは,それぞれは検出可能となり,それぞれのコンテナへサービス名を指定することでアクセスできるようになる.

  • Ex.) serviceがfrontなら,(プロトコル)://front:(ポート)のような形でアクセス可能

(参考: https://docs.docker.jp/compose/networking.html )

これを使って,nginxのproxy_passをサービス名に合わせて設定すれば良い.

また,今回は,外部へ向けて公開するポートは1つに絞りたいため,locationによってフロント側かバック側かを振り分けるようにする.以下の例では,/dir/以下のパスへのリクエストは,バックへ流すように設定している.ただし,バック側では/dir/を含むリクエストは設定しておらず,リバプロのために勝手につけたパスであるため,取り除いてそれ以降のパスを流すようにしたい.

このためには,proxy_passの最後に/をつけることで,/dir/hoge/hugaへのリクエストは,{proxy_passで設定した宛先}/hoge/hugaへ飛ばすことができる.ちなみに,/をつけない場合は,トリミングされずそのまま渡される.これいつもどっちかわからなくなるので困る.
(参考: https://qiita.com/mkuwan/items/dce68409aaf16142a438 )

server{
    listen 80;
    server_name app;

    location /dir/ {
        proxy_pass http://back/;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    location / {
        proxy_pass http://front:3000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

作ったdocker-compose.yaml

次に,こいつらをdocker compose upで一括処理できるように,yamlを書いていく.ちなみに, 一応説明すると,docker-compose.yamlは,複数のコンテナをこんなふうに動かしてくださいと指示するための指示書である.

まず,今回は各コンテナに対してすでにDockerfileを作成したので,buildでDockerfileを配置しているディレクトリ(context)とそのファイル名を指定する.

今回のディレクトリ構成は以下のような形である.

FileUploader
|- docker-compose.yaml
|- front
|   |- Dockerfile
|   |- .env.local
|
|- back
|   |- Dockerfile
|
|- nginx
    |- Dockerfile
    |- nginx.conf

なので,contextdockerfileは以下のように設定すれば良い.

サービス名:
    build:
      context: ./front
      dockerfile: Dockerfile

その後,フロント側とバック側に関しては,起動するために,ルートディレクトリにworking_dirを設定する.そして,commandで起動コマンドを入力すれば良い.なお,bashなどを使いたい時は,command: bash -c "./main"のように指定する.
(参考: https://qiita.com/ntrlmt/items/cce919c14e4dff07e7ee )

また,nginxに関しては,フロントとバックが起動しているかどうかを確認してから起動するように,depends_onを指定しておく.

また,外部に開くポートに関しては,nginxだけを見せれば良いでの,ホスト側の任意のポートとnginxがListenしているポートをマッピングさせておく.

    nginx:
        ports:
          - "8080:80"

以上の項目を書き込んだyamlの例を以下に示す.

services:
  front:
    build:
      context: ./front
      dockerfile: Dockerfile
    working_dir: /node/dirShareApp/front/dir-share
    command: npm run start
  back:
    build:
      context: ./back
      dockerfile: Dockerfile
    working_dir: /go/src/dirShareApp/back
    command: bash -c "./main"
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    depends_on:
      - front
      - back
    ports:
      - "8080:80"
    

動作確認

docker compose upをすると,自動でコンテナがビルドされ,アプリも起動.今回の設定では,localhost:8080にアクセスすれば,next.jsのアプリ画面が開き,操作すると無事バックにもリクエストが通っているのが確認できました.ちなみに,設定ファイルはgithubで公開しています.

まとめ

Docker composeを使えば,1コマンドで一連のアプリを自動で起動させることができるようになりました!

その他参考サイト

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?