I try to run my app on EC2 Amazon Linux 2023, but even if it looks in pm2 logs that it runs (shows regular vite info that I can access it via localhost:5173). I cannot access it via "public-ip:5173". AWS CodeBuild Pipeline shows that everything went correct. Security group in inbounds rools is set like that:
Port/Protokol | Source |
---|---|
5173/Custom TCP | 0.0.0.0/0 |
80/HTTP | 0.0.0.0/0 |
80/HTTP | ::/0 |
443/HTTPS | 0.0.0.0/0 |
version: 0.0
os: linux
files:
- source: /
destination: /janus-ui
overwrite: true
file_exists_behavior: OVERWRITE
permissions:
- object: /
pattern: "**"
owner: ec2-user
group: ec2-user
hooks:
BeforeInstall:
- location: scripts/before_install.sh
timeout: 1600
runas: root
AfterInstall:
- location: scripts/after_install.sh
timeout: 1600
runas: root
ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
runas: root
#!/bin/bash
# navigate to app folder
cd /janus-ui
# install dependencies
npm install
npm install --save react react-dom react-scripts react-particles-js
npm install pm2 -g
#!/bin/bash
# navigate to app folder
cd /janus-ui
# install node and npm
curl -sL https://rpm.nodesource.com/setup_18.x | sudo -E bash -
yum -y install nodejs npm
#!/bin/bash
# navigate to app folder
cd /janus-ui
pm2 start npm --name "janus-ui" -- run prod
pm2 startup
pm2 save
pm2 restart all
my scripts in package.json
"scripts": {
"dev": "env-cmd -f .env.development vite --port 5173",
"prod": "env-cmd -f .env.production vite --port 5173",
"build": "vite build",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
# install npm
- npm install
build:
commands:
# run build script
- npm run-script build
artifacts:
# include all files required to run application
# notably excluded is node_modules, as this will cause overwrite error on deploy
files:
- dist/**/*
- src/**/*
- package.json
- appspec.yml
- index.html
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
- scripts/**/*
- .env.production
Generally I stuck. I do it first time and I tried nginx, now pm2 looks easier, but still I cannot access even if logs looks like everything is correct.
I expect to see my page via browser on "public-ip:5173"
To run a react web application you need an http server. React comes with a tiny server just for development (npm run dev) but not for production (for real users) environments.
I will show you some options from manually to automated
I advice you to use docker for your react and spring boot api. I can provide you ready to use templates. Also with this you will work like a pro.
You can install docker with the official guide or my script
Open the 80 port is not complicated
You can use another port if you need: 8080 for spring boot and 8081 for react
Then the aws public url is something like
http://ec2-aa-bb-cc-131.compute-1.amazonaws.com
image source: https://mkyong.com/server/namecheap-domain-name-and-amazon-ec2/
If you chose the 80 port for react, you could use directly the aws public url
thanks erick258 comment
No matter the option you choose, you will need to build the app before serve it. Usually npm run build
does it. Check if the build folder has your web with javascript minified. Like:
If you are not able to build the web app (react, angular, vue, svelte, etc), you could not serve it in the ec2 server
By default the 80 port is used by apache, so that matches with the 80 of your ec2.
Check these:
I think the easiest way is to wipe this folder /usr/local/apache2/htdocs/ and put your dist content. Then restart the apache
So easy. Just create this Dockerfile at the root of your react project:
FROM httpd:2.4
WORKDIR /usr/local/apache2/htdocs/
COPY build/ /usr/local/apache2/htdocs/
RUN chmod -R 755 /usr/local/apache2/htdocs/
Then run this is your shell
npm install
npm run build
docker build -t acme-web-container .
# wait some seconds
docker run -d --name acme-web -it --rm -p 80:80 acme-web-container
The web will be ready to use with the ec2 public domain
Exactly the same of apache but with other folders and commands. Read these:
Create a nginx.conf file with this content
FROM nginx:1.15.8-alpine
#config
copy ./nginx.conf /etc/nginx/nginx.conf
#web
copy build/ /usr/share/nginx/html/
RUN chown -R nginx:nginx /usr/share/nginx/html/
Then run this is your shell
npm install
npm run build
docker build -t acme-web-container .
# wait some seconds
docker run -d --name acme-web -it --rm -p 80:80 acme-web-container
The web will be ready to use with the ec2 public domain
Basically you just need to configure a folder in the web.xml. Read:
As I told you, tomcat is for java. You could use it but in a real environments and or for easy management and scaling:
If you like nodejs, you could use these options to server your spa
Also you can use my library which is able to serve any spa (react, angular, vue, etc)
https://github.com/usil/nodeboot-spa-server
In spring boot if you use environment variables, you can build the application just one time and then deploy it everywhere just changing the env variables. Example:
This is for real or enterprise environments in which you need several environment for the same application like:
If you like that way, sadly in react is not possible. Read this to understand it : https://jrichardsz.github.io/devops/just-one-build-for-spas
In the spas (react, angular, vue) you need to build for each environment (dev, test, staging, uat, prod, etc) which is not devops suitable. To fix this read https://jrichardsz.github.io/web/how-serve-spa-csr-react-angular-vue-webs and or you can use again my library:
https://github.com/usil/nodeboot-spa-server
Read the What is /settings.json ? section
In this mode, all the react repository is docker driven, so you don't need to perform the npm run build
before the docker build ..
. With this your react application could be fully ported to kubernetes or some orchestrator. I like https://aws.amazon.com/elasticbeanstalk
Also you open the possibility to use devops:
Basically your Dockerfile should be like this:
# build environment
FROM node:alpine as build
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
And finally the required commands will be
docker build -t acme-web-container .
docker run -d --name acme-web -it --rm -p 80:80 acme-web-container
More details here: