У меня есть проект MERN, настроенный с помощью Docker.Среда разработки в порядке;у меня проблемы с производством.
Мне нужно такое поведение:
- В разработке:
- Это состояние контейнеров:
- Nodemon запускается в контейнере экспресс-образа узла (от узла: alpine) с портом 9000 , открытым для хоста.(это backend / api)
- MongoDB работает в своем собственном контейнере на основе официального образа с портом 27017 , открытым для хоста.(это база данных)
- React запускается с горячей перезагрузкой в своем контейнере образа (из узла: alpine) с портом 3000 , открытым для хоста.(это внешний интерфейс)
- В производстве:
- Это состояние контейнеров:
- Узел работает вКонтейнер экспресс-изображения узла (из узла: alpine) с без портов , открытый для хоста.
- MongoDB работает в своем собственном контейнере на основе официального образа с без портов открыт для хоста.
- React запускается в своем образе (из nginx: alpine) контейнера с портом 80 , открытым для хоста.
Бэкэнд / api ссылается на базу данных, используя имя контейнера, а контейнер внешнего интерфейса / реагирует на бэкэнд, используя имя контейнера.
Я положил proxy: localhost:9000
вреагировать package.json файл.В производственном процессе я поместил в файл nginx.conf следующее.
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
}
location /api {
proxy_pass http://localhost:9000;
}
В производственном файле docker-compose.yml я удалил expose: "9000"
и ports: "9000:9000"
, которые былиприсутствует в файле docker-compose.yml.Я запускаю docker-compose -f docker-compose.yml -f docker-compose.production.yml up
.
Моя проблема заключается в том, что порты "localhost: 9000" и "localhost: 27017" по какой-то причине все еще работают.Я хочу, чтобы все маршруты, кроме "example.com/api", проходили через React.Только «example.com/api» должен идти непосредственно к бэкэнду.
Кроме того, я не уверен, что это связано, но есть ли способ убедиться, что «example.com/api» идет кбэкэнд без необходимости делать require("express")().get('/api'...
?Например, просто выполнение require("express")().get('/'...
по умолчанию принимает вызовы "example.com/api".
Примечание. Я использовал сети, а не ссылки, чтобы соединять контейнеры.Backend подключен как к React, так и к MongoDB, а React и MongoDB не подключены друг к другу.
Вот мой docker-compose.yml:
version: "3.7"
services:
##############################
# Back-End Container
##############################
backend:
container_name: backend
build:
context: ./backend/
target: development
restart: always
expose:
- "9000"
environment:
- MONGO_URI=mongodb://db:27017/db
- PORT=9000
- NODE_ENV=development
- DEBUG=app
- JWT_SECRET=secretsecret
- JWT_EXPIRY=30d
ports:
- "9000:9000"
- "9229:9229"
volumes:
- "./backend/:/home/node/app/"
- /home/node/app/node_modules/
depends_on:
- db
networks:
- client
- server
##############################
# Front-End Container
##############################
frontend:
container_name: frontend
build:
context: ./frontend/
target: development
restart: always
expose:
- "3000"
- "35729"
environment:
- NODE_ENV=development
- REACT_APP_PORT=3000
- CHOKIDAR_USEPOLLING=true
ports:
- "3000:3000"
- "35729:35729"
volumes:
- "./frontend/:/home/node/app/"
- /home/node/app/node_modules/
networks:
- client
##############################
# MongoDB Container
##############################
db:
container_name: db
image: mongo
restart: always
volumes:
- dbdata:/data/db/
ports:
- "27017:27017"
networks:
- server
networks:
client:
server:
volumes:
dbdata:
Вот мойФайл .env
MONGO_URI=db:27017/somedb?authSource=admin
PORT=9000
MONGO_PORT=27017
MONGO_INITDB_ROOT_USERNAME=mongoadmin
MONGO_INITDB_ROOT_PASSWORD=secret
MONGO_INITDB_DATABASE=somedb
NODE_ENV=production
Вот мой docker.compose.production.yml:
version: "3.7"
services:
##############################
# Back-End Container
##############################
backend:
container_name: backend
init: true
environment:
- MONGO_URI=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_URI}
- PORT=${PORT}
- NODE_ENV=${NODE_ENV}
build:
context: ./backend/
target: production
restart: always
depends_on:
- db
networks:
- client
- server
##############################
# Front-End Container
##############################
frontend:
container_name: frontend
build:
context: ./frontend/
target: production
restart: always
environment:
- NODE_ENV=${NODE_ENV}
expose:
- "80"
ports:
- "80:80"
networks:
- client
##############################
# MongoDB Container
##############################
db:
container_name: db
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
volumes:
- dbdata:/data/db/
ports:
- "27017:27017"
networks:
- server
networks:
client:
server:
volumes:
dbdata:
Файлы Docker имеют только FROM, WORKDIR, RUN, COPY и CMD.