<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lightning Bolt</title>
    <description>The latest articles on DEV Community by Lightning Bolt (@apfirebolt).</description>
    <link>https://dev.to/apfirebolt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F623115%2F0e030598-8d70-4d1b-b922-b068efcfb28b.png</url>
      <title>DEV Community: Lightning Bolt</title>
      <link>https://dev.to/apfirebolt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/apfirebolt"/>
    <language>en</language>
    <item>
      <title>Deploy your MEVN (MongoDB, Express, Vue and Node) application on a server using Docker and Docker-compose</title>
      <dc:creator>Lightning Bolt</dc:creator>
      <pubDate>Wed, 19 Mar 2025 19:52:52 +0000</pubDate>
      <link>https://dev.to/apfirebolt/deploy-your-mevn-mongodb-express-vue-and-node-application-on-a-server-using-docker-and-262c</link>
      <guid>https://dev.to/apfirebolt/deploy-your-mevn-mongodb-express-vue-and-node-application-on-a-server-using-docker-and-262c</guid>
      <description>&lt;p&gt;In this post, I would be discussing the approach I followed while deploying one of my hobby projects created using MEVN stack. For this to work you only need to have Docker installed on your system. We'd follow a container-based approach and deploy containers for each individual entity of our project. In case you're interested I'd be using the following project as a reference which I created using MEVN stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Apfirebolt/miniurl_mevn" rel="noopener noreferrer"&gt;https://github.com/Apfirebolt/miniurl_mevn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a user authentication-based URL shortener app. Logged-in users can submit longer URLs, and the app stores shortened versions of them in the database. Let's break it down into major components for which we need containers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Back-end written in Express&lt;/li&gt;
&lt;li&gt;MongoDB database&lt;/li&gt;
&lt;li&gt;Nginx as a reverse proxy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the front-end written in Vue, we won't be using a container. Instead, we'd be serving the build files using Express which would be containerized. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Build the front-end
&lt;/h2&gt;

&lt;p&gt;The front-end is written in Vue using Vite. Running the build command would collect the assets generated through Vue inside dist folder which would be served through Express.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Configure Express to serve Vue build
&lt;/h2&gt;

&lt;p&gt;In this file called server.js inside back-end folder following changes are made to instruct Express server to serve the build files found inside client/dist folder in case environment is "production".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import path from 'path';
import express from 'express';
import dotenv from 'dotenv';
dotenv.config();
import connectDB from './config/db.js';;

const port = process.env.PORT || 5000;

connectDB();

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

if (process.env.NODE_ENV === 'production') {
  const __dirname = path.resolve();
  app.use(express.static(path.join(__dirname, '/client/dist')));

  app.get('*', (req, res) =&amp;gt;
    res.sendFile(path.resolve(__dirname, 'client', 'dist', 'index.html'))
  );
} else {
  app.get('/', (req, res) =&amp;gt; {
    res.send('API is running....');
  });
}

app.listen(port, () =&amp;gt; console.log(`Server started on port ${port}`));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Add Dockerfile for Node
&lt;/h2&gt;

&lt;p&gt;Inside the root folder of the project a Dockerfile for serving Express application is created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use the official Node.js 22 image as the base image
FROM node:22

# Set the working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code to the working directory
COPY . .

# Expose port 5000
EXPOSE 5000

# Start the application
CMD ["npm", "start"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Node 22 is used as the base image. App folder is configured to be used as the project root folder. All the dependencies are installed, source files are copied and port 5000 is exposed for communication with other containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Creating a Docker-compose file
&lt;/h2&gt;

&lt;p&gt;We'd be spawning three services each for back-end, proxy-server and mongoDB database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'
services:
  express:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: express_miniurl
    ports:
      - 5000:5000
    depends_on:
      - mongo

  mongo:
    image: mongo
    container_name: mongo_miniurl
    restart: unless-stopped
    volumes:
      - ./mongo_data:/data/db
    ports:
      - '27017:27017'

  nginx:
    image: nginx
    container_name: nginx_miniurl
    restart: unless-stopped
    ports:
      - '80:80'
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - express

volumes:
  mongo_data:
    external: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first service we have is for the Node app which uses the Dockerfile we initialized in the previous step. The second service is for MongoDB, it uses the official Mongo image from the Docker hub. It exposes conventional port 27017 for communication with external containers as well as the host machine in case required. The container has also been explicitly named 'mongo_miniurl' and configured to keep on running unless stopped. It also uses volumes for data persistence as you might be aware that containers don't persist data once they're destroyed.&lt;/p&gt;

&lt;p&gt;The third service is an Nginx proxy server that directs traffic from ports 80 and 443 to port 5000, where the Express backend listens.&lt;/p&gt;

&lt;p&gt;Notably, the default nginx.conf file is overwritten with a configuration specifically crafted to enable communication with the Express backend. I'd get to this Nginx which resides inside the Nginx folder at the root level in this sample project.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Custom Nginx file
&lt;/h2&gt;

&lt;p&gt;In summary, this Nginx configuration file is designed to forward all HTTP requests received on port 80 to the Express backend listening on port 5000. It also sets essential headers to ensure proper communication between the client, Nginx, and the backend server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;events {
    worker_connections 1024; # Adjust as needed
}

http {
    upstream express {
        server express:5000;
    }

    server {
        listen 80;
        server_name localhost;

        location / {
            proxy_pass http://express;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Defining the upstream and configuring proxy_pass are key steps in this configuration file. The ability to use the name 'express' stems from its definition as a service name within the Docker Compose file used in the preceding step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;events {
    worker_connections 1024; # Adjust as needed
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worker_connections directive limits each Nginx worker to 1024 simultaneous client connections. This is suitable for development, but likely needs adjustment for production loads.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Configuration Settings adjustments
&lt;/h2&gt;

&lt;p&gt;This project utilizes environment variables defined in an .env file. Create one with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=development
PORT=5000
MONGO_URI="mongodb://mongo:27017/mevn_url_shortener"
JWT_SECRET=your-secret-here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MONGO_URI uses 'mongo' instead of 'localhost' because 'mongo' is the service name defined for our MongoDB database in the Docker Compose file. Docker Compose establishes an internal network, enabling containers to communicate using these service names as hostnames."&lt;/p&gt;

&lt;p&gt;That is it folks, you'd now be able to run the project through a simple docker-compose up command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application should be accessible on port 80 if there aren't any other applications using this port on your machine.&lt;/p&gt;

&lt;p&gt;Thank you for following along with this tutorial. If you have any questions or insights to share, please leave a comment below. I'd love to hear from you for any suggestions or improvements!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>docker</category>
      <category>vue</category>
      <category>express</category>
    </item>
    <item>
      <title>Cool AI-powered application ideas for your next project</title>
      <dc:creator>Lightning Bolt</dc:creator>
      <pubDate>Sat, 25 Mar 2023 06:23:46 +0000</pubDate>
      <link>https://dev.to/apfirebolt/cool-ai-powered-application-ideas-for-your-next-project-3em6</link>
      <guid>https://dev.to/apfirebolt/cool-ai-powered-application-ideas-for-your-next-project-3em6</guid>
      <description>&lt;p&gt;This post would be aimed at people having limited knowledge of AI and how they can still leverage AI features in their applications using the API provided by OpenAI, the organization behind ChatGPT.&lt;/p&gt;

&lt;p&gt;A good place to start would be to register on their website at &lt;a href="https://platform.openai.com/" rel="noopener noreferrer"&gt;https://platform.openai.com/&lt;/a&gt; and get your API key. Explore the examples page they have and you’d find 50+ cool ideas to try for your next AI-powered application. I’d list down my favourites from the list they have which I explored:-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Language conversion from English to Spanish&lt;/li&gt;
&lt;li&gt;Keyword extractor from paragraphs of text&lt;/li&gt;
&lt;li&gt;Item classifier based on categories&lt;/li&gt;
&lt;li&gt;Grammar correction&lt;/li&gt;
&lt;li&gt;Movie to emojis&lt;/li&gt;
&lt;li&gt;Ad from the product description&lt;/li&gt;
&lt;li&gt;Tweet classifier&lt;/li&gt;
&lt;li&gt;Javascript to Python&lt;/li&gt;
&lt;li&gt;Questions and Answers&lt;/li&gt;
&lt;li&gt;Explain code&lt;/li&gt;
&lt;li&gt;Interview Questions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They have a quick start guide where they illustrate how to build a ‘pet name generator‘ in Node JS here -&lt;br&gt;
 &lt;a href="https://platform.openai.com/docs/quickstart/closing" rel="noopener noreferrer"&gt;https://platform.openai.com/docs/quickstart/closing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I actually used this &lt;strong&gt;‘Interview Questions‘&lt;/strong&gt; model they had on the examples page. This would generate a list of questions for you based on the topic you provide in the text box. For instance, if you type something like “15 Most popular interview questions in Python“, it would reply back with 15 most popular interview questions in Python, exactly what you asked it for. You can try playing around with this here -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://platform.openai.com/playground/p/default-interview-questions?model=text-davinci-003" rel="noopener noreferrer"&gt;https://platform.openai.com/playground/p/default-interview-questions?model=text-davinci-003&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As of now, they have examples in &lt;strong&gt;Python&lt;/strong&gt; and &lt;strong&gt;Javascript&lt;/strong&gt;. They have packages available which you can use for testing. Mine was a simple app using React with just a payload being passed to the API in JSON format. Below is the excerpt I took from the application I built. This contains the payload I passed to the openAI end-point.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const jsonData = {&lt;br&gt;
    "model": "text-davinci-003",&lt;br&gt;
    "prompt": "Python interview questions",&lt;br&gt;
    "temperature": 0.5,&lt;br&gt;
    "max_tokens": 150,&lt;br&gt;
    "top_p": 1.0,&lt;br&gt;
    "frequency_penalty": 0.0,&lt;br&gt;
    "presence_penalty": 0.0&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;‘Model‘&lt;/strong&gt; key specifies which model to be used from the openAI API. “Prompt“ is the input sequence you pass into the model. The model then breaks down this sequence into granular pieces called ‘tokens‘ which are fed into the model to process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‘Temperature‘&lt;/strong&gt; parameter in Layman's terms simply means it controls the degree of randomness and creativity of the response generated by the model. A high-temperature value triggers more unpredictable outcomes from the model while a low value injects more confidence the model has in the most probable generated outcomes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‘Top_P‘&lt;/strong&gt; parameter is used for sampling the model outcomes based on cumulative probability distribution. For instance, a top_p of 0.3 means that only the tokens comprising the top 30% probability mass are considered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‘Frequency Penalty‘&lt;/strong&gt; limits the text from occurring further in the response based on the frequency of its presence till now in the response text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‘Presence Penalty‘&lt;/strong&gt; has a similar purpose to the ‘frequency penalty‘ except that it does not take the frequency of words into account while diminishing the relevance of keywords generated in the response text.&lt;/p&gt;

&lt;p&gt;This was just a basic explanation of the options you pass in the payload. To get more comfortable with it, the best way inevitably would be to just play around with the options and see the difference in the produced response. It definitely helps if you know statistics and machine learning concepts. Here’s the link for the project I implemented in Vue JS using this API for the folks who are interested:- &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Apfirebolt/ask-interview-questions-ai-in-vue" rel="noopener noreferrer"&gt;https://github.com/Apfirebolt/ask-interview-questions-ai-in-vue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You don't need a lot of AI knowledge to use this. This brings this post to the conclusion 🙂. If you like this post, please consider a reaction in form of a like or comment. Until then, see you in the next post 👋&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>machinelearning</category>
      <category>openai</category>
    </item>
    <item>
      <title>Why I choose CRA ( Create-react-app) over Vite for this React project ?</title>
      <dc:creator>Lightning Bolt</dc:creator>
      <pubDate>Tue, 14 Mar 2023 03:00:27 +0000</pubDate>
      <link>https://dev.to/apfirebolt/why-i-choose-cra-create-react-app-over-vite-for-this-react-project--cj8</link>
      <guid>https://dev.to/apfirebolt/why-i-choose-cra-create-react-app-over-vite-for-this-react-project--cj8</guid>
      <description>&lt;p&gt;You must have stumbled upon many posts praising Vite and how it should be the de-facto standard to get started with React apps. Vite is awesome, nothing wrong with it. But, sometimes I just believe when you're put into this decision-making situation, you should give yourself some time instead of blindly picking the new tech upgrade in the market and ditching the older one.&lt;/p&gt;

&lt;p&gt;I still use both CRA (create-react-app) and Vite for my React projects. In the organization (Mercedes Benz) I work, we had to start a new project from nothing. We had interns, and junior developers to collaborate with on that project. The project requirements were mostly already defined and were not likely to change in a short period. It was established to be a small to medium-sized full-stack application with an estimated completion time of two months. There weren't major performance-related concerns so I decided to pick CRA even though I, myself am a big admirer of Vite.&lt;/p&gt;

&lt;p&gt;CRA has been proven successful over these many years and got support from Facebook. It was easier to find help related to deployment, installation of new packages and more issues in case they show up in the development process (which they would). It is not an app which is likely to be in the development phase for a long period. Had that been the case, or we were likely to face performance-related issues in the long run because of the app being too bulky, I'd have opted to go with Vite. But, that wasn't the case here. Sticking with CRA ensures that we have more help available on the internet, less time spent on learning and more in development. Most packages have stable compatible versions with CRA available with proper documentation. So, why not stick with it?&lt;/p&gt;

&lt;p&gt;I've seen some developers blindly going for the upgrades in the market instead of considering the older technology while making architectural-level decisions in designing an application from scratch. In my opinion, it is completely fine to sometimes stick with older tech stack even while creating new applications. I'd bring Vue into the picture for a moment where there is a buzz in the market about why you should ditch Vue 2 ever since a stable version of Vue 3 has been released. But, why always? Why can't I use Vue 2.6 in my apps in 2023? Maybe there is a UI library that only has a stable version for Vue 2. It is your choice to still use Vue 2 or create-react-app, it is not obsolete and not likely to be so for the next few years. So relax, and use what you love. You should however have a pretty convincing reason to justify your choice.&lt;/p&gt;

&lt;p&gt;So, that's it for this post. Here, I just put my two cents on why it's fine to continue using existing technologies despite them having better upgrades available. If you have anything to say, please comment in the comments section. See you in the next post. 😀&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>vite</category>
      <category>webdev</category>
    </item>
    <item>
      <title>New python post</title>
      <dc:creator>Lightning Bolt</dc:creator>
      <pubDate>Thu, 13 Oct 2022 12:10:30 +0000</pubDate>
      <link>https://dev.to/apfirebolt/new-python-post-5def</link>
      <guid>https://dev.to/apfirebolt/new-python-post-5def</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0l27lrkobxgvisyqxpc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0l27lrkobxgvisyqxpc.jpg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another line after the post.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
