サンプルリポジトリ
記事で紹介した内容をリポジトリにあげてあります。よろしければ参考にしてください。
nginx イメージを使う
たったこれだけでカレントディレクトリのpublicフォルダを公開するウェブサーバーを建てられます。
$ docker run -d -p 8080:80 -v $PWD/public:/usr/share/nginx/html:ro nginx
しかし、単にサーバーを立てるだけならわざわざ docker を使わずにもっと短くできます((python -m http.server 8080 ./public
で代用できます))。せっかく Nginx を使うのですから、設定ファイルを使いたいですよね。設定ファイルをマウントするには次のようにします。
$ docker run -d -p 8080:80 -v $PWD/public:/usr/share/nginx/html:ro \ -v $PWD/nginx.conf:/etc/nginx/nginx.conf:ro \ -v $PWD/conf.d:/etc/nginx/conf.d:ro nginx
しかし、これだけでは立ち上がる Nginx の prefix が /etc/nginx
になってしまうので、prefix を /usr/share/nginx
にして起動します。
$ docker run -d -p 8080:80 -v $PWD/public:/usr/share/nginx/html:ro \ -v $PWD/nginx.conf:/etc/nginx/nginx.conf:ro \ -v $PWD/conf.d:/etc/nginx/conf.d:ro nginx nginx -p /usr/share/nginx -g 'daemon off;'
さらに --restart=always
を付ければ再起動後も自動で立ち上がるようになります。
docker-compose を使う
上のコマンドを docker-compose.yml で書くと次のようになります。
version: '3' services: web: image: nginx:alpine ports: - 8080:80 volumes: - ./public:/usr/share/nginx/html:ro - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./conf.d:/etc/nginx/conf.d:ro command: nginx -p /usr/share/nginx -g 'daemon off;'
これなら restart: always
をつけることで再起動後も自動で立ち上がるようにできます。
あとは docker-compose.yml と同階層でdocker-compose up -d
を実行するとサーバーが立ち上がります。
リバースプロキシ
ネットワークをたててその中で完結させたい場合は以下のようにすると簡潔です。
$ docker create network -d bridge my-network $ docker run -d -p 8080:80 -v $PWD/public:/usr/share/nginx/html:ro \ --net my-network \ -v $PWD/nginx.conf:/etc/nginx/nginx.conf:ro \ -v $PWD/conf.d:/etc/nginx/conf.d:ro nginx \ nginx -p /usr/share/nginx -g 'daemon off;'
docker-compose.yml を使うと以下になります。
version: '3' services: web: image: nginx:alpine ports: - 8080:80 volumes: - ./public:/usr/share/nginx/html:ro - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./conf.d:/etc/nginx/conf.d:ro command: nginx -p /usr/share/nginx -g 'daemon off;' networks: default: external: name: my-network
external で指定してあるのは、このコンテナでネットワークを立ててしまうと、このコンテナを起点に依存関係ができてしまうためです。ネットワークを作るかわりに external で既存のネットワークを使えば、このコンテナは他のコンテナの起動状況に関わらず立ち上げることができます。また、他のコンテナもこのコンテナの起動状況に依存せずに済みます。
他のコンテナは、外部とはこのリバースプロキシを介して通信できるので、ports
の代わりにexpose
でポートをネットワーク内に公開するだけで良いです。