Dockerでサーバー構築する際のポート指定で気をつけること
Docker で社内向けのWebアプリをホストするサーバーを構築しようと考えていて、ひとまず Vagrant 上で色々と試していたのですが、これまで Docker はローカルの開発用環境にしか使っていなかったので、今まであまり気にしてなかったり知らなかったことをちょっとまとめてみます。
ほぼほぼ、dockerとufwの設定が独立なせいで無駄にポートが開いてしまう件と、解決するためのdocker runオプションの記法について #Docker – Qiita でまとめられている内容ですが。
- Dockerコンテナ間だけで共有したいポートは expose を使う
- 自分と同じように Docker はローカルの開発用環境で使う前提のサンプルコードなど、ポートの共有はほぼほぼ ports になっている場合が多いですが、ports だとホストOSへポートフォワードして、結果外部にも公開されます。なので、Dockerコンテナ間だけで共有したいポートは expose で指定します。
- 外部に共有したいけど対象がホストOSだけの場合、ports を使って IPアドレスで限定する
例えば、Redmine コンテナを立ち上げるとして、
- 3000ポートをホストOSのみに公開、外部には開放しない
- 3306ポートはDockerコンテナ間だけに開放、ホストOSからもアクセス不可
といった設定だと、以下のような docker-compose.yml の記述になります。
version: '3.1' services: app: image: redmine:5.1.2 restart: always ports: - "127.0.0.1:3000:3000" environment: REDMINE_DB_MYSQL: db REDMINE_DB_USERNAME: redmine REDMINE_DB_PASSWORD: redmine REDMINE_DB_DATABASE: redmine REDMINE_PLUGINS_MIGRATE: 1 REDMINE_SECRET_KEY_BASE: supersecretkey db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: redmine MYSQL_USER: redmine MYSQL_PASSWORD: redmine MYSQL_RANDOM_ROOT_PASSWORD: 1 volumes: - ./mysql:/var/lib/mysql expose: - 3306
この辺り、事前に調べてたり、もともと知ってたりしてないと第一感で「ufw でポートを塞げば良いんじゃね?」って思って設定するも、公開されっぱなしで「え…?」ってなりがちですが、前に上げた dockerとufwの設定が独立なせいで無駄にポートが開いてしまう件と、解決するためのdocker runオプションの記法について #Docker – Qiita でも触れられてる通り、ufw の設定は効きません。これ、結構罠ですよね。