I'm working on a React app and I have it working when I deploy it as a Docker container, in a Rancher cluster, to what I'll call a "normal" endpoint. Meaning if I set up the endpoint to be test.site.com, everything works fine. The problem is my company is insisting on using path to direct traffic to different services. For example, test.site.com/my-site will direct traffic to my React app, but test.site.com/other-site directs traffic to another service. I'm having an issue where when I deploy my site to test.site.com/my-site, my app can't seem to resolve some of its assets. Opening the console in the browser gives errors such as:
GET https://test.site.com/cesium/Cesium.js net::ERR_ABORTED 405
GET https://test.site.com/cesium/Widgets/widgets.css net::ERR_ABORTED 404
GET https://test.site.com/bundle.js net::ERR_ABORTED 404
(Cesium is a library I'm using in my app https://cesium.com/blog/2018/03/05/integrating-cesium-and-react/)
I've only recently started working with webpack, so I think there's probably some configuration there to fix this? Here's the relevant config files.
webpack.config.js
const path = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const HtmlPlugin = require('html-webpack-plugin')
const HtmlTagsPlugin = require('html-webpack-tags-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const dotenv = require('dotenv')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
publicPath: '/',
},
resolve: {
modules: [path.join(__dirname, 'src'), 'node_modules'],
alias: {
react: path.join(__dirname, 'node_modules', 'react'),
},
extensions: ['.jsx', '.js'],
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /\.(png|svg|jpe?g|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
},
],
},
devServer: {
historyApiFallback: {
index: '/',
},
},
externals: {
cesium: 'Cesium',
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
}),
new webpack.DefinePlugin({
'process.env': JSON.stringify(dotenv.config().parsed), // it will automatically pick up key values from .env file
}),
new CopyWebpackPlugin({
patterns: [
{
from: 'node_modules/cesium/Build/Cesium',
to: 'cesium',
},
],
}),
new HtmlPlugin({
template: './src/index.html',
}),
new HtmlTagsPlugin({
append: false,
tags: ['cesium/Widgets/widgets.css', 'cesium/Cesium.js'],
}),
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('/cesium'),
}),
],
}
Dockerfile
FROM node:14-slim AS builder
ENV NODE_ENV production
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
FROM nginx:1.21.0-alpine as production
ENV NODE_ENV production
COPY --from=builder /app/build /usr/share/nginx/html
RUN echo $(ls -1 /usr/share/nginx/html)
RUN chown nginx:nginx -R /usr/share/nginx
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN echo $(ls -1 /etc/nginx/conf.d/)
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}