前回、AWS ElasticBeansTalk で試作したNode.js開発環境をDockerを使ってローカルにポーティングしましたが今回は再びAWS EC2にリフトアンドシフトしてみました。RedisとS3互換ストレージサーバーMinIOの接続が拒否される原因がなんとなく分かったのでメモします。
Dockerを使えばローカルもAWSもほとんどシームレスに環境の移行ができました
VPC | 172.31.0.0/16 |
VPCサブネット | 172.31.0.0/20 |
インスタンスIP(ローカル) | 172.31.15.141 |
Docker ブリッジネットワーク | 172.18.0.0/24 |
DockerブリッジGW | 172.18.0.1 |
dnsmasq | 172.18.0.2 |
MySQL5.7 | 172.18.0.3 |
Redis | 172.18.0.4 |
Node.jsアプリ | 172.18.0.5 |
MinIOクライアント(mc) | 172.18.0.6 |
MinIO(S3) | 172.18.0.10 |
https-portal | 172.18.0.100 |
これは関係ないかもしれませんがEC2にはデフォルトで入っていないNetworkManagerをインストールしてみました。
MySQLデータベースとMinIO(S3)バケットを作成してMCクライアントから管理者アカウントを作成してNode.js サンプルを docker buildしましたがポート3000でLISTENしているアプリをリバースプロキシするhttps-portal で認証エラーが出るようでした。
これはインスタンスIPのネットワークであるeth0をDockerのネットワーク(172.31.15.0/24)として使っていたため起こるDNSエラーでした。
ip -4 a | grep inet でネットワークを確認します。
$ ip -4 a | grep inet inet 127.0.0.1/8 scope host lo
inet 172.31.15.141/20 brd 172.31.15.255 scope global dynamic eth0
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
inet 172.18.0.1/24 brd 172.18.0.255 scope global global br-206fc282aa57
ですので今回はブリッジインターフェイスのネットワーク(172.18.0.0/24)を使うとDNSがいい感じに解決してくれました。
一方で確かにhttps-portal で3000でLISTENしているアプリがブラウザ上から表示されるのですがRedis, S3コンテナへの接続ができずアップロードした画像が表示されないようでした。
その点を踏まえつつRedis, S3コンテナも https-portal のDOMAIN設定で複数サービスをリバースプロキシすると良いようでした。docker-compose.yml は最終的には以下になりました。
vi docker-compose.yml
version: '3' services: mysql: image: mysql:5.7 container_name: mysql ports: - "3306:3306" environment: - MYSQL_USER=sampleUser - MYSQL_PASSWORD=samplePass - MYSQL_DATABASE=sampleDb - MYSQL_ROOT_PASSWORD=rootpass networks: td000net1: ipv4_address: 172.18.0.3 restart: always volumes: - db-data:/var/lib/mysql redis: image: redis:latest container_name: redis ports: - "6379:6379" networks: td000net1: ipv4_address: 172.18.0.4 s3: image: minio/minio:latest container_name: s3 ports: - "9000:9000" - "9001:9001" networks: td000net1: ipv4_address: 172.18.0.10 restart: always volumes: - "s3-data:/data" - "s3-config-data:/root/.minio" command: "server /data --console-address :9001" env_file: - .env environment: - MINIO_ROOT_USER=${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} - MINIO_SERVER_URL=http://172.18.0.10:9000 application: image: sample_todos:1.0 hostname: appapi.live container_name: application extra_hosts: - "appapi.live:54.249.5.106" ports: - "3000:3000" networks: td000net1: ipv4_address: 172.18.0.5 restart: always init: true env_file: - .env environment: - MYSQL_HOST=mysql - MYSQL_PORT=3306 - MYSQL_USER=sampleUser - MYSQL_PASS=samplePass - MYSQL_DB=sampleDb - AWS_ACCESS_KEY=${AWS_ACCESS_KEY} - AWS_SECRET_KEY=${AWS_SECRET_KEY} - MINIO_ROOT_USER=${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} - AWS_REGION=ap-northeast-1 - AWS_DEFAULT_OUTPUT=json - AWS_ENDPOINT=http://172.18.0.10 - AWS_PORT=9000 - AWS_S3_BUCKET=docker-local-sample-bucket - IMAGE_ENDPOINT=http://appapi.live:9000 - REDIS_HOST=172.18.0.4 - REDIS_PORT=6379 volumes: - ".:/app" - "/app/node_modules" depends_on: - mysql - redis - s3 mc: image: minio/mc:latest container_name: mc depends_on: - s3 entrypoint: /bin/sh networks: td000net1: ipv4_address: 172.18.0.6 stdin_open: true tty: true dnsmasq: restart: always image: 4km3/dnsmasq container_name: dnsmasq environment: TZ: "Asia/Tokyo" ports: - "53:53/udp" - "53:53/tcp" volumes: - './PV/etc/dnsmasq.d:/etc/dnsmasq.d' networks: td000net1: ipv4_address: 172.18.0.2 dns: - 8.8.8.8 - 127.0.0.1 cap_add: - NET_ADMIN https-portal: image: steveltn/https-portal:1 container_name: https-portal extra_hosts: - 'appapi.live:127.0.0.1' ports: - '80:80' - '443:443' links: - application - s3 - redis networks: td000net1: ipv4_address: 172.18.0.100 restart: always volumes: - ./certs:/var/lib/https-portal - /var/run/docker.sock:/var/run/docker.sock:ro environment: DOMAINS: 'appapi.live -> http://application:3000, appapi.live -> http://s3:9000, appapi.live -> http://redis:6379' CLIENT_MAX_BODY_SIZE: 100M STAGE: 'production' # FORCE_RENEW: 'true' volumes: db-data: s3-data: s3-config-data: networks: td000net1: ipam: driver: default config: - subnet: 172.18.0.0/24 gateway: 172.18.0.1
運用にあたっては S3, MySQLコンテナを docker-compose down する前にイメージをその都度 docker commit すると吉です。
最後までお読みいただきありがとうございました。