I would like to dockerize and create a build process for a simple Vue.js application using Dockerfile. But, I get some errors when building from NGINX, it looks like the static build files of the project are missing. When I log in to localhost:8080 - I get an empty page, and in the console the following messages:
2023/01/06 07:00:03 [error] 30#30: *1 open()
"/usr/share/nginx/html/vue-ims/js/chunk-vendors.97986597.js" failed
(2: No such file or directory), client: 172.17.0.1, server: localhost,
request: "GET /vue-ims/js/chunk-vendors.97986597.js HTTP/1.1", host:
"localhost:8080", referrer: "http://localhost:8080/"
...
I tried to access the /usr/share/nginx folder inside the container, but nothing was visible there. During the dockerfile build process, it should COPY all the necessary files to certain folders that should be accessible, but seems like nothing happened.
Dockerfile:
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json .env ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
I also tried to build without the production stage as mentioned in comments, checked the /app/dist, /js/ folder inside the container and got the files there.
Thanks to #bassxzero solved this problem.
nginx.conf:
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
Related
I have a react app. When I build my app via the dev server (localhost: 3000), the app is served correctly with the correct styling etc.
However, when I serve via nginx (via docker) I get a completely different UI? Does anyone know why this may be?
I don't think it is a docker issue. I am using webpack if this is something that I may need to look at?
My nginx config:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /usr/share/nginx/html;
location = / {
try_files $uri /index.html;
}
}
Dockerfile:
FROM nginx:1.16-alpine
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY public/ /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
I have a vue.js project created with Vue CLI and npm run serveit always run on localhost.
I want to access from my phone (another IP inside the same network), so I want the serve to run on 0.0.0.0. I tried adding the vue.config.js file and setting the host:
module.exports = {
publicPath: '/',
devServer: {
host: '0.0.0.0',
port: 8080
}
}
Changing the port works fine, but the host override is ignored. This is the output of serve:
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.0.21:8080/
At first I thought it was being ignored, so I tried setting the host to 0.0.0.1 and the output is "correct", so the file is not ignored, only the 0.0.0.0 is being changed to localhost:
App running at:
- Local: http://0.0.0.1:8080/
- Network: http://0.0.0.1:8080/
I saw in some forums that devServer has a public option to set the URL, but if I try setting pubic: 'http://0.0.0.0:8080/' I get an error:
> npm run serve
Debugger attached.
> vue-model-viewer#0.1.0 serve <my project path>
> vue-cli-service serve
Debugger attached.
INFO Starting development server...
ERROR ValidationError: webpack Dev Server Invalid Options
options should NOT have additional properties
ValidationError: webpack Dev Server Invalid Options
options should NOT have additional properties
I need to run the server on 0.0.0.0 so I can test it on my phone.
Any help will be very appreciated.
You shouldn't need to run it on 0.0.0.0 from your local machine to test it on your phone. As long as the port on which it's running is open to external traffic and your phone is connected to your LAN via wifi, you can just put the IP address of your computer and the port # in as the URL.
I am using nginx with react.
My nginx.conf file
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
}
As per this config nginx is serving 200 for all routes..
Suppose my routes are
example.com/login
example.com/landing
Now suppose someone enter wrong url
example.com/test
In that case i want to throw 404 without landing to application at nginx level itself. Is this possible to handle routing at nginx level and send 404 despite of 200 and than handling at react level.
I found that to restrict any particular route at nginx level we can do it using below code
location ^~ /test/ {
return 404
}
But i want to restrict all routes which are invalid for that i used
# return 404 for all routes
location / {
return 404;
}
# define each possible route like this
location /login {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /landing {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
But after this my application is not loading getting 503 Service Temporarily Unavailable
First question is it really possible to achieve routing at nginx level if yes what approach i need to take any clue or reference will be of great help.
Thanks in advance
EDIT
Please find docker file
# Base Image
FROM node:10-alpine AS base
MAINTAINER test#test.com
RUN mkdir -p /usr/src/app
COPY . /usr/src/app
# Dependencies
FROM base as build
WORKDIR "/usr/src/app"
RUN npm install
RUN npm run test
RUN npm run build
# Web Server
FROM nginx:alpine
EXPOSE 80
COPY --from=build /usr/src/app/build /usr/share/nginx/html
COPY --from=build /usr/src/app/nginx.conf /etc/nginx/conf.d/default.conf
Yes, nginx can be used for this.
COPY --from=build /usr/src/app/nginx.conf /etc/nginx/nginx.conf
Just use this one.
Deploy React js(build directory) static files in Nginx server.
Using kubernetes, i am running the nginx server to serve the React js "build" directory for static files. I could access the simple index.html in the browser. But not the index.html with react js code. The root directory has the index.html file, static directory and other files in it. Directory structure is copied to this path.
nginx.conf is like below
events {
worker_connections 1024;
}
http {
server {
listen 80;
root /usr/share/nginx/html;
#index index.html;
location / {
index index.html;
try_files $uri $uri/index.html /index.html;
}
location /static/ {
autoindex on;
root /usr/share/nginx/html/static/;
}
}
}
In the browser, index.html is not loaded, but in source (right-click in the browser > select source), the index.html code is available. formatted index.html file copied from source in the browser is at this path. I am predicting that javascript(css,js) code is not executed or having issues loading in the browser. Otherwise, there is a problem with the nginx configuration to load the javascript files.
how to properly configure nginx to deploy Reactjs build directory files?
try_files does not tell nginx to serve the static file. Reaching the closing brace in the absence of any other operation causes it to serve the static file. try_files tests for the existence of the file in the local file system and may rewrite the URL.
You have syntax errors in your file i.a white spaces.
Remember to create service for nginx - type LoadBalancer and refer to it in deployment configuration file. You have to add your server if there are several servers that match the IP address and port of the request.
Here is example how you should execute this process. Make sure you followed every step from tutorial: nginx-configuration - there is example of exercise on PHP application but there are the same steps to reproduce with ReactJS app.
Your conf file should looks like this:
events {
worker_connections 1024;
}
http {
server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
server_name your_server_name_or_IP
location / {
try_files $uri $uri/index.html /index.html;
}
location /static/ {
autoindex on;
root /usr/share/nginx/html/static/;
}
}
}
The below code that works for me.
server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
server_name xyz.application.com;
server_name localhost;
location / {
ssi on;
set $inc $request_uri;
if (!-f $request_filename) {
rewrite ^ /index.html last;
}
index index.html;
try_files $uri $uri/index.html /index.html =404;
}
Setting the rewrite redirects to index.html page. I am not sure about the impact of ssi, set $inc $request_uri in the code.
I'm using Node.js and need to save files to a tmp directory within my app. The problem is that Elastic Beanstalk does not set the app directory to be writable by the app. So when I try to create the temp directory I get this error
fs.js:653
return binding.mkdir(pathModule._makeLong(path),
^
Error: EACCES, permission denied '/var/app/tmp/'
at Object.fs.mkdirSync (fs.js:653:18)
at Promise.<anonymous> (/var/app/current/routes/auth.js:116:18)
at Promise.<anonymous> (/var/app/current/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
at Promise.emit (events.js:95:17)
at Promise.emit (/var/app/current/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
at Promise.fulfill (/var/app/current/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
at /var/app/current/node_modules/mongoose/lib/query.js:1394:13
at model.Document.init (/var/app/current/node_modules/mongoose/lib/document.js:250:11)
at completeOne (/var/app/current/node_modules/mongoose/lib/query.js:1392:10)
at Object.cb (/var/app/current/node_modules/mongoose/lib/query.js:1151:11)
I've tried several things such as an app-setup.sh script within .ebextensions/scripts/app-setup.sh that looks like this
#!/bin/bash
# Check if this is the very first time that this script is running
if ([ ! -f /root/.not-a-new-instance.txt ]) then
newEC2Instance=true
fi
# Get the directory of 'this' script
dirCurScript=$(dirname "${BASH_SOURCE[0]}")
# Fix the line endings of all files
find $dirCurScript/../../ -type f | xargs dos2unix -q -k
# Get the app configuration environment variables
source $dirCurScript/../../copy-to-slash/root/.elastic-beanstalk-app
export ELASTICBEANSTALK_APP_DIR="/$ELASTICBEANSTALK_APP_NAME"
appName="$ELASTICBEANSTALK_APP_NAME"
dirApp="$ELASTICBEANSTALK_APP_DIR"
dirAppExt="$ELASTICBEANSTALK_APP_DIR/.ebextensions"
dirAppTmp="$ELASTICBEANSTALK_APP_DIR/tmp"
dirAppData="$dirAppExt/data"
dirAppScript="$dirAppExt/scripts"
# Create tmp directory
mkdir -p $dirApp/tmp
# Set permissions
chmod 777 $dirApp
chmod 777 $dirApp/tmp
# Ensuring all the required environment settings after all the above setup
if ([ -f ~/.bash_profile ]) then
source ~/.bash_profile
fi
# If new instance, now it is not new anymore
if ([ $newEC2Instance ]) then
echo -n "" > /root/.not-a-new-instance.txt
fi
# Print the finish time of this script
echo $(date)
# Always successful exit so that beanstalk does not stop creating the environment
exit 0
As well as creating a file called 02_env.config within .ebextensions that looks like this
# .ebextensions/99datadog.config
container_commands:
01mkdir:
command: "mkdir /var/app/tmp"
02chmod:
command: "chmod 777 /var/app/tmp"
Neither seem to work. How can I create a tmp directory within my app that is writable?
I recently experienced the same issue with a .NET application where the application was failing because it couldn't write to a directory, even after I had set the permissions.
What I found was that after the whole .ebextensions process was completed, the final step was a web container permissions update which ended up overwriting my ebextensions permissions change.
To solve it I moved the directory outside of the web container and updated the application to write there instead.
In your case I would suggest /tmp
With the newer (current?) Amazon Linux 2 elastic beanstalk installs, setting up a Post Deploy hook is the way to make this happen. The tmp folder needs to be created and made writeable AFTER elastic beanstalk has moved the newly deployed app bundle to /var/app. It's just a shell script placed in the following location from the root of your app:
.platform/hooks/postdeploy/10_create_tmp_and_make_writeable.sh
#!/bin/bash
mkdir /var/app/current/tmp
chmod 777 /var/app/current/tmp