Skip to content

Commit

Permalink
Merge pull request #93 from solo-io/charlesthebird/readOnlyFilesystemFix
Browse files Browse the repository at this point in the history
Charlesthebird/read only filesystem fix
  • Loading branch information
Charlesthebird authored Aug 23, 2024
2 parents b6c8a8c + 3ba5bc3 commit c2b6812
Show file tree
Hide file tree
Showing 15 changed files with 871 additions and 21 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
**/node_modules/*
*.local
dist
dist
.DS_Store
54 changes: 41 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
FROM node:18.16.0
###############
# #
# Build Stage #
# #
###############

FROM node:18.16.0 AS build_stage

# Install global dependencies.
RUN apt-get update && apt-get install -y build-essential

# Copy all project files.
WORKDIR /app
COPY ./projects projects
COPY ./scripts scripts

# Run the startup script, without starting the server.
# This script:
# - Installs dependencies.
# - Builds the UI.
# - Moves the UI build folder to the server project.
# - Inserts an EJS view engine variable into the UI build,
# so that the server can send the live environment variables
# along with the UI when the build is served.
RUN START_SERVER=false sh ./scripts/startup.sh

###############
# #
# Serve Stage #
# #
###############

FROM node:18.16.0 AS serve_stage

ENV VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \
VITE_CLIENT_ID=$VITE_CLIENT_ID \
Expand All @@ -15,19 +47,15 @@ ENV VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \
VITE_LOGO_IMAGE_URL=$VITE_LOGO_IMAGE_URL \
VITE_COMPANY_NAME=$VITE_COMPANY_NAME

# Copy files for build
# Copy the server files, (this includes the UI build).
WORKDIR /app
COPY ./projects projects
WORKDIR /app/projects/ui

# Install global dependencies and set up for runtime
RUN apt-get update && apt-get install -y build-essential
RUN yarn install
EXPOSE 4000
COPY --from=build_stage /app/projects/server .

# Build the app and pass in the environment variables, then start it.
# The build can't happen in 2 stages (build and runtime),
# since these variables will change when the image is deployed.
# Pass through the environment variables, and then start the server.
# These variables will change when the image is deployed.
# This needs to be `node ./bin/www` instead of `yarn start because
# running yarn causes a yarn cache file to change, which doesn't work
# in read-only environments.
ENTRYPOINT VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \
VITE_CLIENT_ID=$VITE_CLIENT_ID \
VITE_TOKEN_ENDPOINT=$VITE_TOKEN_ENDPOINT \
Expand All @@ -42,4 +70,4 @@ ENTRYPOINT VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \
VITE_APIS_IMAGE_URL=$VITE_APIS_IMAGE_URL \
VITE_LOGO_IMAGE_URL=$VITE_LOGO_IMAGE_URL \
VITE_COMPANY_NAME=$VITE_COMPANY_NAME \
yarn build && yarn run vite preview --port 4000 --host
node ./bin/www
7 changes: 7 additions & 0 deletions changelog/v0.0.34/support-for-read-only-filesystems.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
changelog:
- type: FIX
issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/18336
description: >-
Adds a server with a view engine to the project, which only is used to
serve the UI and insert configuration from environment variables.
Also fixes a yarn audit issue with axios.
33 changes: 33 additions & 0 deletions projects/server/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var express = require("express");
var path = require("path");

// Express and view engine setup
var app = express();
app.set("views", path.join(__dirname, "public", "dist"));
app.set("view engine", "ejs");

// The environment variables that we will pass through to the React app.
var variablesInit = `
const insertedEnvironmentVariables = ${JSON.stringify(
Object.fromEntries(
Object.entries(process.env).filter(([key, _value]) =>
key.startsWith("VITE_")
)
)
)};
`;

// This renders the index.ejs file
app.get("/", (_req, res) => {
res.render("index.ejs", { VariablesInit: variablesInit });
});

// This serves all static assets.
app.use(express.static(__dirname + "/public/dist"));

// Any fallthrough routes go to index.ejs.
app.get("*", (_req, res) => {
res.render("index.ejs", { VariablesInit: variablesInit });
});

module.exports = app;
89 changes: 89 additions & 0 deletions projects/server/bin/www
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* This file was pulled from the Express generator's pug template, and does the following:
* - Creates an http server on the requested port, using the Express app from `../app.js`.
* - Adds some logging messages for different statuses.
*/

/**
* Module dependencies.
*/

var app = require("../app");
var http = require("http");

/**
* Get port from environment and store in Express.
*/

var port = normalizePort(process.env.PORT || "4000");
app.set("port", port);

/**
* Create HTTP server.
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port);
server.on("error", onError);
server.on("listening", onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== "listen") {
throw error;
}

var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case "EACCES":
console.error(bind + " requires elevated privileges");
process.exit(1);
break;
case "EADDRINUSE":
console.error(bind + " is already in use");
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
console.log("Listening on " + bind);
}
15 changes: 15 additions & 0 deletions projects/server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "./bin/www",
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"ejs": "^3.1.10",
"express": "^4.19.2",
"http": "^0.0.1-security",
"path": "^0.12.7"
}
}
Loading

0 comments on commit c2b6812

Please sign in to comment.