This is one of the project, i did it for my client. In this blog i am using sample code from github.
Note: No Code has used from vendor ends, only sharing manifests files
- Open Powershell, Create a node app
mkdir docker-template cd docker-template # setup npm, download the package on windows https://nodejs.org/dist/v18.20.2/node-v18.20.2-win-x64.zip #Extract the zip .\npm init .\npm install express
2. Create a Server.js file (using notepad command)
const express = require("express"); const app = express(); const port = 8080; app.get("/", async (req, res) => { res.setHeader("Content-Type", "text/html"); res.status(200); res.send("<h1>Hello world</h1>"); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`);
3. #Run the following command
.\node.exe server.js
4. Open in Browser
http://localhost:8080
5. Let’s containerize
1)Identify the windows OS 2)Download the nodejs module 3)Copy the required file 4)Expose the port where it will listen 5)Pass the command when it starts
6. Write Dockerfile
FROM mcr.microsoft.com/windows/servercore:1803 as installer SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"] RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v18.20.2/node-v18.20.2-win-x64.zip";expand-archive nodejs.zip FROM mcr.microsoft.com/windows/nanoserver:1803 WORKDIR "C:\nodejs\node-v18.20.2-win-x64" COPY --from=installer "C:\nodejs\node-v18.20.2-win-x64" . RUN SETX PATH "C:\nodejs\node-v18.20.2-win-x64" RUN npm config set registry https://registry.npmjs.org/ # Create app directory # this is the location where you will be inside the container WORKDIR /usr/src/app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) # copying packages first helps take advantage of docker layers COPY package*.json ./ RUN npm install COPY . . # Make this port accessible from outside the container # Necessary for your browser to send HTTP requests to your Node app EXPOSE 8080 # Command to run when the container is ready # Separate arguments as separate values in the array CMD ["node", "server.js"]
7.Build image
Rename-Item .\Dockerfile.txt .\Dockerfile docker build -t myapp .
8. Run the container
docker run -d --name=mynode -p 8080:8080 myapp docker ps #open in browser http://localhost:8080
9. Identify the Image
Setup postgres same way we setup nodejs
Ref docker file: Postgres dockerfile
Create a table:database-seed.sql
CREATE TABLE employees ( id SERIAL, name text, title text, CONSTRAINT employees_pkey PRIMARY KEY (id) ); INSERT INTO employees(name, title) VALUES ('Meadow Crystalfreak ', 'Head of Operations'), ('Buddy-Ray Perceptor', 'DevRel'), ('Prince Flitterbell', 'Marketing Guru');
10.Docker file for db:dbdockerfile
FROM stellirin/postgres-windows WORKDIR docker-entrypoint-initdb.d COPY "database-seed.sql" ./
11. Run the dockerbuild command
docker build -t dbpostgres -f .\dbdockerfile .
12. Modify the server.js file
const { Client } = require("pg"); const express = require("express"); const app = express(); const port = 8080; const dbConfig = { password: "root", user: "root", host: "postgres", }; app.use(express.static("public")); app.get("/employees", async (req, res) => { try { const client = new Client(dbConfig); // Create a new client for each connection await client.connect(); const results = await client.query("SELECT * FROM employees"); res.setHeader("Content-Type", "application/json"); res.status(200); res.send(JSON.stringify(results.rows)); } catch (error) { console.error("Query failed:", error); res.status(500).send("Query failed"); } }); (async () => { app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); }); })();
13. Create frontend files for the app
mkdir public cd public notepad
14. Copy the below content, and save as index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>My Docker Template</title> <script src="script.js"></script> <link rel="stylesheet" href="styles.css" /> </head> <body> <template> <div class="card"> <img src="https://res.cloudinary.com/dqse2txyi/image/upload/v1639943067/blogs/docker-node/profile-picture_eav2ff.png" alt="Avatar" width="240px" /> <div class="container"> <h4>Placeholder</h4> <p>Placeholder</p> </div> </div> </template> </body> </html>
15.public/styles.css
body { padding: 12px; display: flex; flex-direction: row; column-gap: 24px; } .card { box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); transition: 0.3s; border-radius: 5px; transition: 0.3s; } .card:hover { transform: scale(1.03); } .container { padding: 0 12px; } img { border-radius: 5px 5px 0 0; }
public/script
fetch("/employees") .then((response) => response.json()) .then((data) => { data.forEach((employee) => { // Select the <template> we created in index.html const cardTemplate = document.querySelector('template'); // Clone a copy of the template we can insert in the DOM as a real visible node const card = cardTemplate.content.cloneNode(true); // Update the content of the cloned template with the employee data we queried from the backend card.querySelector('h4').innerText = employee.name; card.querySelector('p').innerText = employee.title; // Append the card as a child with the employee data to the <body> element on our page document.body.appendChild(card); }); });
#Come out from public folder cd ..
16.Now build the app again
Docker file changes
FROM mcr.microsoft.com/windows/servercore:1803 as installer SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"] RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v18.20.2/node-v18.20.2-win-x64.zip";expand-archive nodejs.zip FROM mcr.microsoft.com/windows/nanoserver:1803 WORKDIR "C:\nodejs\node-v18.20.2-win-x64" COPY --from=installer "C:\nodejs\node-v18.20.2-win-x64" . #RUN icacls . /grant Everyone:(OI)(CI)F /T RUN SETX PATH "C:\nodejs\node-v18.20.2-win-x64" RUN npm config set registry https://registry.npmjs.org/ # Create app directory # this is the location where you will be inside the container WORKDIR /usr/src/app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) # copying packages first helps take advantage of docker layers COPY package*.json ./ RUN npm install RUN npm install pg # If you are building your code for production # RUN npm ci --only=production COPY . . # Make this port accessible from outside the container # Necessary for your browser to send HTTP requests to your Node app EXPOSE 8080 #CMD cmd.exe # Command to run when the container is ready CMD ["node", "server.js"]
17,
docker build -t mynode . docker run -d --name=myapp -p 8080:8080 mynode Start the container for db first docker run -d --name=postgres -e POSTGRES_USER=root -e POSTGRES_PASSWORD=root -e POSTGRES_DB=root -p 5432:5432 dbpostgres
18. Open in browser: http://localhost:8080