docker-composeでportsとexposeの使い分けを整理します.
exposeはホストからアクセスできないポートですが,portsはホストからアクセスできるポートです.*1
例えば,port 5432にpostgres データベースを起動し,djangoを使ってサーバーを作り,ブラウザーからアクセスするという開発環境を考えます.
version: '3'
services:
postgres:
image: postgres:11-alpine
expose:
- "5432"
django:
image: django-web:latest
command: ash -c "
python3 manage.py migrate &&
python3 manage.py runserver 0.0.0.0:8000"
ports:
- "8000:8000"
postgresはdjangoからアクセスできればよいので,exposeを使用します.
djangoはホストのブラウザーからアクセスするので,portsを使用します.
ホストのポートを指定するのは必要がなければ,docker-composeに一任するのがよいです.例えば,ports: "5432:5432" と指定してpostgresを起動すると,複数のpostgresを使いたい時に,ポートで競合してエラーとなります.
Bind for 0.0.0.0:5432 failed: port is already allocated.
指定しなければdocker-composeが自動的に空いているアドレスやポートを設定してくれるので,便利です.