I am trying to use docker for MERN project. I have created Dockerfile in both client and server, and docker-compose.yml in root folder.
I executed code docker-compose build. It executed without any error. Then I run docker-compose up, node and mongodb run successfully but react js is exited with code 0.
Dockerfile for client
# build environment
FROM node:12.18.2-alpine
RUN mkdir -p /opt/app/ps-client
WORKDIR /opt/app/ps-client
# install app dependencies
COPY package.json .
# COPY package-lock.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "run", "start"]
docker-compose.yml
version: "3.8" # specify docker-compose version
# Define the services/ containers to be run
services:
back-end: # name of the first service
build: server # specify the directory of the Dockerfile
ports:
- "5000:5000" #specify ports mapping
links:
- database # link this service to the database service
database: # name of the third service
image: mongo # specify image to build container from
ports:
- "27017:27017" # specify port forwarding
front-end: # name of the second service
build: client # specify the directory of the Dockerfile
ports:
- "3000:3000" # specify port mapping
I tried docker-compose --verbose up only for react js, result
docker container inspect b9e429 result of this command is result
Try adding the following options to the front-end service configuration in the docker compose file.
stdin_open: true
tty: true
This should be equivalent to running the container with the -it options.
You can read more about the issue here: https://github.com/facebook/create-react-app/issues/8688
Add tty: true to your front-end service should suffice. The full context of the issue is described at: https://github.com/facebook/create-react-app/issues/8688 as mentioned by Teddy Sterne
Related
Current I am working on a full stack application with a react frontend, mysql DB, and apache php instance. Something seems to be up with my changes going from my docker container to localhost. I can write from my local machine -> docker, but it seems like localhost is not reading react from my docker container.
I know that my mount is working correctly local machine -> docker file system because whenever I make changes in my IDE and save, then go and cat App.js within my docker container, that changes are there.
Any insight would be helpful, I think what is happening is that docker is taking a copy of the file upon creating the container, because whenever I remake the container, my changes to through to localhost.
p.s. I'm newish to docker, so let me know if you need more information. Thanks!
docker-compose
version: "3.7"
services:
frontend:
container_name: frontend
build:
context: "./hartley_react"
dockerfile: Dockerfile
volumes:
- "./hartley_react:/app"
- "/app/node_modules"
ports:
- 3000:3000
stdin_open: true
environment:
- CHOKIDAR_USEPOLLING=true
command: npm start
php:
container_name: php
build:
context: "./dockerfiles/php-img/"
ports:
- "80:80"
volumes:
- ./src:/var/www/html/
db:
container_name: db
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: userdb
MYSQL_USER: my_user
MYSQL_PASSWORD: my_password
volumes:
- ./mysqldata:/var/lib/mysql
adminer:
container_name: adminer
depends_on:
- db
image: adminer
restart: always
ports:
- 8080:8080
volumes:
my-mysqldata:
frontend:
React DockerFile
FROM node:17.4.0-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ "npm", "start" ]
I guess your problem is that npm start do not auto reload if you edit your files. For that you could use nodemon or supervisor which can reload the project each time a file is updated. Otherwise you should restart manually (probably by restarting the docker container)
There are a few things you can try:
check your package.json file and specifically scripts whether start gives npm start with hot reload option or not.
to do so, you may do the full test in your local (without docker) and check whether the changes you are making in html (frontend) is indeed reflecting to your application locally without rebuilding or not.
secondly, create another script inside package.json file (custom script) to have npm run/ npm dev (available in react but not sure for your case) with hot-reload or use nodemon for that.
Once you have that, use that in your docker-compose file in place of CMD [ "npm", "start" ]
For me, It looks like your dockerfile and docker-compose file along with the named volume definition looks ok.
Only one thing though - Not sure why did you mention the "command: npm start" inside docker-compose file while you already have covered that part in your dockerfile while creating an image.
I was dockerising an app of mine but I wanted to access it on port 80 on my machine, every time a change the port in docker-composer.yml it returnes the error:
ERROR: for site Cannot create container for service site: mount denied:
the source path "dcfffb89fd376c0d955b0903e3aae045df32a073a6743c7e44b3214325700576:D:\\projetos\\portfolio\\site\\node_modules:rw"
too many colons
ERROR: Encountered errors while bringing up the project.
Im running on windows
docker-composer.yml
version: '3.7'
services:
site:
container_name: site
build: ./site
volumes:
- 'D:\projetos\portfolio\site'
- 'D:\projetos\portfolio\site\node_modules'
ports:
- 3000:3000
stdin_open: true
environment:
- CHOKIDAR_USEPOLLING=true
- COMPOSE_CONVERT_WINDOWS_PATHS=true
command: npm start
Dockerfile
FROM node:16.13.1-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]
I was using the wrong path pattern, on windows you have to use /c/path/to/volume since the ":" is used inside docker stuff(don't know what), also removed the command COMPOSE_CONVERT_WINDOWS_PATHS=true and worked just fine.
I have a dummy react app deployed from Dockerfile.dev:
FROM node:alpine AS builder
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY . .
RUN npm run build
FROM nginx
EXPOSE 80
COPY --from=builder /app/build /usr/share/nginx/html
which is deployed to elasticbeanstalk right after it is pushed to GitHub using TravisCI:
sudo: required
services:
- docker
before_install:
- docker build -t name/docker-react -f Dockerfile.dev .
script:
- docker run -e CI=true name/docker-react npm run test
deploy:
provider: elasticbeanstalk
region: 'us-east-1'
app: 'docker'
env: 'Docker-env'
bucket_name: 'elasticbeanstalk-us-east-1-709516719664'
bucket_path: 'docker'
on:
branch: main
access_key_id: $AWS_ACCESS_KEY
secret_access_key: $AWS_SECRET_KEY
The app is successfully deploying to EB but displays 502 Bad Gateway as soon as I access it (by clicking the app link in AWS EB). Enhanced health overview reports:
Process default has been unhealthy for 18 hours (Target.FailedHealthChecks).
Docker-env EC2 instance is running and after allowing all incoming connections to it I can connect just fine:
I can build my app using Dockerfile.dev locally with no problems:
docker build -t name/docker-react -f Dockerfile.dev .
=> => naming to docker.io/name/docker-react
docker run -p 3000:3000 name/docker-react
AWS has a hard time with the '.' folder designation and prefers the long form ./
Try to edit the COPY instruction to COPY package*.json ./
And try also to remove the named builder. By default, the stages are not named, and you refer to them by their integer number, starting with 0 for the first FROM instruction.
Your Dockerfile should looks like:
FROM node:alpine
WORKDIR '/app'
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx
EXPOSE 80
COPY --from=0 /app/build /usr/share/nginx/html
You should have a docker-compose.yml, just ensure that you have the right port mapping inside:
Example:
services:
web-service:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "80:3000" # outside:inside container
finally your TravisCI configuration must be edited. secret_acces_key has ONE 'S'
...
access_key_id: $AWS_ACCESS_KEY
secret_acces_key: $AWS_SECRET_KEY
Nginx default port is 80, and AWS only checks docker-compose.yml to manage resources efficiently, just do the right port mapping inside that file
version: '3'
services:
web:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "80:3000"
volumes:
- /app/node_modules
- .:/app
I have 2 docker containers, the front being a React.js app running on ports 3000:3000 and the back being a Flask API running on 5000:5000.
ISSUE:
I am having an issue with these containers wrapped together in docker-compose where the front will be accessible via localhost:3000 as it would normally run outside a container, however it is unable to communicate with the back container. I receive a net::ERR_EMPTY_RESPONSE in browser when attempting to use any API component. How might I be able to resolve this?
SETUP:
My directory for this docker-compose setup is as follows:
/project root
- docker-compose.yml
/react front
- Dockerfile
/app
/flask back
- Dockerfile
/api
My docker-compose.yml is as follows:
version: "3.8"
services:
flask back:
build: ./flask back
command: python main.py run -h 0.0.0.0
volumes:
- ./flask back/:/usr/src/app/
ports:
- 5000:5000
env_file:
- ./flask back/.env
react front:
build: ./react front
volumes:
- ./react front/app:/usr/src/app
- usr/src/app/node_modules
ports:
- 3000:3000
links:
- flask back
The front Dockerfile:
# pull official base image
FROM node:13.12.0-alpine
# set working directory
WORKDIR /usr/src/app
# add `/react front/node_modules/.bin` to $PATH
ENV PATH /react front/node_modules/.bin:$PATH
# install app dependencies
ADD package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts#3.4.1 -g --silent
# start app
CMD ["npm", "start"]
The back Dockerfile:
FROM python:alpine3.7
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt
COPY . /usr/src/app/
TROUBLESHOOTING SO FAR:
So far I have consulted the following threads on SO:
Flask and React Docker containers not communicating via Docker-Compose - where the package.json needed a proxy addition.
ERR_EMPTY_RESPONSE from docker container - where IP addresses needed rewritten to 0.0.0.0 (this appears to be a unique issue to GO as I never used this form of port and IP configuration in my project)
Neither of these very similar issues have resolved my issue. I am also able to ping the back-end container with the front-end and vice versa. Running the React container while running the Flask API outside of its container also works as expected/intended. If there is any other information anyone would like, I would be happy to provide.
Thank you for the time and patience.
I have the following docker-compose file:
version: "3"
services:
scraper-api:
build: ./ATPScraper
volumes:
- ./ATPScraper:/usr/src/app
ports:
- "5000:80"
test-app:
build: ./test-app
volumes:
- "./test-app:/app"
- "/app/node_modules"
ports:
- "3001:3000"
environment:
- NODE_ENV=development
depends_on:
- scraper-api
Which build the following Dockerfile's:
scraper-api (a python flask application):
FROM python:3.7.3-alpine
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "./app.py"]
test-app (a test react application for the api):
# base image
FROM node:12.2.0-alpine
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:/app/src/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /app/package.json
RUN npm install --silent
RUN npm install react-scripts#3.0.1 -g --silent
RUN npm install axios -g
# start app
CMD ["npm", "start"]
Admittedly, I'm a newbie when it comes to Docker networking, but I am trying to get the react app to communicate with the scraper-api. For example, the scraper-api has the following endpoint: /api/top_10. I have tried various permutations of the following url:
http://scraper-api:80/api/test_api. None of them have been working for me.
I've been scavenging the internet and I can't really find a solution.
The React application runs in the end user's browser, which has no idea this "Docker" thing exists at all and doesn't know about any of the Docker Compose networking setup. For browser apps that happen to be hosted out of Docker, they need to be configured to use the host's DNS name or IP address, and the published port of the back-end service.
A common setup (Docker or otherwise) is to put both the browser apps and the back-end application behind a reverse proxy. In that case you can use relative URLs without host names like /api/..., and they will be interpreted as "the same host and port", which bypasses this problem entirely.
As a side note: when no network is specified inside docker-compose.yml, default network will be created for you with the following name [dir location of docker_compose.yml]_default. For example, if docker_compose.yml is in app folder. the network will be named app_default.
Now, inside this network, containers are reachable by their service names. So scraper-api host should resolve to the right container.
It could be that you are using wrong endpoint URL. In the question, you mentioned /api/top_10 as an endpoint, but URL to test was http://scraper-api:80/api/test_api which is inconsistent.
Also, it could be that you confused the order of the ports in docker-compose.yml for scraper-api service:
ports:
- "5000:80"
5000 is being exposed to host where docker is running. 80 is internal app port. Normally, flask apps are listening on 5000, so I thought you might have meant to say:
ports:
- "80:5000"
In which case, between containers you have to use :5000 as destination port in URLs: http://scraper-api:5000 as an example (+ endpoint suffix, of course).
To check connectivity, you might want to bash into client container, and see if things are connecting:
docker-compose exec test-app bash
wget http://scraper-api
wget http://scraper-api:5000
etc.
If you get a response, then you have connectivity, just need to figure out correct endpoint URL.