3

I have a sample application, I am using nodejs and reactjs, So my project folder consists of client and server folder. The client folder is created using create-react-app.

i have created two Dockerfile for each of the folder, and i am using a docker-compose.yml on the root of the project.

everything is working fine. Now i just want to host this application. I am trying to use jenkins.

Since i have little knowledge on the devops side. i have some doubts

1) if i use two docker files for client and react and it is started by docker-compose.yml , will it be running in two different containers or in a single container? from what ever i have read i think it will take two container thats the use of docker-compose.yml file. Little bit confused on this ?

2) also when i do the sudo docker-compose up, it is running perfectly but it is showing "to create production build use npm run build", based on the env how can i change this one. Do i need to create different docker-compose.yml file for each environment. How can i use the same file but different npm start or npm run build based on the env ?

3) can i use docker-compose.yml file for building the pipeline in jenkins or do i need a Dockerfile in the root of project. I have seen most of the projects having a single Dockerfile. Is that i am not able to use docker-compose.yml for hosting the application ?

4) why i use NODE_COMMAND for server in Command property of docker-compose.yml file is because when i am running application in local i need to have the auto reloading , so in terminal if i put NODE_COMMAND = nodemon it will take instead of running node index.js but in production it will take only node index.js if i don't mention any NODE_COMMAND.

5) Do i need the CMD in Dockerfile of each client and server since when i run docker-compose up it will take the command of docker-compose.yml. So i think the precedence will take from the docker-compose.yml file. is it ?

6) what is the use of volumes is it required in docker-compose.yml file ?

7) in env file i am using API_HOST and APP_SERVER_PORT how it is internally worrking with the package.json? is it doing the proxy thing. When we need to hit nodejs we usually gives "proxy": "http://localhost:4000", but here how it will take http://server:4000 . How this thing works ?

8) when we are creating a container we have ports like 3000, 3001 ... so the container port and our application port how it matches, by use of exports environments and ports in the docker-compose.yml file will take care of that ?

please see the below folder structure

movielisting
   client
     Dockerfile
     package.json
     package.lock.json
     ... other create-react-app folders like src..
   server
     Dockerfile
     index.js
   docker-compose.yml
   .env

Dockerfile -- client

FROM node:10.15.1-alpine

#Create app directory and use it as the working directory
RUN mkdir -p /srv/app/client
WORKDIR /srv/app/client

COPY package.json /srv/app/client
COPY package-lock.json /srv/app/client

RUN npm install

COPY . /srv/app/client

CMD ["npm", "start"]

Dockerfile -- server

FROM node:10.15.1-alpine

#Create app directory
RUN mkdir -p /srv/app/server
WORKDIR /srv/app/server

COPY package.json /srv/app/server
COPY package-lock.json /srv/app/server

RUN npm install

COPY . /srv/app/server

CMD ["node", "index.js"]

docker-compose.yml -- root of project

version: "3"

services:
  #########################
  # Setup node container
  #########################
  server:
    build: ./server
    expose:
      - ${APP_SERVER_PORT}
    environment:
      API_HOST: ${API_HOST}
      APP_SERVER_PORT: ${APP_SERVER_PORT}
    ports:
      - ${APP_SERVER_PORT}:${APP_SERVER_PORT}
    volumes:
      - ./server:/srv/app/server
    command: ${NODE_COMMAND:-node} index.js

    ##########################
    # Setup client container
    ##########################

  client:
    build: ./client
    environment:
      - REACT_APP_PORT=${REACT_APP_PORT}
    expose:
      - ${REACT_APP_PORT}
    ports:
      - ${REACT_APP_PORT}:${REACT_APP_PORT}
    volumes:
      - ./client/src:/srv/app/client/src
      - ./client/public:/srv/app/client/public
    links:
      - server
    command: npm run start

.env

API_HOST="http://localhost:4000"
APP_SERVER_PORT=4000
REACT_APP_PORT=3000

package.json -- client

"proxy": "http://server:4000"

what all things can i refactor,

Any help appreciated.

2
  • This would be much easier to answer if it were split into several smaller questions. Some of the questions (like #5 and #6) you should be able to answer via the information on docs.docker.com. Commented Feb 23, 2019 at 12:24
  • Sure will split that one but may I know the other questions solutions Commented Feb 23, 2019 at 13:28

2 Answers 2

4

1) if i use two docker files for client and react and it is started by docker-compose.yml , will it be running in two different containers or in a single container? from what ever i have read i think it will take two container thats the use of docker-compose.yml file. Little bit confused on this ?

Each dockerfile will build a docker image. So in the end you will have two images one for the react application and the other one for the backend which is nodejs application


2) also when i do the sudo docker-compose up, it is running perfectly but it is showing "to create production build use npm run build", based on the env how can i change this one. Do i need to create different docker-compose.yml file for each environment. How can i use the same file but different npm start or npm run build based on the env ?

You need to build the react application within the steps you have in its Dockerfile in order to be able to use it as a normal application. Also you might use environment varaible to customize the image during the build using build-args for example passing custom path or anything else.


3) can i use docker-compose.yml file for building the pipeline in jenkins or do i need a Dockerfile in the root of project. I have seen most of the projects having a single Dockerfile. Is that i am not able to use docker-compose.yml for hosting the application ?

It would be better if you use the dockerfile(s) with jenkins in order to build your images and keep docker-compose.yml file(s) for deploying the application itself without using the build keyword


4) why i use NODE_COMMAND for server in Command property of docker-compose.yml file is because when i am running application in local i need to have the auto reloading , so in terminal if i put NODE_COMMAND = nodemon it will take instead of running node index.js but in production it will take only node index.js if i don't mention any NODE_COMMAND.

Using command inside the docker-compose.yml file will override the CMD for the dockerfile which was set during the build step


5) Do i need the CMD in Dockerfile of each client and server since when i run docker-compose up it will take the command of docker-compose.yml. So i think the precedence will take from the docker-compose.yml file. is it ?

Generally speaking yes you need it however as long as you want to use override it from the docker-compose file you might added it as CMD ["node", "--help"] or something


6) what is the use of volumes is it required in docker-compose.yml file ?

Volumes is needed in case you have shared files between containers or you need to keep data persistent on the host


7) in env file i am using API_HOST and APP_SERVER_PORT how it is internally worrking with the package.json? is it doing the proxy thing. When we need to hit nodejs we usually gives "proxy": "http://localhost:4000", but here how it will take http://server:4000 . How this thing works ?

server is an alias for the nodejs container inside the docker network once you start your application. and why named server ? because you have it inside your docker-compose.yml file in this part:

services:
  server:

But of course you can change it by adding alias to it within network keyword inside the docker-compose.yml file

Note: React itself is a client side which means it works through the browser itself so it wont be able to contact the nodejs application through docker network you may use the ip itself or use localhost and make the nodejs accessible through localhost


8) when we are creating a container we have ports like 3000, 3001 ... so the container port and our application port how it matches, by use of exports environments and ports in the docker-compose.yml file will take care of that ?

Docker itself does not know about which port your application is using so you have to make both of them use the same port. and in nodejs this is achievable by using environment variable


For more details:

Sign up to request clarification or add additional context in comments.

10 Comments

thanks for the response. So if i host a mock server, which is running in port 3001, so how can i call the 3001 from the server folder. when i try to call the localhost:3001/data i am getting error connection refused error. Since we are running in a container it is not able to hit the oiginal localhost:3001 port. How can i resolve this one
You need to make port mapping through docker, for example 3001 -> 3000, so when you access the application from the host through 3001 it will talk to 3000 on the container to get the data you need, but make sure that the application itself is actually running on port 3000
i have client which is react running in 3000, i have server node js which is running in 4000. and i have a node mock server which is running in 3001. so in my index.js of sever i am calling fetch("localhost:3001/api/data"). I didn't want this mock server to be added in the docker-compose.yml this mock server is for api testing
The mock server is the same as the docker host where you using docker-compose ?
when ever i am hiiting that api the response i am getting is error connection refused ? so from docker container how can i call that actual mock server api. if istart normally without docker i am able to get the response
|
0

if any one facing issues with connecting react and express, make sure there is NO localhost attached to server api address in client code

(eg: http://localhost:5000/api should be changed to /api),

since proxy entry is there in package.json file.

PS: if no entry is there, add

{
  "proxy": "http://server:5000"
}

to package.json, ('server' is your express app container name in docker-compose file)

finally made it work. thought of sharing this if it helps anyone else

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.