Развертывание контейнеризированного приложения Reat Django с помощью nginx
У меня есть приложение: клиент в react. сервер на django.
приложение является контейнерным:
backend-container
и frontend-container
следующим образом (docker-compose.yaml
):
version: '3.8'
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile
args:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_HOST: ${POSTGRES_HOST}
SECRET_KEY: ${SECRET_KEY}
DEBUG: ${DEBUG}
CORS_ALLOWED_ORIGIN: ${CORS_ALLOWED_ORIGIN}
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
image: backend
container_name: backend-container
ports:
- "8000:8000"
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_HOST: ${POSTGRES_HOST}
SECRET_KEY: ${SECRET_KEY}
DEBUG: ${DEBUG}
CORS_ALLOWED_ORIGIN: ${CORS_ALLOWED_ORIGIN}
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
args:
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
image: frontend
container_name: frontend-container
ports:
- "3000:3000"
environment:
NODE_ENV: production
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
и приложение размещено на экземпляре EC2, развернуто с помощью действия github: name: My workflow
on: workflow_dispatch
jobs:
first-job:
runs-on: self-hosted
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build the Docker backend image
env:
POSTGRES_USER: ${{ secrets.POSTGRES_USER }}
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
POSTGRES_HOST: ${{ secrets.POSTGRES_HOST }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
DEBUG: ${{ secrets.DEBUG }}
CORS_ALLOWED_ORIGIN: ${{ secrets.CORS_ALLOWED_ORIGIN }}
REACT_APP_ALLOWED_HOST: ${{ secrets.REACT_APP_ALLOWED_HOST }}
run: |
sudo docker-compose -p fullstack down
sudo POSTGRES_USER=$POSTGRES_USER POSTGRES_PASSWORD=$POSTGRES_PASSWORD POSTGRES_HOST=$POSTGRES_HOST SECRET_KEY=$SECRET_KEY DEBUG=$DEBUG CORS_ALLOWED_ORIGIN=$CORS_ALLOWED_ORIGIN REACT_APP_ALLOWED_HOST=$REACT_APP_ALLOWED_HOST docker-compose -p fullstack up --build -d
Я вижу, что контейнеры запущены на моем экземпляре EC2.
Я настроил nginx на экземпляре EC2:
server {
listen 80;
server_name _;
location / {
proxy_pass http://172.20.0.3:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
}
}
172.20.0.3
- это адрес локальной сети моего frontend-container
.
мое react-приложение в настоящее время пытается обратиться из кода к моему backend-контейнеру через backend:8000 (backend - это имя сервиса в моем docker-compose) следующим образом:
const App = () => {
const [books, setBooks] = useState([]);
useEffect(() => {
fetch(http://${process.env.REACT_APP_ALLOWED_HOST}:8000/demoapp/allBooks)
.then(response => response.json())
.then(data => setBooks(data.books)) // Access the 'books' property of the response
.catch(error => console.error('Error fetching data:', error));
}, []);
...
мой api запрос http://backend:8000/demoapp/allBooks
не проходит таким образом.
Возможно, я что-то упустил в конфигурации nginx, и я не знаю, что именно.
ah ok Я думал, что вы хотите использовать прокси nginx для обслуживания обоих контейнеров, но вы просто хотите, чтобы react fe и django были в общении. так что для того, чтобы это работало, я думаю, что вам не хватает сетевого блока в docker compose. Если два контейнера не находятся в одной сети docker, они не могут взаимодействовать. Поэтому вы можете изменить docker compose следующим образом и провести тест:
version: '3.8'
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile
args:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_HOST: ${POSTGRES_HOST}
SECRET_KEY: ${SECRET_KEY}
DEBUG: ${DEBUG}
CORS_ALLOWED_ORIGIN: ${CORS_ALLOWED_ORIGIN}
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
image: backend
container_name: backend-container
ports:
- "8000:8000"
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_HOST: ${POSTGRES_HOST}
SECRET_KEY: ${SECRET_KEY}
DEBUG: ${DEBUG}
CORS_ALLOWED_ORIGIN: ${CORS_ALLOWED_ORIGIN}
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
networks:
- my-network
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
args:
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
image: frontend
container_name: frontend-container
ports:
- "3000:3000"
environment:
NODE_ENV: production
REACT_APP_ALLOWED_HOST: ${REACT_APP_ALLOWED_HOST}
networks:
- my-network
networks:
my-network:
driver: bridge
попробуйте добавить что-то вроде этого в конфигурацию nignx:
server {
listen 80;
server_name your.domain.com;
location / {
# Forward requests to the frontend
proxy_pass http://172.20.0.3:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
# Forward API requests to the backend
proxy_pass http://backend-container:8000; # Use container name for internal Docker communication
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- обязательно проверьте хосты для обоих контейнеров .