I try docker. I write configuration for compose, and separate dockerfiles.
All services work good, but my frontend app doesnt display styles, console not have errors, style css load success. I dont have idea what is it
Dockerfile for nginx and react
FROM node:16.13.1 as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY ./client .
RUN npm install
RUN npm install react-scripts#3.4.1 -g --silent
RUN npm run build
FROM nginx
COPY --from=build /app/build /var/www/client
COPY nginx/nginx.conf /etc/nginx/
EXPOSE 80
nginx.conf, i think trouble here, but what exactly i dont know
events {
worker_connections 1024;
}
http{
server{
listen 80;
location / {
root /var/www/client;
try_files $uri $uri/ /index.html ;
}
location /api {
rewrite ^/api/?(.*) /$1 break;
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_pass http://deliverycx_backend:5000;
}
}
}
and docker compose
version: "3.9"
networks:
mongodb_net:
driver: bridge
services:
deliverycx_client:
container_name: deliverycx_client
build:
context: .
dockerfile: ./Dockerfile.webserver
ports:
- "80:80"
networks:
- mongodb_net
deliverycx_backend:
container_name: deliverycx_backend
env_file:
- ./server/.production.env
depends_on:
- redis
- mongodb
build:
context: ./server
networks:
- mongodb_net
links:
- redis
ports:
- "5000:5000"
redis:
image: redis
command:
- "redis-server"
- "--loglevel ${REDIS_LOGLEVEL:-warning}"
- "--databases 2"
- "--save 900 1"
- "--save 300 10"
- "--save 60 10000"
volumes:
- ./redis/data:/data
networks:
- mongodb_net
mongodb:
container_name: mongodb
image: mongo
volumes:
- ./mongo/data:/data/db
networks:
- mongodb_net
EDITED: my web server send css files like text\plain, i include mime.types but its not resolve problem
Related
I am trying to setup a complete django react webapp via docker-compose on AWS. I went through a tutorial to create a django backend with database and ssl via nginx-proxy and letsencrypt acme-companion.
Everything works so far, but I struggle to add reactjs code as the frontend. I created a frontend folder with react-code and a Dockerfile to create the static files:
# Dockerfile frontend
FROM node:15.13-alpine as build
WORKDIR /frontend
# add `/app/node_modules/.bin` to $PATH
ENV PATH /frontend/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm ci --silent
COPY . ./
RUN npm run build
# The second stage
# Copy React static files
FROM nginx:stable-alpine
COPY --from=build /frontend/build /usr/share/nginx/html
I tried to change the default file in nginx/vhost.d/default to access static frontend files as default and the django-backend-app via /api:
# nginx/vhost.d/default
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
try_files $uri #proxy_api;
}
location /admin {
try_files $uri #proxy_api;
}
location #proxy_api {
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Url-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://backend:8000;
}
location /django_static/ {
autoindex on;
alias /app/backend/server/django_static/;
}
}
Here is the docker-compose file:
# docker-compose.yml
version: '3.8'
services:
backend:
platform: linux/amd64
build:
context: ./django
dockerfile: Dockerfile.prod
logging:
driver: "awslogs"
options:
awslogs-region: "eu-central-1"
awslogs-group: "acquirepad_nginx_proxy"
awslogs-stream: "web"
image: "${BACKEND_IMAGE}"
command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --log-level=debug
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- ./.env
frontend:
build:
context: ./frontend
volumes:
- react_build:/frontend/build
nginx-proxy:
container_name: nginx-proxy
build: nginx
logging:
driver: "awslogs"
options:
awslogs-region: "eu-central-1"
awslogs-group: "acquirepad_nginx_proxy"
awslogs-stream: "nginx-proxy"
image: "${NGINX_IMAGE}"
restart: always
ports:
- 443:443
- 80:80
volumes:
- react_build:/var/www/frontend
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- /var/run/docker.sock:/tmp/docker.sock:ro
depends_on:
- frontend
- backend
nginx-proxy-letsencrypt:
platform: linux/amd64
logging:
driver: "awslogs"
options:
awslogs-region: "eu-central-1"
awslogs-group: "acquirepad_nginx_proxy"
awslogs-stream: "nginx-proxy-letsencrypt"
image: nginxproxy/acme-companion
env_file:
- ./.env.staging.proxy-companion
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- acme:/etc/acme.sh
depends_on:
- nginx-proxy
volumes:
static_volume:
media_volume:
certs:
html:
vhost:
acme:
react_build:
When I run docker-compose on the AWS-EC2 instance, the django backend is still displayed by default on the website and I can not get access to the frontend. I have the feeling, that the file /nginx/vhost.d/default does not have any influence on the webapp at all. Help is much appreciated.
I'm configuring a React application to work with NGINX and docker-compose - I'm getting either 502 Bad Gateway or 504 Timeout errors on NGINX
My docker compose file:
frontend:
build:
context: ../../
restart: always
volumes:
- '../../:/app'
- '/app/node_modules'
ports:
- "3000:3000"
depends_on:
- "backend"
environment:
- CHOKIDAR_USEPOLLING=true
stdin_open: true
tty: true
nginx:
build:
context: ../../nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- volume1:/usr/share/nginx/html
links:
- "backend"
- "db"
My docker file for NGINX:
FROM nginx:latest
COPY . /usr/share/nginx/html
COPY nginx.conf /etc/nginx/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
My nginx.conf file:
events{
}
http{
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
proxy_pass http://frontend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
}
If I navigate to localhost I have in the console:
lightchan-nginx-1 | 2022/03/15 19:25:58 [error]
32#32: *8 connect() failed (111: Connection refused)
while connecting to upstream,
client: 172.26.0.1, server: localhost, request:
"GET / HTTP/1.1", upstream: "http://23.221.222.250:3000/", host: "localhost"
Which tells me that nginx is seeing the upstream (ie the internal ip address that docker-compose is using) from http://frontend. But I don't know why the connection is refused. Any ideas?
EDIT: Someone suggested in another thread to replace
# proxy_set_header Connection 'upgrade';
proxy_set_header Connection "";
Which seemingly just turns off websockets. I don't know why that should have any affect, but that hasn't worked either.
I needed
nginx:
build:
context: ../../nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- volume1:/usr/share/nginx/html
links:
- "backend"
- "db"
- "frontend" <-- this line.
Thanks to David Maze for the 'hint'.
I want to make a project that uses spring boot as a backend and React as a frontend.
In the spring boot,
#GetMapping("/home")
I'll use that.
In React,
axios({
url: '/home',
method: 'GET'
}).then((res) => {
callback(res.data);
})
It was confirmed that the data was received by running it as 'npm start'.
However, there was a problem with using a docker.
When I returned using curl on Spring Boot, the result came out well.
React did not work properly. (Proxy setup is also completed.)
So Nginx and React were used together.
However, it did not work well.
Is it right to use Nginx when connecting Spring Boot and React?
I'd really appreciate it if you could tell me the architecture how to connect.
The architecture necessarily hopes for a spring boot of the back end and a react of the front using a docker.
However, if there is a better design, it is also good.
Perhaps, the proxy setting may be wrong? (Error does not appear and the value is blank.)
I added code.
Front/Dockerfile
FROM node:12-alpine
RUN mkdir /app
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /app/package.json
RUN npm install —no-cache
RUN npm install -g react-scripts
RUN npm install -g react-router-dom
RUN apk add —no-cache git
COPY . /app
CMD ["npm", "start"]
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream docker-nginx {
server client:3000;
}
server {
listen 80;
server_name localhost;
location /sockjs-node {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://docker-nginx;
}
location / {
proxy_pass http://docker-nginx;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
front/docker-compose.yml
version: '3.3'
services:
web:
image: nginx:latest
container_name: web
restart: "on-failure"
ports:
- 80:80
volumes:
- ./web/nginx.conf:/etc/nginx/nginx.conf
client:
build:
context: ./client
container_name: client
restart: "on-failure"
expose:
- 3000
volumes:
- './client:/app'
- '/app/node_modules'
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
stdin_open: true
tty: true
networks:
- clonet_network
restart: always
networks:
clonet_network:
external: true
back/docker-compose.yml
version: '3'
services:
home:
build:
context: .
dockerfile: ./Home/Dockerfile
args:
JAR_FILE: ./Home/build/libs/*.jar
container_name: home_con
volumes:
- ./Home:/app
ports:
- 2004:8080
networks:
- clonet_network
restart: always
networks:
clonet_network:
external: true
I added this it in nginx.conf
location /home {
proxy_pass http://localhost:2004;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
localhost:80/home says '502 Bad Gateway'.
I'm new to web development, and I run into a strange error.
I have a React/Django app which I'm trying to productionize with nginx and docker.
Django runs on a postgres db, and nginx just reroutes port 80 to my react and django ports.
When I locally deploy the application using
npm run build
serve -s build
everything works as desired.
However, doing the same through Docker doesn't.
I have a Dockerfile building the react application:
FROM node:12.18.3-alpine3.9 as builder
WORKDIR /usr/src/app
COPY ./react-app/package.json .
RUN apk add --no-cache --virtual .gyp \
python \
make \
g++ \
&& npm install \
&& apk del .gyp
COPY ./react-app .
RUN npm run build
FROM node:12.18.3-alpine3.9
WORKDIR /usr/src/app
RUN npm install -g serve
COPY --from=builder /usr/src/app/build ./build
Now when I use
docker-compose build
docker-compose up
I see that my Django, React, Postgres and nginx containers are all running, with nginx visible at port 80. When I open localhost in my browser, I see nginx is looking for some static react files in the right directory. However, the react files it is looking for have a different hash than the static files. The static files of both the nginx and react container are the same. So somehow, my asset-manifest.json contains the wrong filenames. Any idea what causes this is or how I can solve this?
Edit: Added docker-compose.yml:
version: "3.7"
services:
django:
build:
context: ./backend
dockerfile: Dockerfile
volumes:
- django_static_volume:/usr/src/app/static
expose:
- 8000
env_file:
- ./backend/.env
command: gunicorn core.wsgi:application --bind 0.0.0.0:8000
depends_on:
- db
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./postgres/.env
react:
build:
context: ./frontend
dockerfile: Dockerfile
volumes:
- react_static_volume:/usr/src/app/build/static
expose:
- 5000
env_file:
- .env
command: serve -s build
depends_on:
- django
nginx:
restart: always
build: ./nginx
volumes:
- django_static_volume:/usr/src/app/django_files/static
- react_static_volume:/usr/src/app/react_files/static
ports:
- 80:80
depends_on:
- react
volumes:
postgres_data:
django_static_volume:
react_static_volume:
Do you need to run React in a separate container? Is there any reason for doing this? (It might be)
In my approach, I'm building React static files in nginx Dockerfile, and copy them to /usr/share/nginx/html. Then nginx serves it at location /.
nginx Dockerfile
# The first stage
# Build React static files
FROM node:13.12.0-alpine as build
WORKDIR /app/frontend
COPY ./frontend/package.json ./
COPY ./frontend/package-lock.json ./
RUN npm ci --silent
COPY ./frontend/ ./
RUN npm run build
# The second stage
# Copy React static files and start nginx
FROM nginx:stable-alpine
COPY --from=build /app/frontend/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
nginx configuration file
server {
listen 80;
server_name _;
server_tokens off;
client_max_body_size 20M;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
try_files $uri #proxy_api;
}
location /admin {
try_files $uri #proxy_api;
}
location #proxy_api {
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Url-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://backend:8000;
}
location /django_static/ {
autoindex on;
alias /app/backend/server/django_static/;
}
}
Docker-compose
version: '2'
services:
nginx:
restart: unless-stopped
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
ports:
- 80:80
volumes:
- static_volume:/app/backend/server/django_static
- ./docker/nginx/development:/etc/nginx/conf.d
depends_on:
- backend
backend:
restart: unless-stopped
build:
context: .
dockerfile: ./docker/backend/Dockerfile
volumes:
entrypoint: /app/docker/backend/wsgi-entrypoint.sh
volumes:
- static_volume:/app/backend/server/django_static
expose:
- 8000
volumes:
static_volume: {}
Please check my article
Docker-Compose for Django and React with Nginx reverse-proxy and Let's encrypt certificate for more details. There is also example of how to issue Let's encrypt certificate and renew it in docker-compose. If you will need more help, please let me know.
I am trying to dockerize my React app with Go API and I faced with the following error.
Proxy error: Could not proxy request /api/todos from localhost:3000 to http://localhost:8080.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
So I found this on google that I need to add those lines in to my package.json
"proxy": "http://localhost:8080","secure": false,
I have tried couple of other alternatives around above solution but didn't work out as well.
If I start my Go API in the container and if I start my React app from console with npm start, It does work. But If I try to compose them that is not working.
Any advice appreciated!
My docker-compose.yml;
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
react:
build: frontend
restart: always
tty: true
ports:
- "8080:3000"
Here is my backend docker;
FROM golang:latest
RUN mkdir /app
ADD . /app
WORKDIR /app
COPY main.go .
RUN go get -v -u github.com/gorilla/mux
RUN go build main.go
CMD ["/app/main"]
And the my frontend docker;
FROM node:14
RUN mkdir /app
ADD . /app
WORKDIR /app
COPY /package*.json /app
RUN npm install
COPY . /app
EXPOSE 3000
CMD ["npm","start"]
I think the error is the docker-compose port mapping
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
react:
build: frontend
restart: always
tty: true
ports:
- "3000:3000"
this property in package.json
"proxy": "http://localhost:8080"
works in developement mode, not in production
Answer to proxy react request to backend
To proxy your request i think you shoud use another strategy
create a front-end server that implements the proxy (here an example) https://gist.github.com/saniaky/3a5e68acc2b1ee69ed49b6a3eaee094a
OR
add another container with nginx as reverse proxy (here an article that explain something similar to your case https://medium.com/#frontendfoo/docker-react-express-reverse-proxy-15d7b37f8dc2)
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
react:
build: frontend
restart: always
tty: true
ports:
- "3000:3000"
revproxy:
build: ../docker-reverseProxy
image: "reverseproxy:1.0.0"
ports:
- "80:80"
server {
listen 80;
location /api {
proxy_pass http://backend/;
proxy_redirect off;
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-Host $server_name;
}
location / {
proxy_pass http://frontend;
proxy_redirect off;
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-Host $server_name;
}
}
with reverse proxy you can map a request to a specific path (/api as example) to another server (your server exposed on :8080).
With the above configuration with docker compose you will expose your front on path / (:80) and your back on /api (:80)
UPDATE
I try the solution that i suggest in my last comment, the correct proxy configuration shoud be this (considerig the first strategy that i suggest)
....
api: {
target: 'http://go',
pathRewrite: {
'^/api': '/',
},
},
....
In this way the internal routing of docker compose will be routed to the container called "go" (the name that you assign in your docker compose)
When you make a request to http://localhost:8080/ from inside your react container, your system checks if it can resolve that URI.
The issue is that the only thing that is accessible from inside react is port 3000. There is nothing on the localhost of react on port 8080.
However, the service go is accessible on the address http://localhost:8080/ from the host's machine.
Docker uses its own DNS for containers, and you have to be aware of how this works.
To solve the issue, add a network to react and go containers on your docker-compose.yml file:
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
networks:
- some_network
react:
build: frontend
restart: always
tty: true
ports:
- "3000:3000"
networks:
- some_network
networks:
some_network:
Now that your containers can communicate, change the proxy in the package.json file to:
"proxy": "http://go:8080"
This will direct the traffic to the go container on port 8080, as Docker will look up the domain called go on its embedded DNS server.