質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

proxy

proxy(プロキシー)は、企業などの内部コンピュータとインターネットの中間に位置し、例えば直接インターネットに接続できない内部コンピュータの代理としてインターネットに接続する等をするシステム、もしくは代理として機能を実行するソフトウェアです。内部ネットワークへのアクセスを一元管理し、内部からの特定の種類の接続以外を遮断すること、外部からの不正アクセスを拒否することなどに用いられます。

Q&A

0回答

1649閲覧

jwilder/nginx-proxyで複数のDBコンテナの同じportに疎通させたい

mackintosh

総合スコア228

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

proxy

proxy(プロキシー)は、企業などの内部コンピュータとインターネットの中間に位置し、例えば直接インターネットに接続できない内部コンピュータの代理としてインターネットに接続する等をするシステム、もしくは代理として機能を実行するソフトウェアです。内部ネットワークへのアクセスを一元管理し、内部からの特定の種類の接続以外を遮断すること、外部からの不正アクセスを拒否することなどに用いられます。

0グッド

0クリップ

投稿2021/10/23 14:43

わかる方いましたらお願いします。

docker-composeでローカル環境構築しているのですが
ローカル環境で案件1と2のように複数のDBコンテナで3306で受けることはできませんでしょうか?

案件1と2はディレクトリで分けていてdocker-compose.ymlはそれぞれのディレクトリにあり両ymlファイルに

ports: - :3306:3306

とすると当然portの競合をするので、portsを使う場合3307:3306などと案件ごとにportの管理をしていかなければならないはめになるので、exposeを使えばportの競合はおきませんが、sqlクライアントなどからアクセスできなくなってしまいました。

portの場合、sqlクライアントで127.0.0.1:3006や127.0.0.1:3007で疎通できていましたが
exposeにすると127.0.0.1で疎通ができていないようです。

ちなみに、jwilder/nginx-proxyを使っているのでDBコンテナに名前解決(バーチャルドメイン)指定して、
local.db.anken1.jp:80やlocal.db.anken1.jp:3306としても疎通できません。

SPA開発のdocker構成例ですが一部挙げます。

anken1: build: ./containers/anken1 container_name: "anken1" networks: - container-link environment: - TZ=Asia/Tokyo - VIRTUAL_HOST=local.anken1.jp - LETSENCRYPT_HOST=local.anken1.jp - CERT_NAME=default - NUXT_HOST=0.0.0.0 expose: - 3000 volumes: - ./../services/anken1:/var/www/html - ./config/root/anken1/.bashrc:/root/.bashrc - ./config/root/.vimrc:/root/.vimrc working_dir: /var/www/html command: bash -c "yarn dev" anken1-api: build: ./containers/anken1-api container_name: "anken1-api" networks: - container-link environment: - TZ=Asia/Tokyo - VIRTUAL_HOST=local.api.anken1.jp - LETSENCRYPT_HOST=local.api.anken1.jp - CERT_NAME=default expose: - 80 volumes: - ./../services/anken1-api:/var/www/html - ./config/root/anken1-api/.bashrc:/root/.bashrc - ./config/root/.vimrc:/root/.vimrc working_dir: /var/www/html anken1-db: build: ./containers/anken1-db container_name: "anken1-db" networks: - container-link expose: - 3306 environment: - TZ=Asia/Tokyo - MYSQL_ROOT_PASSWORD=root - VIRTUAL_HOST=local.db.anken1.jp - LETSENCRYPT_HOST=local.db.anken1.jp - CERT_NAME=default volumes: - ./containers/anken1-db/docker-entrypoint-initdb.d/initial.sql:/docker-entrypoint-initdb.d/initial.sql - mysql:/var/lib/mysql - ./config/root/.bashrc:/root/.bashrc - ./config/root/.vimrc:/root/.vimrc

VIRTUAL_HOSTとLETSENCRYPT_HOSTはjwilder/nginx-proxyと連動していて、ホストPCの/etc/hostsにバーチャルドメインを記述して127.0.0.1お紐づけておけばあとは勝手に、jwilder/nginx-proxyを経由して対象のコンテナにproxyしてくれるものです。

フロントとAPIの方は問題なく疎通しています。
ブラウザでnuxt.jsの方も描画されて動いています。

なにが原因なのかと思ってnginx-proxyに入ってnginxの設定を見てみました。

% docker exec -it nginx-proxy bash [nginx-proxy][root@a7435562c65b:0 app]# cat /etc/nginx/conf.d/default.conf
# local.anken1.jp upstream local.anken1.jp { ## Can be connected with "container_network" network # anken1 server 172.18.0.7:3000; } server { server_name local.anken1.jp; listen 80 ; access_log /var/log/nginx/access.log vhost; # Do not HTTPS redirect Let'sEncrypt ACME challenge location ^~ /.well-known/acme-challenge/ { auth_basic off; auth_request off; allow all; root /usr/share/nginx/html; try_files $uri =404; break; } location / { return 301 https://$host$request_uri; } } server { server_name local.anken1.jp; listen 443 ssl http2 ; access_log /var/log/nginx/access.log vhost; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; add_header Strict-Transport-Security "max-age=31536000" always; include /etc/nginx/vhost.d/default; location / { proxy_pass http://local.anken1.jp; } }

最終的に、upstreamで3000に転送かけているのでanken1で3000でexposeしているnuxtにアクセスできているのか、ふむふむ。

# local.db.anken1.jp upstream local.db.anken1.jp { ## Can be connected with "container_network" network # anken1-db server 172.18.0.5:80; } server { server_name local.db.anken1.jp; listen 80 ; access_log /var/log/nginx/access.log vhost; # Do not HTTPS redirect Let'sEncrypt ACME challenge location ^~ /.well-known/acme-challenge/ { auth_basic off; auth_request off; allow all; root /usr/share/nginx/html; try_files $uri =404; break; } location / { return 301 https://$host$request_uri; } } server { server_name local.db.anken1.jp; listen 443 ssl http2 ; access_log /var/log/nginx/access.log vhost; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; add_header Strict-Transport-Security "max-age=31536000" always; include /etc/nginx/vhost.d/default; location / { proxy_pass http://local.db.anken1.jp; } }

dbの名前解決の方は、3306でexposeしてるはずなのに80でproxyされている...
nginxの設定ファイルはVIRTUAL_HOSTとLETSENCRYPT_HOSTがあるサービスからproxyが何に設定されているかなど読み取って自動生成されるので、ここのupstreamの172.18.0.5:80;を172.18.0.5:3306;にかえたいところだけど動作がどうなるかよく分からないので、anken1-dbのyamファイルでexposeを80にして試してみました。

そうすればupstreamの172.18.0.5:80;に対して、待ち受けているportが80で辻褄はあるはずなのでこれで疎通確認するも疎通ができない状態です。

anken1の方は、3000でexposeしているのに、local.anken1.jp:3000じゃなくてlocal.anken1.jpでアクセスできるので
同じ考え方でanken1-dbの方も、3306でexposeしたら

upstream local.db.anken1.jp { ## Can be connected with "container_network" network # anken1-db server 172.18.0.5:3306; }

になるんじゃないか?と思いましたが何故か

upstream local.db.anken1.jp { ## Can be connected with "container_network" network # anken1-db server 172.18.0.5:80; }

になっているようです。

私の知見では今ある解決法としては以下の2つです。

  • portを分けて管理する
  • anken1db-containerやanken2db-containerなどと案件毎にDBを持たずに、ローカル開発環境としてはcommom.db-containerなどとして全ての案件のDBを一元化するような運用にする

どっちも逃げ案になるので、やはり複数のDBコンテナを同時に立てながらも3306で受けるようにしたいです...
どう解決するのが良いでしょうか...

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

surface_0

2021/11/18 09:03

ちょっと長文なので、ちゃんと汲み取れていないかもしれませんが、まず要件を確認させてください。 質問の要点をまとめるとこういうことでしょうか? --- DBサーバーを含むdocker-composeスタックを同時に複数立ち上げたときに、 外部のクライアントからDBにアクセスする為の公開ポートが被ってしまうので避けたいが、 ポート番号を分けたくないので、できればバーチャルドメインを使って切り替えられないか? --- 推察ですが、ポートを分けたくない理由としては、今後案件が増えるたびに空きポートを管理するのが面倒になるから。 といった感じでしょうか?
surface_0

2021/11/18 09:12

目的はMySQLへのアクセスだと思いますが、対してnginx-proxyはHTTPのリバースプロキシであり、 プロトコルに互換性が無いと思うのですが、それについては把握されていますでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問