javascript - 本地主机在 Docker 中无法用于生产

标签 javascript node.js reactjs mongodb docker

我使用 docker 在本地机器上成功运行了 MERN 应用程序。然后,只是为了好玩,我想让它部署到 AWS、EC2 实例。部署后,react-app 中的 fetch 调用出现此错误:

GET http://localhost:5000/posts/ net::ERR_CONNECTION_REFUSED
App.js:37 TypeError: Failed to fetch
我只是从保存在 mongodb 中的 react 应用程序创建和获取帖子。这在本地机器上运行良好,但在 Amazon EC2 实例(Ubuntu 18.04)中运行良好,即使前端部分仍在显示但在有 api 调用时会出错,它也不起作用。
我对实例进行了 sshed 并在其中尝试了 curl 命令,它给出了正确的结果。但是使用提供的公共(public) url,即来自 react 应用程序,会出现上述错误。
这里有一些细节,希望你们能帮助我。
react :App.js
import React from 'react';
import './App.css';

const serverUrl = 'http://localhost:5000'

const postModel = {
    title: '',
    body: '',
}

function App() {

    const [posts, setPosts] = React.useState([])
    const [post, setPost] = React.useState({ ...postModel })

    React.useEffect(() => {


        //get all the posts
        fetch(`${serverUrl}`, {
            method: 'GET',
        })
            .then(res => res.json())
            .then(res => {
                console.log(res)
            })
            .catch(err => console.log(err))

        //get all the posts
        fetch(`${serverUrl}/posts/`, {
            method: 'GET',
        })
            .then(res => res.json())
            .then(res => {
                setPosts([...res])
            })
            .catch(err => console.log(err))
    }, [])


    const _postChange = (e) => {
        setPost({ ...post, [e.target.name]: e.target.value })
    }

    const _addPost = () => {
        //add new post

        const requestJson = JSON.stringify(post)
        console.log(requestJson)
        fetch(`${serverUrl}/post/add/`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: requestJson
        })
            .then(res => res.json())
            .then(res => {
                console.log(res)
                setPosts([...posts, { title: res.post.title, body: res.post.body }]);
                setPost({ ...postModel })
            })
            .catch(err => console.log(err))
    }

    console.log(post)

    return (
        <div className="App">
            <h2>All Posts</h2>
            <div>
                <input placeholder="Post Title" value={post.title} onChange={_postChange} type="text" name="title" />
                <input placeholder="Post body" value={post.body} onChange={_postChange} name="body" />
                <button onClick={_addPost}>Add</button>
            </div>
            <div>
                {posts.map((instance, index) => {
                    return <div key={index}>
                        <h4>{instance.title}</h4>
                        <p>{instance.body}</p>
                        <hr />
                    </div>
                })}
            </div>
        </div>
    );
}

export default App;
react :Dockerfile
# build environment
FROM node:12.2.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /app/package.json
RUN npm install --silent
RUN npm install react-scripts@3.4.1 -g --silent
COPY . /app
RUN npm run build

# production environment
FROM nginx:1.16.0-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
react :package.json
{
  "name": "react-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "cra-template": "1.0.3",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "3.4.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
后端:index.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const Post = require('./models/Post');
const cors = require('cors')

const app = express();

app.use(cors());
app.use(bodyParser.json());


// Connect to MongoDB
mongoose
  .connect(
    'mongodb://mongo:27017/node-mongo-docker',
    { useNewUrlParser: true }
  )
  .then(() => console.log('MongoDB is on'))
  .catch(err => console.log(err));


//test the work
app.get('/', (req, res) => {
  res.json({ 'message': 'Working properly' })
})

//get all posts
app.get('/posts', (req, res) => {
  console.log("Getting of posts")
  Post
    .find()
    .then(posts => res.json(posts))
    .catch(err => res.json({ 'error': err }))
})

//post a new post
app.post('/post/add', (req, res) => {
  console.log(req.body)
  const newPost = new Post({
    title: req.body.title,
    body: req.body.body,
  })
  newPost
    .save()
    .then(post => res.json({ 'post': post }))
});

const port = 5000;

app.listen(port, () => console.log('Server is on'));
后端:Dockerfile
FROM node:12.2.0-alpine 

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5000

CMD ["npm", "start"]
后端:package.json
{
  "name": "node-mongo-docker",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.3",
    "cors": "^2.8.5",
    "express": "^4.16.3",
    "mongoose": "^5.2.7",
    "nodemon": "^2.0.4"
  }
}
docker -compose.yml
version: '3'
services:
  react:
    container_name: react-app
    build: ./react-app
    ports: 
      - '80:80'
    links:
      - server
  server:
    container_name: node-mongo-docker
    restart: always
    build: ./node-mongo
    ports:
      - '5000:5000'
    links:
      - mongo
    # volumes:
    #   - '.:/usr/src/app'
  mongo:
    container_name: mongo
    image: mongo
    ports:
      - '27017:27017'

最佳答案

您需要将“localhost”替换为已部署后端的 url。
React 是一个 客户端 javascript 库,并在用户的网络浏览器中运行,因此它将使用访问您页面的用户的“localhost”,不是 服务器的本地主机。

关于javascript - 本地主机在 Docker 中无法用于生产,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63103356/

相关文章:

javascript - 删除 JavaScript 中的 if if 语句 true 禁用

javascript - 通过 JavaScript 提交数据最简单的方法是什么?

javascript - Rails 5 : javascript preview and remove image, 水平对齐预览图片

node.js - 是否可以仅在尚未安装 npm 包的情况下安装它?

mysql - 在 Meteor 方法中检索 MySQL 插入 ID

javascript - 将 CSS 样式(或类)添加到组件中 React 对象数组的每个元素

javascript - 在更多输入字段中设置值

node.js - 如何在 Mongoose 中进行聚合 + 填充

javascript - 使用 webpack 将 react 和 react-router 导出到独立的 html 文件时,应用程序不运行

reactjs - 如何在 Material UI 中布局表单?