<?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: Thi Nguyen</title>
    <description>The latest articles on DEV Community by Thi Nguyen (@tttn13).</description>
    <link>https://dev.to/tttn13</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%2F984298%2Fc3215df6-9a43-490f-9613-b28af065b11a.png</url>
      <title>DEV Community: Thi Nguyen</title>
      <link>https://dev.to/tttn13</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tttn13"/>
    <language>en</language>
    <item>
      <title>Unlocking Productivity with MCP Servers and Claude: A Comprehensive Guide</title>
      <dc:creator>Thi Nguyen</dc:creator>
      <pubDate>Wed, 09 Apr 2025 10:28:13 +0000</pubDate>
      <link>https://dev.to/tttn13/unlocking-productivity-with-mcp-servers-and-claude-a-comprehensive-guide-2692</link>
      <guid>https://dev.to/tttn13/unlocking-productivity-with-mcp-servers-and-claude-a-comprehensive-guide-2692</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In recent years, the integration of artificial intelligence (AI) into software development and data management has revolutionized workflows across various industries. One key technology enabling this integration is the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;, which allows AI assistants like Claude to interact seamlessly with multiple data sources and tools. This article will explore how to set up an MCP server with Claude to work with local files, enhancing productivity and streamlining file management tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is MCP and Why Use It?
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Model Context Protocol&lt;/strong&gt; is an open standard designed to facilitate interactions between AI assistants and diverse data sources. Key benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Universal Access&lt;/strong&gt;: Query and retrieve data from multiple sources using a single protocol.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure, Standardized Connections&lt;/strong&gt;: Handles authentication and data formatting, eliminating the need for ad-hoc API connectors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sustainable Ecosystem&lt;/strong&gt;: Reusable connectors simplify development across multiple Large Language Models (LLMs).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Working with large language models like Claude often requires interacting with local files, but most AI interfaces don't support direct file uploads. Here's how to set up a local MCP (Model Control Protocol) server to enable Claude to work with your local files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Connect Claude to Local Files?
&lt;/h3&gt;

&lt;p&gt;Claude's web interface and API don't support file uploads directly. An MCP server acts as a bridge between your local files and Claude, allowing you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Process large files that exceed Claude's context window&lt;/li&gt;
&lt;li&gt;Maintain privacy by keeping files on your local machine&lt;/li&gt;
&lt;li&gt;Work with file formats that aren't supported in the chat interface&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Use Cases for MCP Server with Claude
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Intelligent Document Processing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Report Summarization&lt;/strong&gt;:
Example: &lt;em&gt;"Extract key insights from Q2_Financials.docx and highlight major trends"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured Data Analysis&lt;/strong&gt;:
Example: &lt;em&gt;"Convert sales_data.csv into a bullet-point summary with top performing products"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Comparison&lt;/strong&gt;:
Example: &lt;em&gt;"Compare draft_v1.txt and draft_v2.txt showing only the substantive changes"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Automated File Operations
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smart Organization&lt;/strong&gt;:
Example: &lt;em&gt;"Move all PDF invoices from Downloads to Documents/Finance/2024_Invoices"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch Renaming&lt;/strong&gt;:
Example: &lt;em&gt;"Rename all screenshot files in this folder with pattern 'YYYY-MM-DD_Screenshot_N'"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage Optimization&lt;/strong&gt;:
Example: &lt;em&gt;"Identify and delete all .tmp files older than 30 days in the project directory"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Development Workflow Enhancement
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Optimization&lt;/strong&gt;:
Example: &lt;em&gt;"Refactor utils.py to improve runtime performance with detailed comments"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Documentation&lt;/strong&gt;:
Example: &lt;em&gt;"Generate comprehensive README.md covering installation, usage, and API reference"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment Management&lt;/strong&gt;:
Example: &lt;em&gt;"Synchronize database credentials across all .env files in the microservices folder"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;p&gt;Before setting up the Filesystem MCP Server, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Desktop App&lt;/strong&gt; (available for macOS and Windows).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; (check with &lt;code&gt;node --version&lt;/code&gt;; download from nodejs.org).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic coding knowledge&lt;/strong&gt; (command-line operations, editing configuration files).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correct file system permissions&lt;/strong&gt; (read/write access to target files and directories).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 1: Install and Configure the Filesystem MCP Server
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Locate the Configuration File&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Open the &lt;strong&gt;Claude Desktop App&lt;/strong&gt; and go to &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;Developer&lt;/strong&gt; tab and click &lt;strong&gt;Edit Config&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Locate the &lt;code&gt;claude_desktop_config.json&lt;/code&gt; file:

&lt;ul&gt;
&lt;li&gt;macOS: &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Windows: &lt;code&gt;%APPDATA%\Claude\claude_desktop_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modify the Configuration File&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Open &lt;code&gt;claude_desktop_config.json&lt;/code&gt; in a text editor.&lt;/li&gt;
&lt;li&gt;Replace its contents with the following configuration, adjusting “username” and file paths as needed:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"filesystem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"@modelcontextprotocol/server-filesystem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"/Users/username/Documents"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;path&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"/Users/username/Downloads"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;path&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"restrictions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"maxFileSizeMB"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"allowedExtensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;".txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".csv"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Considerations&lt;/strong&gt;:&lt;br&gt;
    - &lt;strong&gt;Principle of Least Privilege&lt;/strong&gt;: Only include necessary directories.&lt;br&gt;
    - &lt;strong&gt;Extension Whitelisting&lt;/strong&gt;: Prevent accidental binary file modifications.&lt;br&gt;
    - &lt;strong&gt;Size Limits&lt;/strong&gt;: Avoid memory issues with large files.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Restart Claude
&lt;/h4&gt;

&lt;p&gt;Restart the &lt;strong&gt;Claude Desktop App&lt;/strong&gt; to apply configuration changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Verify Installation
&lt;/h4&gt;

&lt;p&gt;After restarting, look for a &lt;strong&gt;hammer icon&lt;/strong&gt; in the bottom-right of Claude’s input box. Clicking it should reveal available &lt;strong&gt;Filesystem MCP Server&lt;/strong&gt; tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the Filesystem MCP Server
&lt;/h3&gt;

&lt;p&gt;Now that the server is running, try these commands with Claude:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a file&lt;/strong&gt;: “Create a file &lt;code&gt;Desktop/test/hello_world.txt&lt;/code&gt; with 'Hello, World' as text.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Count files&lt;/strong&gt;: “How many files are in my Downloads folder?”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summarize a document&lt;/strong&gt;: “Summarize &lt;code&gt;report.txt&lt;/code&gt; from my Desktop folder.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manage files&lt;/strong&gt;: “Move &lt;code&gt;image.png&lt;/code&gt; from Desktop to Downloads.” “Rename all &lt;code&gt;.png&lt;/code&gt; files in Downloads to start with '2024-'.”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Claude will request your permission before making changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Troubleshooting
&lt;/h3&gt;

&lt;p&gt;If you encounter issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Restart Claude&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check JSON syntax&lt;/strong&gt; (&lt;code&gt;claude_desktop_config.json&lt;/code&gt;) using an online JSON validator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate file paths&lt;/strong&gt; (ensure they are absolute, not relative).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check logs&lt;/strong&gt; for errors:

&lt;ul&gt;
&lt;li&gt;macOS: &lt;code&gt;~/Library/Logs/Claude&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Windows: &lt;code&gt;%APPDATA%\Claude\logs&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Run the server manually&lt;/strong&gt; via the command line: &lt;code&gt;npx @modelcontextprotocol/server-filesystem&lt;/code&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;By connecting an MCP server to Claude, you streamline file interactions, automate workflows, and enhance productivity — all while keeping control over your data. This guide helps you get started with &lt;strong&gt;Model Context Protocol&lt;/strong&gt; and Claude for seamless local file management.&lt;/p&gt;

&lt;p&gt;⁂&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Slack Integration</title>
      <dc:creator>Thi Nguyen</dc:creator>
      <pubDate>Fri, 16 Aug 2024 16:56:36 +0000</pubDate>
      <link>https://dev.to/tttn13/slack-integration-4ehb</link>
      <guid>https://dev.to/tttn13/slack-integration-4ehb</guid>
      <description>&lt;p&gt;Let's make a SlackBot !!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. On Slack developer dashboard
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create your very own Slack workspace if not already, head over to this link &lt;a href="https://slack.com/help/articles/206845317-Create-a-Slack-workspace" rel="noopener noreferrer"&gt;https://slack.com/help/articles/206845317-Create-a-Slack-workspace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click on “Create a Slack app” to begin building your application &lt;/li&gt;
&lt;li&gt;Input your application name and select the workspace you just created or where you will be developing your app.&lt;/li&gt;
&lt;li&gt;After creating your app, Slack presents you with the ‘Basic Information’ page.&lt;/li&gt;
&lt;/ul&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%2F8l3radcmpz84dw3ji07e.png" 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%2F8l3radcmpz84dw3ji07e.png" alt="Image description" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&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%2Fdxzgzzenyflhmsc9y5fm.png" 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%2Fdxzgzzenyflhmsc9y5fm.png" alt="Image description" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Turn on Socket Mode &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proceed to OAuth and permissions on the sidebar to add scopes and obtain OAuth Token. For our use case, bot will be capable of chat:write&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2F0wnhx0x2jn18sui2evtt.png" 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%2F0wnhx0x2jn18sui2evtt.png" alt="Image description" width="800" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the app into the Slack workspace on Basic Information page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are 2 tokens: OAuth Token and App Level Token. The first one can be found on OAuth and permissions page. The latter can be found on Basic Information page &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Add SlackBot To Your Slack channel
&lt;/h2&gt;

&lt;p&gt;To add your bot to a channel, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inside Slack, locate your bot in the left-hand sidebar.&lt;/li&gt;
&lt;li&gt;Click on the dropdown arrow next to your bot’s name.&lt;/li&gt;
&lt;li&gt;Select “Add this app to a channel.”&lt;/li&gt;
&lt;li&gt;Choose the channel you want to add your bot to. In this case, we will select the desired channel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. In your project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install the above package to establish communication with Slack&lt;/li&gt;
&lt;li&gt;Create an &lt;code&gt;settings.json&lt;/code&gt; to store the secrets: OAuthToken and slack channel name. In our use case, we will have them in an azure function project in &lt;code&gt;local.settings.json&lt;/code&gt; file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "WEBSITE_TIME_ZONE": "AUS Eastern Standard Time",
        "SlackApiToken": "token",
        "SlackChannel": "#chanel"
    },
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reference&lt;br&gt;
[(&lt;a href="https://danieldonbavand.com/2023/05/03/how-to-create-a-custom-slack-bot-with-net-7/)" rel="noopener noreferrer"&gt;https://danieldonbavand.com/2023/05/03/how-to-create-a-custom-slack-bot-with-net-7/)&lt;/a&gt;]&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Install and deploy a Postgresql database for free</title>
      <dc:creator>Thi Nguyen</dc:creator>
      <pubDate>Thu, 16 Mar 2023 23:13:49 +0000</pubDate>
      <link>https://dev.to/tttn13/install-postgres-on-ubuntu-4b3i</link>
      <guid>https://dev.to/tttn13/install-postgres-on-ubuntu-4b3i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;At the time of writing this article, I was in need of a database for my personal project and AWS is one of the most popular choices. Before this I have never created a database server on a remote machine so I figured it would be a good opportunity to document it for future projects. This guide is meant for beginner.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We'll install a Postgresql database and host it on Ubuntu which is a Linux distribution. We'll first need to create the Ubuntu instance using AWS EC2 service. At the end of the tutorial, you should have a database ready to connect to other services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 : Create an Ubuntu EC2 instance
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the AWS Management Console and navigate to the EC2 dashboard.&lt;/li&gt;
&lt;li&gt;Click on the "Launch Instance" button to begin creating a new EC2 instance.&lt;/li&gt;
&lt;li&gt;Choose the Ubuntu AMI (Amazon Machine Image) you want to use. You can search for "Ubuntu" in the search bar and select the appropriate version of Ubuntu that you want to use.&lt;/li&gt;
&lt;/ol&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%2Fehxpqdiubzj481bdfb4x.png" 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%2Fehxpqdiubzj481bdfb4x.png" alt="Image description" width="800" height="681"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select the instance type you want to use based on your requirements. I pick instance type t2.micro for 1GB free of memory&lt;/li&gt;
&lt;li&gt;Configure the instance details. This includes setting the number of instances you want to launch, network settings, storage options, and other advanced settings.&lt;/li&gt;
&lt;li&gt;Configure security group settings. This includes setting up inbound and outbound rules to allow traffic to and from your instance.&lt;/li&gt;
&lt;li&gt;Review your instance configuration and launch the instance.&lt;/li&gt;
&lt;li&gt;Choose or create a key pair that will be used to authenticate SSH connections to the instance. You can do so either by going to Network &amp;amp; Security -&amp;gt; Key Pairs or select Create new Key Pair in the same modal as Key Pairs when creati
ng the instance.&lt;/li&gt;
&lt;/ol&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%2F29woccx3bo6xlysh0o07.png" 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%2F29woccx3bo6xlysh0o07.png" alt="Image description" width="800" height="841"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once your instance is launched, you can connect to it using SSH and follow the instructions provided in this document to install PostgreSQL on your Ubuntu instance.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2: Connect to your EC2 instance
&lt;/h2&gt;

&lt;p&gt;To connect to your EC2 instance, you can use a terminal program such as SSH. You will need to have the private key associated with your EC2 instance to authenticate. You can use the following command to connect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i /path/to/private/key.pem ubuntu@your-ec2-instance-ip-address

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the key file is stored in the Downloads directory, you'll likely see this error message&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for '/Users/username/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because the key.pem file is stored in a unsecured location (Downloads folder) and the SSH client does not allow the use of private keys accessible by others. We need to update the access permissions of the key file to allow reading by you via the chmod command (The name chmod is short for “change mode”).&lt;/p&gt;

&lt;p&gt;Default username of the ubuntu server is ubuntu. Run the command to change the permissions and connect to the instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 400 ssh -i /path/to/private/key.pem ubuntu@your-ec2-instance-ipv4-address

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you got a warning the authenticity of host is not established do you want to connect, answer &lt;strong&gt;Yes .&lt;/strong&gt; You are now connected !&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Update your system
&lt;/h2&gt;

&lt;p&gt;Once you have successfully logged into the machine, before installing any software, it is recommended to update your system to ensure that you have the latest security patches and bug fixes. You can do this by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Install PostgreSQL
&lt;/h2&gt;

&lt;p&gt;To install PostgreSQL on Ubuntu, you can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install postgresql postgresql-contrib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will install PostgreSQL and its accompanying tools and libraries. During the installation process, you may be prompted to create a password for the PostgreSQL administrative user (postgres). Make sure to remember this password, as you will need it to log in to your database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Verify the installation
&lt;/h2&gt;

&lt;p&gt;To verify that PostgreSQL has been installed correctly, you can use the following command to check its version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql --version

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should output the version number of PostgreSQL that you have installed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 : Create an Ubuntu user in PostgreSQL service
&lt;/h2&gt;

&lt;p&gt;After installing PostgreSQL, the service should automatically start. However, if you need to start or stop the service manually, you can use the following commands:&lt;/p&gt;

&lt;p&gt;To start the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start postgresql

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To stop the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl stop postgresql

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have now successfully installed PostgreSQL on your Ubuntu EC2 instance. You can now start using it to create and manage your databases. &lt;/p&gt;

&lt;p&gt;To connect to Postgres, switch to the &lt;code&gt;postgres&lt;/code&gt; user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo -i -u postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a Postgres database user run the following command which will give an interactive prompt for configuring the new user called &lt;code&gt;ubuntu&lt;/code&gt;. For the sake of simplicity, the &lt;code&gt;ubuntu&lt;/code&gt; user will be a superuser, which is the equivalent of being a root user on linux. The super user will have the ability to create/delete/modify databases and users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;createuser --interactive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prompt ask for the name of new user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter name of role to add: ubuntu
Shall the new role be a superuser? (y/n) y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log in to postgres using the &lt;code&gt;postgres&lt;/code&gt; user for now to verify the new &lt;code&gt;ubuntu&lt;/code&gt; user was created successfully&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres@ipv4.address.EC2.instance:~$ psql
psql (12.4 (Ubuntu 12.4-0ubuntu0.20.04.1))
Type "help" for help.

postgres=# \\du
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

 ubuntu    | Superuser, Create role, Create DB                          | {}

postgres=#

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit out of the &lt;code&gt;psql&lt;/code&gt; by running &lt;code&gt;\\q&lt;/code&gt; and also exit out of the postgres user by running &lt;code&gt;exit&lt;/code&gt; on the command line. Let's try to run psql as the ubuntu user now. An error similar to the one below should be observed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql: error: could not connect to server: FATAL:  database "ubuntu" does not exist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason for this is that Postgres by default tries to connect to a database that is the same name as the user. Since the user is &lt;strong&gt;ubuntu&lt;/strong&gt; it tries to connect to a database called &lt;strong&gt;ubuntu&lt;/strong&gt; as well which does not exist. Instead we can pass in the -d flag and connect to a database that we know exists, like &lt;code&gt;postgres&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql -d postgres

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right now the ubuntu user in Postgres does not have a password associated with it. We will need to add a password like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER USER ubuntu PASSWORD 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: Allow connections to PostgreSQL
&lt;/h2&gt;

&lt;p&gt;To allow remote connections to PostgreSQL on your Ubuntu EC2 instance, you need to modify the PostgreSQL configuration file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the configuration file with the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /etc/postgresql/&amp;lt;version&amp;gt;/main/postgresql.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Replace &lt;code&gt;&amp;lt;version&amp;gt;&lt;/code&gt; with the version number of PostgreSQL that you have installed (e.g. 11).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the line that starts with &lt;code&gt;listen_addresses&lt;/code&gt; and uncomment it by removing the &lt;code&gt;#&lt;/code&gt; symbol at the beginning of the line.&lt;/li&gt;
&lt;li&gt;Change the value of &lt;code&gt;listen_addresses&lt;/code&gt; to &lt;code&gt;“*”&lt;/code&gt; to allow connections from any IP address.&lt;/li&gt;
&lt;li&gt;Save and close the file.&lt;/li&gt;
&lt;li&gt;Next, you need to modify the &lt;code&gt;pg_hba.conf&lt;/code&gt; file to allow connections from remote hosts.&lt;/li&gt;
&lt;li&gt;Open the &lt;code&gt;pg_hba.conf&lt;/code&gt; file with the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following line at the end of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;host    all             all             0.0.0.0/0               md5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: This line will allow connections from any IP address. If you want to restrict access to specific IP addresses, replace &lt;code&gt;0.0.0.0/0&lt;/code&gt; with the appropriate IP address range.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Save and close the file.&lt;/li&gt;
&lt;li&gt;Restart the PostgreSQL service for the changes to take effect:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now be able to connect to your PostgreSQL server from a remote host by specifying the IP address of your EC2 instance as the host name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8 : Open the port in the AWS dashboard
&lt;/h2&gt;

&lt;p&gt;To add an inbound rule on your EC2 instance to allow all connections on Postgres port 5432, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the AWS Management Console and navigate to the EC2 dashboard.&lt;/li&gt;
&lt;li&gt;Select the instance that you want to modify.&lt;/li&gt;
&lt;li&gt;Click on the "Security" tab at the bottom of the page.&lt;/li&gt;
&lt;li&gt;Select the security group associated with your instance.&lt;/li&gt;
&lt;li&gt;Click on the "Edit inbound rules" button.&lt;/li&gt;
&lt;li&gt;Click on the "Add rule" button.&lt;/li&gt;
&lt;li&gt;Select "PostgreSQL" from the "Type" dropdown menu.&lt;/li&gt;
&lt;li&gt;Leave the "Source" field as "Anywhere" to allow all connections, or specify a specific IP address or range to restrict connections to specific hosts. Source &lt;code&gt;0.0.0.0/0&lt;/code&gt; will accept all the incoming requests&lt;/li&gt;
&lt;/ol&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%2Fmmx37cttcfyzx8cpen3p.png" 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%2Fmmx37cttcfyzx8cpen3p.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mmx37cttcfyzx8cpen3p.png" width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the "Save rules" button.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You should now be able to connect to your PostgreSQL server from any IP address on port 5432.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 9 : Connect the database to your app service
&lt;/h2&gt;

&lt;p&gt;I used a database management tool/viewer called &lt;a href="https://tableplus.com/download" rel="noopener noreferrer"&gt;Tableplus&lt;/a&gt; to interact with the db and run sql commands. Add a connection and test it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host: Public IPv4 DNS of the EC2 instance
User: ubuntu
Password: password
Port: 5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click Test, if everything is good, then Connect&lt;/p&gt;

&lt;p&gt;Once connection is set up using &lt;code&gt;Tableplus&lt;/code&gt;, we can run sql query to create db :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt; &lt;span class="n"&gt;testdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your PostgreSQL db is ready to connect to your app back end. You will need to provide your app the following vars so it can connect to the db.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DATABASE_NAME: testdb
HOST: Public IPv4 DNS of the EC2 instance
USER: ubuntu
PASSWORD: password
PORT: 5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Dockerize full stack React app</title>
      <dc:creator>Thi Nguyen</dc:creator>
      <pubDate>Tue, 14 Mar 2023 22:06:13 +0000</pubDate>
      <link>https://dev.to/tttn13/dockerize-full-stack-react-app-44ej</link>
      <guid>https://dev.to/tttn13/dockerize-full-stack-react-app-44ej</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Say you have finished your React project and you want to run it but you don't want to do it locally, what should you do? Your codebase is on github - great! We need to find a different way to publish the project remotely. This is useful if someone wanted to run the service from their machine, here comes Docker - arguably the most useful tool ever created haha jk. We just need to fetch the docker container, run it and we have our service ready . &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the structure of my app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-app
|_server
|__client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to create separate Dockerfile for client and server app. I also used a postgresql database hence we need to set it up.  &lt;/p&gt;

&lt;p&gt;In the client, create a file called Dockerfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:16

WORKDIR /usr/app

COPY package*.json ./

RUN npm ci -qy
RUN npm run build

COPY . .

EXPOSE 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next step is to build the image and push it to Dockerhub. &lt;br&gt;
Run the following commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build . -t username/my-app-react
docker push username/my-app-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to server folder, create another Dockerfile 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;FROM node:16
WORKDIR /usr/src/app

COPY package*.json ./

RUN npm ci --only=production
COPY . .
EXPOSE 8800
CMD [ "node", "server.js" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repeat the step to build and push the image&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build . -t username/my-app-api
docker push username/my-app-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need a docker-compose file to define and tell docker to launch all the necessary services for our full stack app, including the database.&lt;/p&gt;

&lt;p&gt;Navigate to the root directory, in my case it was the server folder, create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file, add the following&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:
  pgdatabase:
    image: postgres:14.1-alpine
    restart: unless-stopped
    env_file: ./.env.development
    ports:
      - '5432:5432'
    volumes: 
      - db:/var/lib/postgresql/data
  backend:
    depends_on:
      - pgdatabase
    image: "username/my-app-api"
    env_file:
        "./.env.development"
    build:
      context: ./
      dockerfile: ./Dockerfile
    ports:
      - "8800:8800"
  frontend:
    depends_on:
      - backend
    image: "username/my-app-react"
    env_file:
        "./social-app-client/.env"
    build:
      context: ./client
      dockerfile: ./Dockerfile
    ports:
      - "3000:3000"
    links:
      - "backend:be"
volumes: 
  db:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the server folder, start up docker-compose&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 -f docker-compose.yml up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Connect Redis with Node app</title>
      <dc:creator>Thi Nguyen</dc:creator>
      <pubDate>Thu, 09 Mar 2023 22:40:26 +0000</pubDate>
      <link>https://dev.to/tttn13/connect-to-a-redis-remote-server-3l4j</link>
      <guid>https://dev.to/tttn13/connect-to-a-redis-remote-server-3l4j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I wanted to use an in memory key value pair storage for my personal project since I never got to use one at work. I chose Redis just because it's a long established and well supported service. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I have Redis hosted on a remote ubuntu server.&lt;/p&gt;

&lt;p&gt;There's some configuration that we have to modify. Follow this &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-20-04" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; to properly configure Redis so it can accept connections.&lt;/p&gt;

&lt;p&gt;In order to connect my Node app to the remote Redis instance, we need to install &lt;code&gt;redis&lt;/code&gt; and &lt;code&gt;redis-om&lt;/code&gt; packages in our Node app. &lt;br&gt;
First, define the connection URL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require("dotenv").config();

const URL = `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REDIS_HOST&lt;/strong&gt; : the public IP address of the server. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REDIS_PORT&lt;/strong&gt; : the Port that Redis was exposed to on the server, by default it's &lt;code&gt;6379&lt;/code&gt;. In my case, the Redis host is the public IP of the EC2 instance. But in order to open port &lt;code&gt;6379&lt;/code&gt; of my remote ubuntu server, I have to add an inbound rule on the AWS dashboard. Click &lt;a href="https://dev.to/tttn13/install-postgres-on-ubuntu-4b3i"&gt;here&lt;/a&gt; to see how I did it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//index.js

const init = async () =&amp;gt; {
  const redisClient = require("redis").createClient({
    url: URL,
  });
  await redisClient.on("error", (err) =&amp;gt;
    console.log("Redis Client Error", err)
  );

  await redisClient.connect();
  if (redisClient.isReady) {
    console.log("client is ready");
  }
  await redisClient.set("key", "testvalue");
  const value = await redisClient.get("key");
  console.log("value is", value);
  await redisClient.disconnect();
};

init();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're like me and you don't have a password enabled for your redis, you will probably see something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ErrorReply: DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a an authentication password for the default user. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow one of the suggested solutions mentioned above then rerun the redis server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart redis-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your app again and it should be working. You are now connected to Redis ! &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploy full stack React app on Heroku</title>
      <dc:creator>Thi Nguyen</dc:creator>
      <pubDate>Tue, 07 Mar 2023 21:29:18 +0000</pubDate>
      <link>https://dev.to/tttn13/deploy-full-stack-react-app-on-heroku-575p</link>
      <guid>https://dev.to/tttn13/deploy-full-stack-react-app-on-heroku-575p</guid>
      <description>&lt;p&gt;We're gonna deploy our full stack React app in the same Heroku app. The back end is a Node express app, while the front end is a react app. The outcome of the deployment is that our backend would live on &lt;code&gt;https://react-app-name.herokuapp.com/api&lt;/code&gt; and our client can be accessed by public via &lt;code&gt;https://react-app-name.herokuapp.com&lt;/code&gt;. I have my Postgresql database set up on a unbuntu server. Click &lt;a href="https://dev.to/tttn13/host-a-postgresql-database-on-ubuntu-server-using-ec2-3dfi"&gt;here&lt;/a&gt; if you would like to learn more.&lt;/p&gt;

&lt;p&gt;This is the structure of my app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app
|_server
|__client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Create a Heroku account
&lt;/h3&gt;

&lt;p&gt;Sign up for a Heroku account. You need to add a credit card in order to create an app but it's not gonna cost anything to deploy the app. There's used to be a free tier plan that we can use to add Postgresql db service which made everything so much simpler, however they scrapped that, hence I chose to host the db on a virtual machine. &lt;/p&gt;

&lt;p&gt;Click New -&amp;gt; Create New App and choose a name for it. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add the config vars
&lt;/h3&gt;

&lt;p&gt;In the Settings section of the app on heroku, add the env variables needed to run your app. &lt;/p&gt;

&lt;p&gt;In my case, since I have the db hosted on an aws ec2 instance, I have the following variables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_BASE_URL=/api
PG_USER=ubuntu
PG_PASSWORD=password
PG_HOST=dbhost
PG_PORT=5432
PG_DATABASE=dbname
PG_DIALECT=postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Configure the Node server app
&lt;/h3&gt;

&lt;p&gt;Add a &lt;code&gt;Procfile&lt;/code&gt; file at the root of our project which is where the &lt;code&gt;package.json&lt;/code&gt; for the server app lives. The reason I have to make a distinction is because I have my server folder nested in a parent folder that doesn't have a &lt;code&gt;package.json&lt;/code&gt;. &lt;code&gt;Procfile&lt;/code&gt; will tell heroku how to run the app when it's deployed to heroku. &lt;code&gt;node server.js&lt;/code&gt; is how the server app is launched. If the main point of entry of your program is called differently, change the script to &lt;code&gt;node point-of-entry.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the Procfile, add the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: node server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Deploy the app
&lt;/h3&gt;

&lt;p&gt;I assumed that you already have git initialized on your project otherwise run &lt;code&gt;git init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After committing all the code to your gh repo, run  &lt;code&gt;heroku git:remote -a heroku-app-name&lt;/code&gt;. Replace &lt;code&gt;heroku-app-name&lt;/code&gt; with the name of your heroku app. &lt;/p&gt;

&lt;p&gt;Like mentioned above, I have my backend directory in another directory, hence I have to adjust the command to deploy the code to the remote heroku.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git subtree push --prefix server-folder heroku main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your app doesn't have the same structure, you can just run the below and it should be good.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push heroku main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's gonna take a while to deploy your app. Inspect the logs on heroku if you encounter any issue.&lt;/p&gt;

&lt;p&gt;If everything is done correctly, you should have a live app. &lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
