Beginner
Beginner

Reputation: 9095

Running react and node in a single port using Dockerfile

I am trying to run docker for my sample project where in the container I need a single port to run, But the build of react code will serve as the index.html, I have the below folder structure.

In index.js file I have tried to add the static path, What am I doing wrong here? I have commented it..

I have tried this much.

sampleapp
   client
     // using cra (create react app) files
     src
     public
     ...
   server
     index.js
   Dockerfile

// app.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  state = {
    response: null
  }

  componentWillMount(){
    this.dataFetching()
  }

  dataFetching = async () => {
    const resjson = await fetch('/api/data');
    const res = await resjson.json();
    this.setState({
      response: res.data
    })
  }


  render() {
    return (
        this.state.response ? this.state.response : null
    );
  }
}

export default App;

// package.json --client

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-scripts": "2.1.5"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "proxy": "http://localhost:4000"
}

// index.js -- server

const express = require('express');
const path = require('path');
const app = express();

// app.use(express.static(path.join(__dirname,  'build')));

// app.get('/*', function(req, res) {
//     res.sendFile(path.join(__dirname, '..', 'app', 'build', 'index.html'));
// });

app.get('/api/data', (req, res) => {
    res.send({data: "Success"})
})

app.listen(4000);

// Dockerfile - sampleapp

FROM node:10.15.1-alpine

COPY . /var/app

WORKDIR /var/app/client
RUN npm install --no-cache && npm run build && npm install -g serve


WORKDIR /var/app/server
RUN npm install --no-cache


EXPOSE 4000
EXPOSE 3000

Upvotes: 0

Views: 869

Answers (1)

Mostafa Hussein
Mostafa Hussein

Reputation: 11940

For the Dockerfile you can change it to the following:

FROM node:10.15.1-alpine

COPY . /var/app

WORKDIR /var/app/client
RUN npm install --no-cache && npm run build && npm install -g serve


WORKDIR /var/app/server
RUN npm install --no-cache

EXPOSE 4000 

CMD [ "npm", "start", "index.js" ]

For index.js (server), you can change it to the following:

const express = require('express');
const path = require('path');
const app = express();

app.get('/api/data', (req, res) => {
    res.send({data: "Success"})
})

app.use(express.static(path.join(__dirname,  '..', 'client', 'build')));

app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, '..', 'client', 'build', 'index.html'));
});

app.listen(4000, '0.0.0.0');
  1. React will be served as a static file through nodeJS
  2. index.js needs to be binded to 0.0.0.0 so you can connect to it from outside the container.

Upvotes: 1

Related Questions