Setting up server.js - javascript

I am trying to containerize my React application with docker and am now a little bit stuck with the server.js file as I do not know how to "implement" the application inside. I was able to simply show a "Hello World" but can't seem to run the application inside.
My idea was initially, that I could just use the index.js file as an entrypoint and use it in the "res.end(x)" as this was the place where I could simply enter the "Hello World".
Am I missing just something small or is my general approach wrong?
My server.js file looks as followed:
const http= require('http');
const fs = require('fs');
const index = fs.readFileSync('index.js');
let app = http.createServer((req, res) => {
res.writeHead(200,{'Content-Type': 'text/plain'});
res.end(index);
});
app.listen(9030, '0.0.0.0');
console.log('Node server running on port 9030')

I share with you this best documentation :
https://nodejs.org/en/docs/guides/nodejs-docker-webapp/

React is generally coded in .jsx files, which need to be compiled/transpiled into regular Javascript. Once this is done, you can serve these files to web browsers any way you like.
Understanding Build tools
React compilation/transpilation is done using Webpack or Parcel. If you're using Create-React-App, then you're using Webpack under the hood. CRA npm start will run a Webpack dev server, and npm run build will put all of the files you need in your build directory. You should do the latter if you want to
Avoid using Webpack dev server
Most tutorials, including the one linked in the comments, suggest using Webpack development server (aka npm start) to run your server in Docker. which is not recommended. Not only does it consume more resources to run, but the development build will run slower in browsers than the production build. The development server is also not meant to handle heavy loads.
Use build for production, with a real server
Use npm run build to generate the build files in the build directory, then use a real web server to serve them to the world.
One example in Docker, using Nginx to serve the files, can be found here
Alternatively the CRA build command itself offers a helpful hint:
The build folder is ready to be deployed.
You may serve it with a static server:
npm install -g serve
serve -s build
This will work in a Docker Node container. An example of a very not-optimized Dockerfile might look like this
FROM node:16-alpine
COPY . .
RUN npm install
RUN npm build
RUN npm install -D serve
CMD ["./node_modules/.bin/serve", "-s", "build"]
The build process can be improved here to leverage cache (by first copying package.json and package-lock.json and installing before copying code over, see example at the end of the answer here), and all of the RUN commands combined

Related

Writing a correct Dockerfile

I created an app using Javascript (with D3.js), JQuery, CSS, but no Node.js. It's your typical 'index.html' browser-run interface. I've been going through Docker tutorials and trying to figure out how to set my app up to a server, but I've had no luck accomplishing it and have only been able to find tutorials using apps with Node. I cannot, for the life of me, figure out what I'm doing wrong, but I'm wondering if the problem (or one of them) lies in my Dockerfile. Also, do I need to have used Node.js for all this to work? My app consists of the following:
A directory called Arena-Task. Within this directory, I have my index.html, my main javascript file called arena.js, and my CSS files. My other necessary files (like images, etc.) are located within two other folders in the same directory called data and scripts.
So now, how would I write my Dockerfile so that I can build it using Docker and publish it to a server? I've attempted following Docker's example Dockerfile:
FROM node:current-slim
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
EXPOSE 8080
CMD [ "npm", "start" ]
COPY . .
But to be honest I'm not quite sure how to make the changes to accommodate my program. I can't figure out if a package.json is required because if it is, then don't I need to be using Node? I don't use any node modules or project dependencies like that in my app. Do I need to be? Is my problem more than just an incorrect Dockerfile?
Sorry that this question is all over the place, but I'm really new to the realm of the server-side. I appreciate any help! Let me know if I can provide any clarification.
lets clarify few things:
node and npm is when you need them, like you are using some npm packages.
package.json - is in use by npm - it stores installed package list in it.
For you case i don't see need of node. so you can create simple image and then you going to need simple web server - something which can serve you html/css/js files on web requests over http. the simplest i know would be nginx.
Also in Dockerfile you need to copy all you resources into image you are building.
that is what COPY package.json . was doing. but in you case you have to copy whole app folder into some app folder in docker image. (assuming app is a folder which holds all you files)
so we are going to have steps
Dockerfile should look something like this:
FROM ubuntu
RUN apt-get install -y nginx
COPY app app
COPY startup.sh /startup.sh
COPY ./nginx-default /etc/nginx/sites-available/default
no need in default commands because you going to start something else during docker run.
nginx-default is a configuration for nginx to work as webserver:
it should look something like this:
server {
listen 8080;
server_name localhost;
root /app
}
nginx is very flexible - if you need something from it google it.
docker image should do something all the time, otherwise image going to stop (some blocking process).
the easiest way i know is to create startup.sh file which going to start nginx as first step and then going to do infinity loop:
exit_script() {
trap - SIGINT SIGTERM # clear the trap
sudo service nginx stop
exit 1
}
sudo service nginx start
while sleep 20; do
CURRENT_TIME=$(date +"%T")
echo "app is running: $CURRENT_TIME"
done
exit_script - is a trap which helps to stop docker image in fast way, but not like terminate. but you can omit that for testing purposes.
finally, build image (docker build -t {your-image-name} .) and to start image use something like this:
docker run -p 8080:8080 {your-image-name} bash /startup.sh
that should work :), though most probably you going to face few errors because i was writing it from the head. (like you may need something else for nginx, or sudo is not installed by default in ubuntu lates image).

Configuring Express Generator to use Pug instead of Jade

I installed Express Generator for Node.js but when I created an example app, I noticed that Jade is deprecated to Pug. I installed Pug, but I still need to tell express generator to use it each time. I've been reading about the subject and it's telling developers to just change the file names manually, but is there a way for this to work out of the box? How do I do that?
Express defaults to Jade but if you wish to pug as a template engine instead of using Jade.
You must type
express --view=pug myapp
This will create a new application called "myapp" using pug by default.
For a more in dept explanation type
express -h
this will show you the available commands, one of the commands is -v
--view add view support
Reference: https://expressjs.com/en/starter/generator.html
I made two mistakes trying to follow the above docs. It's because I'm still getting used to installing packages locally and globally.
2 Mistakes:
I. npx express-generator
This installed it locally, making express unavailable in the command line terminal.
When I installed it globally, I had access.
II. starting in a folder on Atom, an IDE. Express-generator creates a folder for you, so you start in the terminal outside of a folder, such as your desktop.
9 Steps to solution:
Use the terminal in your desktop directory, not an IDE.
Do not create a folder or any file.
Install express-generator globally, not locally.
sudo npm express-generator
Verify you have access by: express -h
Type: express --view=pug my app
Change directories to myapp folder on desktop
npm install
DEBUG=myapp:* npm start
open your browser to http://127.0.0.1:3000/
I think this issue come when npx express-generator is used alone (for those who have node versions above Node.js 8.2.0).
for node versions 8.2.0 or above,
Navigate to the directory where you want to create the app
npx express-generator --view=pug myapp
This will create a myapp folder in the directory with required .pug
files instead of .jade files
for earlier node versions you can find the required steps here express
application generator documentation
npx express-generator --view=pug install.
this should do the trick

How To Deploy an Angular/Node app

I have a simple Angular 4 frontend as well as a node backend which is hosted separately on Heroku.
I deploy my Angular app by running ng build and copying over the contents of the dist folder to the server.
I have since then decided to integrate the backend into the front end so it's all just one project instead of two.
I can easily run node server.js on the root and it runs perfectly on my localhost.
But how can I deploy this to my server? I obviously can't just ng build and copy over the dist folder because that only builds the client folders and files.
Could I just copy over the server folder which holds the routes as well as the server.js file along with the client files and then somehow tell the server to run server.js when the site is loaded?
I use FileZilla to transfer my files onto the server.
Questions:
How do I deploy my angular/node app with FileZilla?
Which files/folders to I copy over with the client files?
If you are using Angular CLI, run ng build command to generate the dist folder.
Copy the dist folder to the backend server nodejs project.
Serve the dist folder using your Nodejs code.
If you are using ExpressJS. This can be done in a single line
app.use(express.static('dist'));
Install Heroku CLI and follow the tutorial to deploy your app: Heroku NodeJS Tutorial
You don't need to build the node app. Node runtime can compile the javascript on the fly.
The build step in angular packages up your code into one file. There is no equivalent in node as there isn't any point. The reason angular minifies and packages a file is so you can download it quickly. You never download the code from node.
On Heroku it's really easy, you don't need to copy anything over just run git push heroku master from the root of your node folder as per the instructions here https://devcenter.heroku.com/articles/getting-started-with-nodejs#deploy-the-app
Just make sure that in your package.json you have all the modules you rely on. It might work locally if you have npm modules installed globally but they also need to be in the package.json so heroku can download them by running npm install

How to create my own scripts in node.js

I am building an nodeapplication, it has 3 environments names are development,testing and production. Each environment has their own hostnames and port numbers. like in the following way
{
"development":{
"host":"develop.com",
"port":"2000"
},
"testing":{
"host":"testing.com",
"port":"2001"
},
"production":{
"host":"production.com",
"port":"2002"
}
}
While running my node application, I used to pass environment name as a command argument. like
node server.js development
(or)
node server.js production
Instead of running application manually along with environment name, I want to implement with node scripts, so I have tried in the following way.
package.json
{
"developemnt":"node server.js development",
"production":"node server.js production",
"testing":"node server.js testing"
}
What I thought, Instead of node server.js development, I can run npm development. This way I have made it, but it's not working. Regarding this, I have read npm script documentaion, as per documentation It's not possible,so is there any way to implement this.
Thanks
For scripts that are not "default scripts" (the ones listed here), you need to use the run parameter with npm:
npm run development
npm run testing
npm run production
More details here.

Grunt distribution doesn't include node_modules

I'm writing an application using Grunt as my build tool. I used the Yeoman generator angular-fullstack. The app is a Node.js app with Express on the backend. While developing, things work fine. If I build the distribution though, I can't deploy it to my server because none of the required npm dependencies are available, like Express for example. It's the first time I build this kind of app, so I assume I'm missing a step since the Gruntfile.js is still all defaults.
The "node_modules" folder is traditionally not included into source code repositories, for various reasons.
If you set up your node application correctly, however, and you have a "package.json" file where all dependencies are listed, then you just need to run npm install to download and install npm modules.

Categories

Resources