<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Irene Ufia on Medium]]></title>
        <description><![CDATA[Stories by Irene Ufia on Medium]]></description>
        <link>https://medium.com/@devopsinsight?source=rss-5acd9462a16c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*JW03FZt3g779nksm-F5T0w.jpeg</url>
            <title>Stories by Irene Ufia on Medium</title>
            <link>https://medium.com/@devopsinsight?source=rss-5acd9462a16c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 13 Jun 2026 07:17:03 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@devopsinsight/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[If You’re Still Deploying to Share Dev Previews in 2025, You’re Doing Too Much]]></title>
            <link>https://towardsdev.com/if-youre-still-deploying-to-share-dev-previews-in-2025-you-re-doing-too-much-edbff4cf8af7?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/edbff4cf8af7</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[localhost]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Fri, 18 Jul 2025 10:01:30 GMT</pubDate>
            <atom:updated>2025-07-18T13:55:52.599Z</atom:updated>
            <content:encoded><![CDATA[<p>As a developer, when working locally and the feature’s coming together.</p><p>What do you do when you want someone, maybe a teammate, a designer, or a friend, to take a quick look.</p><p>Do you:</p><p>a) Push to staging?</p><p>b) Set up a tunnel?</p><p>c) Send screenshots?</p><p>d) None of the above?</p><p>If you use VS Code, there’s a faster way sitting right there: <strong>Forward Port.</strong></p><p>It’s not a replacement for proper deployment. It won’t give you production parity. But when you just need to share your dev environment quickly, this is one of the cleanest ways to do it.</p><h3>How it works:</h3><ul><li>Start your dev app in VS Code (localhost:1111, for example).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xfziN5YLRu6M_Pkt_fsI2A.png" /></figure><ul><li>Open “PORTS” in the terminal of your Vs Code, click “forward a port,” and input your port number for your app.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vZRLv9sEvHDQ3kbyYwmz2w.png" /></figure><ul><li>VS Code gives you a public URL. Share it.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UTa8pnizm-4ZsCf1LYCDaw.png" /></figure><p>That’s it. Someone else can now view your local build—no staging, no CLI tunnels, no delays.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rBh6VX0EodWDZlxljldYqg.png" /></figure><p><strong>Whenever you need quick feedback from a teammate. Want to test on your phone without pushing? Maybe you’re just trying to debug something that only happens on your end. VS Code’s Forward Port makes all of that easier. It’s perfect for sharing isolated features, getting real-time input, or previewing your app on another device without touching your CI/CD pipeline. You’re not replacing deployment, just skipping the overhead when all you need is a short-lived link to your dev box. The best part is it’s built right into VS Code. No plugins, no setup, no ngrok. Just right-click, forward the port, and share.</strong></p><p><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure)</em>.</p><p><em>Follow me for insights and technical tips: </em><a href="https://www.linkedin.com/in/covenantireneufia"><em>LinkedIn</em></a><em> | </em><a href="https://github.com/UfiairENE"><em>Github</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=edbff4cf8af7" width="1" height="1" alt=""><hr><p><a href="https://towardsdev.com/if-youre-still-deploying-to-share-dev-previews-in-2025-you-re-doing-too-much-edbff4cf8af7">If You’re Still Deploying to Share Dev Previews in 2025, You’re Doing Too Much</a> was originally published in <a href="https://towardsdev.com">Towards Dev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Docker Model Runner: Running AI Locally Just Got Better]]></title>
            <link>https://towardsdev.com/docker-model-runner-running-ai-locally-just-got-better-8aaefabedcff?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8aaefabedcff</guid>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Fri, 04 Apr 2025 23:16:25 GMT</pubDate>
            <atom:updated>2025-04-07T13:13:29.100Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PZIZ3gNFgQQPk1E8ySR2eg@2x.jpeg" /></figure><p>Remember when AI first blew up, and everyone was scrambling to run models on their own machines? Yeah, it wasn’t fun. Between setting up dependencies, dealing with hardware limitations, and watching my laptop nearly combust under the weight of an LLM, I gave up and turned to <a href="https://huggingface.co/docs/inference-providers/en/index">inference APIs</a> like most people. Running AI locally just wasn’t worth the hassle.</p><p>But now, Docker Model Runner is making that struggle a thing of the past.</p><h3>What Is Docker Model Runner?</h3><p>Docker Model Runner is a new feature in Docker Desktop that lets you run AI models locally without the usual headaches. It treats models as first-class Docker objects, similar to containers, images, or volumes. With a few simple commands, you can pull an AI model and run it right from your terminal.</p><p>The best part? It’s designed for efficiency, loading models into memory only when needed and running them on demand.</p><h3>Why Running AI Locally Was a Nightmare</h3><p>Before this, trying to run AI models locally was a disaster for most of us.</p><p>Some of us experienced:</p><ul><li><strong>Hardware Struggles: </strong>If you didn’t have a powerful GPU, forget about it. Running models on a CPU was painfully slow.</li><li><strong>Dependency Hell: </strong>Setting up TensorFlow, PyTorch, or other frameworks was a never-ending battle with version conflicts.</li><li><strong>High Resource Consumption: </strong>Even if you got a model running, it could slow your entire system to a crawl.</li><li><strong>Privacy Concerns:</strong> Sending data to cloud inference APIs meant you had to trust third parties with sensitive inputs.</li></ul><h3>How Docker Model Runner Fixes Everything</h3><p>Docker Model Runner removes all that friction by making AI models as easy to work with as Docker containers.</p><ul><li><strong>No Setup Drama: </strong>No more fighting with dependencies. Just pull a model and run it.</li><li><strong>Hardware Acceleration:</strong> Takes advantage of your Mac’s GPU capabilities.</li><li><strong>Works On-Demand:</strong> Models load into memory only when needed, keeping resource usage efficient.</li><li><strong>Fully Local:</strong> No cloud required. Your data stays on your machine, improving privacy.</li></ul><h3>Real-World Applications</h3><p>How professionals can use Docker Model Runner:</p><ul><li>Developers can quickly test AI capabilities locally during development.</li><li>Data scientists can run iterations on datasets without cloud costs.</li><li>Content creators can generate content with complete privacy.</li><li>Teams can experiment with AI models before investing in cloud infrastructure.</li></ul><blockquote><strong>For example, you could use it to build a simple chatbot application, process documents with AI assistance, or analyze data (all running locally on your Mac.)</strong></blockquote><h3>System Requirements &amp; Supported Features</h3><p>According to the official <a href="https://docs.docker.com/desktop/features/model-runner/">documentation</a>:</p><ul><li><strong>Platforms: </strong>Currently available only on Docker Desktop for Mac (Apple Silicon).</li><li><strong>Models: </strong>Supports LLM models like Llama, Mistral, and more through the ollama engine.</li><li><strong>Hardware Acceleration: </strong>Uses GPU acceleration when available on supported Mac platforms.</li><li><strong>Model Repository:</strong> Models can be pulled from the Docker Hub registry.</li></ul><h3>Getting Started (It’s Super Easy)</h3><p><strong>1. Update Docker:</strong> Make sure you’re running Docker Desktop Desktop 4.40 and later on Mac.</p><p><strong>2. Enable Model Runner:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/530/1*5zFzWgqZ2hBIX1ZVMApk1w@2x.jpeg" /></figure><p>It’s enabled by default in Docker Desktop; else enable, apply and restart</p><p><strong>3. Link the CLI Plugin (for Mac users):</strong></p><pre>ln -s /Applications/Docker.app/Contents/Resources/cli-plugins/docker-model ~/.docker/cli-plugins/docker-model</pre><p><strong>4. Use the Docker CLI commands:</strong></p><ul><li><strong>Pull a Model:</strong></li></ul><pre>docker model pull ai/llama3.1</pre><ul><li><strong>List available Models:</strong></li></ul><pre>docker model list</pre><ul><li><strong>Run a Model with a prompt:</strong></li></ul><pre>docker model run ai/llama3.1 &quot;What is Docker?&quot;</pre><p><strong>5. Remove Model:</strong></p><p>You can remove a downloaded model from your system using the command</p><pre>docker model rm ai/llama3.1</pre><p>Docker Desktop also provides a built-in chat interface to interact with your models, making the process even smoother.</p><h3>Integrating Docker Model Runner into Your Software Development Lifecycle</h3><p>If you’re ready to build your own Generative AI application, Docker Model Runner makes it easier than ever to get started. Just started using it to power my local GenAI projects, and I can confidently say it simplifies the entire process.</p><p>To give it a try, I recommend starting with an existing GenAI app that demonstrates the potential of Docker Model Runner. Here’s how I got it running on my local machine:</p><p><strong>1. Set up the Sample App:</strong></p><p>Clone the repository for the sample GenAI app. Run the following command in your terminal:</p><pre>git clone https://github.com/docker/hello-genai.git</pre><p><strong>2. Navigate to the App Directory:</strong></p><pre>cd hello-genai</pre><p><strong>3. Run the App:</strong></p><p>Simply run the run.sh script to pull the selected model and start the application. It is seamless, no manual configuration needed:</p><pre>./run.sh</pre><p><strong>4. Access the App:</strong></p><p>Follow the instructions in the repository’s <a href="https://github.com/docker/hello-genai/blob/main/README.md">README</a>. Once the app is up and running, open it in your browser.</p><p>It’s ready for use, and the interface lets you start typing prompts right away.</p><p>For me, what’s exciting is how fast the responses were. Everything was happening locally on my machine, powered by Docker and the local model. I could immediately interact with my GenAI app and see the results without waiting for cloud-based processing.</p><p>This process is incredibly simple, but the results are impactful. Docker Model Runner is helping me speed up development while keeping everything under my control. If you’re looking to create your own AI-powered applications, I highly recommend getting started with this approach!</p><h3>Summary</h3><p>Docker Model Runner makes working with AI models locally much easier. By removing the setup and dependency issues, it allows for smoother workflows and faster results. With Docker, you can run models directly on your machine, taking advantage of hardware acceleration where available and maintaining control over your resources. You don’t need to rely on cloud-based APIs anymore, meaning your data stays secure and local.</p><p>Whether you’re developing AI-powered applications, experimenting with models, or running analysis;</p><blockquote><strong>Docker Model Runner offers a more efficient and private alternative to cloud-based solutions. It makes it easier to run LLM models on your machine without the usual hassle and complexities, putting you in full control of your AI workflows.</strong></blockquote><p><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure)</em>.</p><p><em>Follow me for insights and technical tips: </em><a href="https://www.linkedin.com/in/covenantireneufia"><em>LinkedIn</em></a><em> | </em><a href="https://github.com/UfiairENE"><em>Github</em></a></p><p>Thanks to <a href="https://www.linkedin.com/in/aniekutmfongodwin?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=ios_app">Anies</a> , <a href="https://www.linkedin.com/in/onionsman?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=ios_app">Onionsman</a> and <a href="https://www.linkedin.com/in/chigozie-nwokoye?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=ios_app">Chigozie Nwokoye </a>for reading drafts.</p><p><strong>More resources:</strong></p><ul><li><a href="https://www.docker.com/blog/docker-desktop-4-40/">Docker Blog Post</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8aaefabedcff" width="1" height="1" alt=""><hr><p><a href="https://towardsdev.com/docker-model-runner-running-ai-locally-just-got-better-8aaefabedcff">Docker Model Runner: Running AI Locally Just Got Better</a> was originally published in <a href="https://towardsdev.com">Towards Dev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fixing “Self-Signed Certificate in Certificate Chain” Error in NestJS with Managed Databases]]></title>
            <link>https://towardsdev.com/fixing-self-signed-certificate-in-certificate-chain-error-in-nestjs-with-managed-databases-5fe40b2d276c?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/5fe40b2d276c</guid>
            <category><![CDATA[nestjs]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[postgresql]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Thu, 27 Mar 2025 07:34:19 GMT</pubDate>
            <atom:updated>2025-04-07T13:25:08.162Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KwtcnBwaBlQd4WdaL8KuWw@2x.jpeg" /></figure><p>In my years as a DevOps engineer, I’ve learned that anticipating production challenges is the key to avoiding disaster. Recently, while working on a NestJS application, we encountered a scenario that underscored this lesson. The developers had thoroughly tested their code using a local PostgreSQL instance, and everything appeared to work flawlessly. However, when we reconfigured our development environment to mimic production by connecting to a managed PostgreSQL database (hosted on DigitalOcean), our application refused to connect and immediately threw this error:</p><pre>ERROR [TypeOrmModule] Unable to connect to the database. Retrying...<br>Error: self-signed certificate in certificate chain<br>    at TLSSocket.onConnectSecure (node:_tls_wrap:1674:34)</pre><p>This wasn’t a mistake in our code; but a direct consequence of managed databases enforcing SSL by default — a critical security measure that local, self-hosted databases often bypass.</p><h3>Understanding the Root Cause</h3><p>The error occurred because <strong>Node.js did not trust the SSL certificate provided by the managed database.</strong></p><p>Most cloud providers whether it’s <strong>AWS RDS, Azure Database, or DigitalOcean</strong> use their own <strong>Certificate Authority (CA)</strong> to sign database certificates. These custom CAs are <strong>not</strong> included in Node.js’s default trusted certificate store, causing SSL validation failures when attempting to connect securely.</p><h3>Why You Shouldn’t Disable SSL Verification</h3><p>A common but dangerous workaround is to disable SSL verification entirely by setting:</p><pre>NODE_TLS_REJECT_UNAUTHORIZED=0</pre><p>However, <strong>this is a security risk</strong> and effectively disables certificate validation, leaving your application vulnerable to <strong>man-in-the-middle attacks.</strong></p><p>Instead, a <strong>better approach</strong> is to explicitly provide Node.js with the correct CA certificate using the NODE_EXTRA_CA_CERTS environment variable.</p><h3>The Solution: Using NODE_EXTRA_CA_CERTS</h3><p>The NODE_EXTRA_CA_CERTS environment variable allows you to extend the list of trusted certificate authorities <strong>without modifying your application code</strong>.</p><h4>Step 1: Obtain the CA Certificate</h4><p>Each cloud provider offers its CA certificate for download. Here’s where to find them:</p><ul><li><strong>DigitalOcean</strong>: Available under the database cluster’s <strong>“Connection Details”</strong></li><li><strong>AWS RDS</strong>: Regional CA certificates can be downloaded from <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html">AWS documentation</a></li><li><strong>Azure Database</strong>: Downloadable from <a href="https://docs.azure.cn/en-us/postgresql/flexible-server/concepts-networking-ssl-tls#configure-ssl-on-the-client">Microsoft’s official documentation</a></li></ul><p>Save the CA certificate to a secure location on your local machine or server.</p><h4>Step 2: Set the NODE_EXTRA_CA_CERTS Environment Variable</h4><p>Before running your application, set the environment variable to point to the downloaded CA certificate.</p><p><strong>For</strong> <strong>Linux/macOS:</strong></p><pre>export NODE_EXTRA_CA_CERTS=/path/to/ca-certificate.crt</pre><p><strong>For Windows (Command Prompt):</strong></p><pre>set NODE_EXTRA_CA_CERTS=C:\path\to\ca-certificate.crt</pre><p><strong>For Windows (PowerShell)</strong>:</p><pre>$env:NODE_EXTRA_CA_CERTS=&quot;C:\path\to\ca-certificate.crt&quot;</pre><h4>Step 3: Run Your Application</h4><p>Now, when you start your application:</p><pre>npm run start</pre><p>Node.js will use the provided CA certificate to establish a secure connection with the database.</p><h3>Permanent Configuration for Different Environments</h3><h4>1. For Development Environments:</h4><p>To avoid manually setting the variable every time, add it to your .env file:</p><pre>NODE_EXTRA_CA_CERTS=/path/to/ca-certificate.crt<br>DATABASE_URI=postgresql://username:password@hostname:port/database?sslmode=require</pre><h4>2. For Production Deployments:</h4><h4>Docker Containers</h4><p>Modify your Dockerfile to copy the CA certificate and set the environment variable:</p><pre>COPY ./ca-certificates/database-ca.crt /etc/ssl/certs/<br>ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/database-ca.crt</pre><h4>Kubernetes Deployment</h4><p>If you are deploying in Kubernetes, update your deployment manifest to mount the CA certificate:</p><pre>env:<br>  - name: NODE_EXTRA_CA_CERTS<br>    value: /etc/ssl/certs/database-ca.crt<br>volumeMounts:<br>  - name: ssl-certs<br>    mountPath: /etc/ssl/certs/database-ca.crt<br>    subPath: database-ca.crt<br>volumes:<br>  - name: ssl-certs<br>    configMap:<br>      name: database-ca-cert</pre><h4>Systemd Service Configuration</h4><p>For applications managed by <strong>systemd</strong>, add the environment variable to the service file:</p><pre>[Service]<br>Environment=&quot;NODE_EXTRA_CA_CERTS=/etc/ssl/certs/database-ca.crt&quot;</pre><h3>Comparing Different Approaches</h3><p>Here’s how NODE_EXTRA_CA_CERTS compares to alternative solutions:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/628/1*JFfzAwJVLjSxFLq_ZuYESQ.png" /></figure><p>As seen above, NODE_EXTRA_CA_CERTS is the <strong>best</strong> balance between security, maintainability, and ease of implementation.</p><h3>Troubleshooting Common Issues</h3><p>If you still experience SSL errors after setting NODE_EXTRA_CA_CERTS, check the following:</p><ol><li><strong>Verify the certificate path</strong>: Ensure the path to the CA certificate is correct and accessible.</li><li><strong>Check the certificate format</strong>: It should be in <strong>PEM format</strong> (.crt or .pem).</li><li><strong>Intermediate certificates</strong>: Some cloud providers use intermediate CAs that must also be included.</li><li><strong>Shell/environment variable scope</strong>: Ensure NODE_EXTRA_CA_CERTS is set in the correct session.</li></ol><h3>Conclusion</h3><p>This method is beneficial for teams working with frameworks like <strong>NestJS, Express, or Fastify</strong>, where database connection configurations can be complex.</p><p><strong>Leveraging </strong><strong>NODE_EXTRA_CA_CERTS instead of </strong><strong>NODE_TLS_REJECT_UNAUTHORIZED, ensures your application maintains strong security without unnecessary code changes or risky workarounds.</strong></p><p>With proper SSL handling, you can eliminate connectivity issues, prevent last-minute deployment failures, and <strong>deploy with confidence</strong> — whether you’re running locally, in staging, or production.</p><p>A well-configured environment is the foundation of a <strong>secure, scalable, and resilient</strong> application. By adopting these best practices, your NestJS applications will be ready to handle real-world deployments while maintaining robust security and reliability.</p><p><strong><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure).</em></strong></p><p><strong><em>Follow me for insights and technical tips: </em></strong><a href="https://www.linkedin.com/in/covenantireneufia"><strong><em>LinkedIn</em></strong></a><strong><em> | </em></strong><a href="https://github.com/UfiairENE"><strong><em>Github</em></strong></a></p><p><strong>Thanks</strong> to <a href="https://www.linkedin.com/in/elisha-ukpong?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=ios_app">Elisha Ukpong</a> and <a href="https://www.linkedin.com/in/onionsman?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=ios_app">Onionsman</a> for reading drafts.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5fe40b2d276c" width="1" height="1" alt=""><hr><p><a href="https://towardsdev.com/fixing-self-signed-certificate-in-certificate-chain-error-in-nestjs-with-managed-databases-5fe40b2d276c">Fixing “Self-Signed Certificate in Certificate Chain” Error in NestJS with Managed Databases</a> was originally published in <a href="https://towardsdev.com">Towards Dev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Step-by-Step Guide: Migrate a Self-Hosted PostgreSQL Database to a Managed Service]]></title>
            <link>https://devopsinsight.medium.com/step-by-step-guide-migrate-a-self-hosted-postgresql-database-to-a-managed-service-8184784004f2?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8184784004f2</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[postgresql]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Mon, 17 Mar 2025 16:39:00 GMT</pubDate>
            <atom:updated>2025-03-17T17:53:52.138Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZSiE_ILPkJmM2Lq96tcyvQ@2x.jpeg" /></figure><p>What should be a straightforward process often turns into a comedy of errors—<strong>except nobody’s laughing when production data is at stake</strong>.</p><p>I was migrating a PostgreSQL database from a self-hosted server to a managed service.</p><blockquote>Unlike self-hosted PostgreSQL, a managed database service automates backups, scaling, security, and maintenance, reducing operational overhead while ensuring high availability, performance, and reliability.</blockquote><p><strong>Simple plan:</strong></p><ul><li>Dump the database.</li><li>Push it to the new managed instance.</li><li>Move on with my life.</li></ul><p>PostgreSQL, of course, had other ideas.</p><p>If you’re about to migrate your database, buckle up. Here’s how to do it right—without breaking security, your patience, or your production environment.</p><h4>Step 1: Dump the Database (And Hope Your Versions Match)</h4><p>I started by running pg_dump on my local machine to pull the database from the remote server:</p><pre>pg_dump -h [SOURCE_HOST] -p 5432 -U [DB_USER] -W -d [DB_NAME] -f backup.sql</pre><p>(You’ll be prompted for the password.)</p><p>Immediately, PostgreSQL smacked me with:</p><pre>pg_dump: error: server version: 15.7; pg_dump version: 14.13<br>pg_dump: error: aborting because of server version mismatch<br></pre><blockquote>PostgreSQL refuses to dump databases using an older client version than the server.</blockquote><h4>Fix: Upgrade Your PostgreSQL Client</h4><p>Since my database was running PostgreSQL 15.7, I upgraded my local client:</p><pre>sudo sh -c &#39;echo &quot;deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main&quot; &gt; /etc/apt/sources.list.d/pgdg.list&#39;<br>wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -<br>sudo apt update<br>sudo apt install -y postgresql-client-15</pre><p>With that, pg_dumpworked without issues.</p><h4>Step 2: Restoring the Dump to a Managed PostgreSQL Database</h4><p>With my backup file ready, I ran:</p><pre>psql -h [MANAGED_DB_HOST] -p [PORT] -U [DB_USER] -W -d [DB_NAME] &lt; backup.sql</pre><p>And PostgreSQL laughed in my face, as if to say, &quot;<strong>Who do you think you are?”</strong></p><pre>psql:backup.sql:1389: ERROR: must be able to SET ROLE &quot;postgres&quot;</pre><blockquote>Why? ,</blockquote><blockquote>With self-hosted, I had full control and could assume the postgres role but many managed services restrict direct access to the postgres superuser role.</blockquote><p>My dump file contained lines like:</p><pre>ALTER TABLE my_table OWNER TO postgres;</pre><p>But my managed database didn’t allow a postgres user with superuser privilege. They create a different default admin role that lacks full privileges.</p><h4>Fix: Change Database Ownership Before Restoring</h4><p>To sidestep this restriction, I replaced all OWNER TO postgres; occurrences in the dump file with my actual database user with the command:</p><pre>sed -i ‘s/OWNER TO postgres;/OWNER TO [YOUR_DB_USER];/g’ backup.sql</pre><p>After that, the restore command worked perfectly. You may then switch your application Database URL to point to the new managed service.</p><h4>Security Warning: Your Backup File is a Goldmine</h4><p>Your backup.sql file likely contains credentials, schema details, and user permissions. Treat it like a password.</p><h4><strong>How to Secure It:</strong></h4><ul><li><strong>Restrict file access:</strong></li></ul><pre>chmod 600 backup.sql</pre><ul><li><strong>Never commit it to Git.</strong></li><li><strong>Store it securely and delete it after migration.</strong></li></ul><h4>Side Note: What If External Connections Are Blocked?</h4><p>I didn’t run into this as this was earlier taken care of, but you might. If you get:</p><pre>psql: error: connection to server at &quot;[MANAGED_DB_HOST]&quot; (192.168.x.x), port 25060 failed: <br>FATAL: no pg_hba.conf entry for host &quot;[YOUR_IP]&quot;, user &quot;[YOUR_DB_USER]&quot;, database &quot;[YOUR_DB_NAME]&quot;<br></pre><p>Your managed database is blocking external connections.</p><h4>Fix: Whitelist Your IP—Securely</h4><p><strong>1. Get your public IP:</strong></p><pre>curl ifconfig.me</pre><p><strong>2. Go to your database provider’s settings and add your IP to the allowlist.</strong></p><p>3. <strong>Only allow trusted IPs—never open access to </strong><strong>0.0.0.0/0. </strong><em>Unless, of course, you enjoy security nightmares.</em></p><h3>Final Lesson</h3><p>This should take 15 minutes. Instead, I had to:</p><ul><li>Upgrade my PostgreSQL client.</li><li>Modify ownership settings to avoid permission issues.</li><li>Work around managed database restrictions.</li></ul><p>Hence, these key takeaways are worthy of note:</p><ol><li><strong>Version compatibility is everything. </strong>Make sure pg_dump and psql match the PostgreSQL server version before you start.</li><li><strong>Managed services have restrictions—</strong>superuser access is off limits, so expect ownership issues.</li><li><strong>Adjust the dump file when needed—</strong>replace OWNER TO postgres; with your actual database username.</li><li><strong>Secure your connections—never</strong> allow unrestricted external access (0.0.0.0/0).</li><li><strong>Back up your backup—just</strong> in case.</li><li><strong>Secure your backup file—</strong>encrypt it, never push it to git, restrict access, and delete it after migration.</li></ol><h3>How I Ensured Data Integrity During Migration</h3><p>A major concern was preventing writes to the database while migration was in progress. Two approaches usually work:</p><h4>Option 1: Logical Replication (For Zero Downtime)</h4><p>For large-scale, mission-critical databases, I’ve used logical replication in the past. This allows continuous syncing between the source and target database, ensuring a seamless switchover as I would need to :</p><p>1. <strong>Set up a replication slot on the source database.</strong></p><p>2. <strong>Configure the managed database as a subscriber.</strong></p><p>3. <strong>Let replication run while the application continues operating.</strong></p><p>4. <strong>Switch over seamlessly once everything is synced.</strong></p><blockquote><strong>This is the best option when downtime isn’t acceptable.</strong></blockquote><h4>Option 2: Maintenance Mode (What I Used Here)</h4><p>For this migration, I opted for a faster, simpler approach that involved a short, controlled downtime:</p><p>1. <strong>Pre-migration notice</strong> – Users were informed in advance that the system would enter maintenance mode.</p><p>2. <strong>Activated maintenance mode</strong> – Prevented new writes while I dumped and restored the database.</p><p>3. <strong>Ran the migration immediately</strong> – With no active writes, the process was clean and efficient.</p><p>4. <strong>Switched the application to the new database</strong> – Once the restore was complete, I pointed the app to the new managed database and disabled maintenance mode.</p><blockquote>This ensured a minimal disruption, rather than an actual downtime where users would see errors or broken functionality.</blockquote><h4>Choosing the Right Approach</h4><ul><li>Use logical replication when you need true zero downtime and can set up continuous syncing.</li><li>Use maintenance mode when a short, controlled downtime is acceptable for a simpler, cleaner migration.</li></ul><p>I’ve used both methods in different scenarios, and <strong>choosing the right one depends on your system’s needs.</strong></p><p>Migrating databases isn’t supposed to be a fight, but PostgreSQL has a way of making sure you earn your victory. If you find yourself in the middle of an unexpected battle, just remember: <strong>the database isn’t being difficult — it’s just making sure you know what you’re doing.</strong></p><p>PostgreSQL enforces best practices for a reason. Follow these steps, and your migration will be seamless, secure, and frustration-free.</p><p><strong><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure).</em></strong></p><p><strong><em>Follow me for insights and technical tips: </em></strong><a href="https://www.linkedin.com/in/covenantireneufia"><strong><em>LinkedIn</em></strong></a><strong><em> | </em></strong><a href="https://github.com/UfiairENE"><strong><em>Github</em></strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8184784004f2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Strategic Infrastructure Scaling: Don't Scale What Isn't Growing]]></title>
            <link>https://blog.startupstash.com/strategic-infrastructure-scaling-dont-scale-what-isn-t-growing-029e75f1ef81?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/029e75f1ef81</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[finops]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Tue, 25 Feb 2025 12:37:56 GMT</pubDate>
            <atom:updated>2025-02-28T16:27:24.414Z</atom:updated>
            <content:encoded><![CDATA[<h2>Strategic Infrastructure Scaling And Cost Optimization: Don’t Scale What Isn’t Growing</h2><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QDpeQ2C7c3bfcwC35s2BRw@2x.jpeg" /></figure><p>A few years ago, a small SaaS startup launched with a great idea — an AI-powered personal finance assistant. The founders were excited, and their first instinct was to build for scale. They provisioned redundant cloud resources, assuming they would need them soon. They were ready for millions of users.</p><p>By the end of their first quarter, they had spent more on infrastructure than they had earned in revenue. Except, they didn’t have millions of users. They had a few hundred. Yet their cloud bill was climbing north of $1,000 per month. Before they had a chance to iterate on their product-market fit, they were drowning in infrastructure costs. Within a year, they shut down.</p><p>This is a common story — that plays out in different variations across the startup world. Founders and engineers often over-engineer their infrastructure based on hypothetical future needs, rather than present realities.</p><p>As a DevOps and infrastructure engineer, I have repeatedly seen this mistake: teams spend excessive time and resources designing for massive scalability when they haven’t even validated their core business model. In this article, I will share important lessons I’ve learned throughout my journey and how to strike the right balance between scalability and efficiency.</p><p>The truth is, <strong>you don’t need to scale until your business demands it</strong>.</p><h3>The High Cost of Premature Scaling</h3><p>AWS, GCP, and Azure provide powerful infrastructure solutions, but they come at a steep price. When teams configure auto-scaling groups, distribute workloads across multiple availability zones, and implement advanced caching strategies before their traffic justifies it, they introduce unnecessary complexity and cost.</p><h3>Where the Costs Add Up</h3><p><strong>1. Cloud Providers Are Expensive: </strong>Distributed architectures come with increased networking, storage, and data transfer costs.</p><p><strong>2. Overprovisioned Resources Drain Budget:</strong> Teams often allocate excessive computing power without fully utilizing it, leading to wasted spend.</p><p><strong>3. Operational Complexity Kills Agility:</strong> Managing a multi-cloud, multi-region setup requires dedicated DevOps expertise, adding overhead.</p><h3>Scaling Strategies: Picking the Right Approach</h3><p>Scaling is a fundamental concept in software architecture, referring to a system’s ability to handle increased load. Scaling isn’t one-size-fits-all. Businesses need to choose the right strategy based on demand — <strong>application specific needs</strong> and <strong>growth patterns</strong>. Here are the three main approaches:</p><ul><li><strong>Vertical Scaling (Scaling Up)</strong>: Enhancing the capacity of a single server by adding more resources, such as CPU or RAM. It’s like upgrading a computer to make it more powerful.</li><li><strong>Horizontal Scaling (Scaling Out)</strong>: Adding more servers to distribute the load. This approach increases capacity by expanding the number of machines working together.</li><li><strong>Diagonal Scaling (A Balanced Approach): </strong>Diagonal scaling is a flexible approach that combines both vertical and horizontal scaling, adjusting dynamically based on current demand. Instead of choosing one strategy upfront, it starts with vertical scaling — adding more CPU, memory, or storage to a single machine until it reaches its limit. Once further growth is needed, it shifts to horizontal scaling by distributing workloads across multiple instances. For example, a business might begin by upgrading its database server, but as traffic grows, it can introduce read replicas and load balancing to manage increasing queries efficiently.</li></ul><blockquote>The key advantage of diagonal scaling is adaptability — it allows infrastructure to grow when demand rises and scale down when demand drops, ensuring cost-efficiency without unnecessary complexity.</blockquote><h3>A Smarter Approach: When to Use the Right Scaling Strategy</h3><p>Instead of over-engineering infrastructure and blindly deploying a distributed system from the beginning, companies should start simple and scale incrementally, teams should optimize their architecture based on actual usage patterns:</p><p><strong>1. Use Vertical Scaling First:</strong> If your application is CPU/memory-bound and traffic is predictable, upgrading to a larger instance is usually the simplest and most cost-effective solution.</p><p><strong>2. Introduce Horizontal Scaling When Needed:</strong> If you’re hitting consistent performance bottlenecks due to concurrent traffic spikes, then adding more instances makes sense.</p><p><strong>3. Monitor Before Scaling: </strong>Performance bottlenecks should be analyzed first — sometimes caching, query optimization, or asynchronous processing can eliminate the need for immediate scaling.</p><blockquote>For applications with fewer than 1,000 monthly users, a monolithic architecture with vertical scaling is often one of the best approach.</blockquote><h3>Why Monoliths Work Better at Early Stages</h3><p>Many startups jump straight into microservices, thinking it’s the modern way to build software. However, microservices introduce communication overhead, deployment complexity, and operational challenges. A well-structured monolith is often easier and cheaper to maintain early on as it provides:</p><p><strong>1. Lower Infrastructure Cost:</strong> A single well-optimized instance is cheaper than running multiple small instances with distributed overhead.</p><p><strong>2. Simplified Debugging &amp; Maintenance: </strong>Fewer moving parts mean fewer things breaking at scale.</p><p><strong>3. Easier to Iterate: </strong>Early-stage applications require rapid development cycles, not excessive infrastructure.</p><h3>Practical Steps to Scale the Right Way</h3><p><strong>1. Keep it Monolithic Initially: </strong>Until you hit scale bottlenecks, avoid microservices and distributed patterns.</p><p><strong>2. Optimize Before Scaling: </strong>Improve database queries, implement caching (Redis, Memcached), and optimize code efficiency before provisioning more resources.</p><p><strong>3. Benchmark Your Limits:</strong> Use load testing to define at what threshold your infrastructure needs to scale.</p><h3>“But I Don’t Want to Configure Things Twice!”</h3><p>A common argument against starting small is that reconfiguring for scale later requires extra work. However, this thinking ignores two critical realities:</p><ol><li><strong>Your Scaling Needs Will Evolve Unpredictably</strong>: Designing prematurely for a million users results in unnecessary complexity.</li><li><strong>Modern Migration Is Easier Than Ever</strong>: Tools like Terraform, Kubernetes, and cloud-native databases simplify infrastructure changes.</li></ol><blockquote>Investing in massive scalability before demand exists is like renting a stadium before you’ve formed a local football team.</blockquote><h3>Is Serverless Really Cost-Effective?</h3><p>Serverless computing is often marketed as an affordable way to scale, but poor configurations can lead to unexpected costs. Misconfigured AWS Lambda, Firebase, or Vercel functions have resulted in five-figure invoices due to:</p><ul><li><strong>Execution Duration Costs</strong>: Poorly optimized functions that run longer than necessary drive up costs.</li><li><strong>Concurrency Limits and Scaling Behavio</strong>r: Auto-scaling adds more instances, each incurring additional costs.</li><li><strong>Networking Costs</strong>: Frequent external database calls lead to excessive cross-region networking charges.</li></ul><blockquote>Serverless isn’t inherently bad, but it requires careful tuning. It’s not always the cheapest solution, especially when running continuously.</blockquote><h3>The Importance of Building for Scalability — Without Prematurely Scaling</h3><p>While premature scaling is a mistake, engineers should still design applications for future scalability without introducing unnecessary overhead.</p><h3>How to Design for Future Scaling</h3><ul><li><strong>Decouple Core Logic</strong>: Structuring business logic modularly makes migrating to microservices easier.</li><li><strong>Choose Databases That Scale: </strong>PostgreSQL, MySQL, and other relational databases can handle significant scale if architected properly with indexing, replication, and partitioning strategies.</li><li><strong>Implement Caching from Day One</strong>: Using a caching layer like Redis significantly reduces the need for excessive scaling by offloading repeated queries.</li><li><strong>Use Feature Flags and Modular Deployment</strong>: This enables incremental migrations without massive rework.</li><li><strong>Avoid Cloud Vendor Lock-in</strong>: Open standards for databases, messaging queues, and storage provide long-term flexibility.</li></ul><h3>When to Actually Scale</h3><p>There is a right time to move beyond vertical scaling and invest in horizontal scaling, distributed databases, and containerized workloads. That time comes when:</p><ul><li>Traffic consistently exceeds 10,000+ monthly users, and performance bottlenecks arise despite optimizations.</li><li>A single server is no longer enough due to CPU/memory constraints, even after vertical scaling.</li><li>Your team requires independent deployments, and the monolith slows down development velocity.</li><li>Your business model is validated, and you need high availability guarantees for paying customers.</li></ul><h3>Conclusion: Scale When Your Business Scales</h3><p>Before designing for millions of users, ask yourself: <strong>Do I even have a thousand yet?</strong></p><blockquote>Many startups fail because they focus on enterprise-scale infrastructure before validating their business model.</blockquote><blockquote>So, as a business, <strong>what is the best infrastructure that won’t cost a lot but can scale when demand rises or falls?</strong></blockquote><p>The answer lies in <strong>diagonal scaling</strong> because the <strong>best infrastructure balances cost and scalability</strong>:</p><ul><li><strong>Start lean</strong> with minimal but efficient resources.</li><li><strong>Optimize vertically first</strong> — improve performance before adding more machines.</li><li><strong>Scale horizontally only when necessary.</strong></li><li><strong>Use automation</strong> to scale dynamically, avoiding unnecessary costs.</li></ul><p>Scaling should be a response to growth, not a prediction of it. Businesses that scale too soon waste money and slow down development. The key is to build infrastructure based on real demand, not future assumptions.</p><p>By balancing <strong>lean infrastructure </strong>with <strong>scalable software design</strong> and <strong>actual business growth</strong>, engineers and startups can manage costs effectively while positioning themselves for future success.</p><blockquote><em>Additional tools and resource ➡️ </em><strong><em>Visit </em></strong><a href="http://www.startupstash.com/"><strong><em>StartupStash</em></strong></a><strong><em><br></em></strong><em>Zendesk is giving $75,000 in credits and perks for startups! ➡️ </em><a href="https://tinyurl.com/4ta2c8j6"><strong><em>Apply Now!</em></strong></a></blockquote><p><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure).</em></p><p><em>Have you experienced infrastructure scaling challenges? Let’s connect and discuss: </em><a href="https://www.linkedin.com/in/covenantireneufia"><em>LinkedIn</em></a><em> | </em><a href="https://github.com/UfiairENE"><em>Github</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=029e75f1ef81" width="1" height="1" alt=""><hr><p><a href="https://blog.startupstash.com/strategic-infrastructure-scaling-dont-scale-what-isn-t-growing-029e75f1ef81">Strategic Infrastructure Scaling: Don&#39;t Scale What Isn&#39;t Growing</a> was originally published in <a href="https://blog.startupstash.com">Startup Stash</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Running Non-LTS Ubuntu Servers Is a Risk:]]></title>
            <link>https://blog.devops.dev/why-running-non-lts-ubuntu-servers-is-a-risk-a4a28a8b81a9?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/a4a28a8b81a9</guid>
            <category><![CDATA[legacy-systems]]></category>
            <category><![CDATA[bash]]></category>
            <category><![CDATA[ubuntu]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Tue, 28 Jan 2025 17:50:43 GMT</pubDate>
            <atom:updated>2025-03-31T08:25:11.062Z</atom:updated>
            <content:encoded><![CDATA[<h4>A Step-by-Step Guide to Upgrading Legacy Ubuntu Servers</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2q-f51g9QFrWjWI1No0FLQ@2x.jpeg" /></figure><p>When I joined the company, I anticipated the usual hurdles — getting familiar with systems, understanding workflows, and aligning with the team’s goals. What I didn’t expect was entering straight into a digital time capsule, surrounded by outdated servers running end-of-life (EOL) versions of Ubuntu.</p><p>As an infrastructure engineer, my job typically revolves around building and maintaining robust, scalable, and — most importantly — up-to-date systems. But sometimes, you inherit problems that aren’t yours, to begin with, and in this case, it was a client’s legacy system that would soon become my headache, or as I like to call it, “my unexpected adventure.”</p><p>The client had been running servers on a version of Ubuntu so outdated, it practically belonged in a museum. The moment I tried to update the server, it hit me: I was dealing with a legacy system way past its prime. The repositories were gone, updates were a distant memory, and security vulnerabilities were waiting to be exploited. Though the legacy system was inherited, ensuring its stability and security was now our challenge to overcome.</p><p>So, what followed was not just a technical fix but a lesson in patience, persistence, and understanding the importance of proactive infrastructure management. Here’s how I transformed a legacy disaster into a secure, stable system that the client could rely on for years to come.</p><h3><strong>Why Running Non-LTS Versions is a Bad Idea</strong></h3><p>Before we discuss how I solved this particular issue, let’s take a step back and ask: <strong>Who the hell provisions servers that aren’t LTS?</strong></p><p>You’d be amazed at how often this happens, especially when it’s not immediately obvious why it matters. <strong>The primary reason you should avoid running non-LTS (non-Long Term Support) versions of Ubuntu — or any Linux distribution, for that matter — on production servers is that they lack the critical support and security updates needed to keep systems stable and secure.</strong></p><p>While non-LTS versions may seem appealing because they offer the latest features and updates, they come with a major downside: <strong>shorter support windows.</strong></p><blockquote>Typically, non-LTS versions (Non-Long Term Support release versions) are supported for only 9 months, which means after that, security patches and software updates are no longer provided. In contrast, LTS versions offer 5 years of support, which includes security updates and patches, making them far more suitable for production environments.</blockquote><h4><strong>Running a non-LTS version can expose your infrastructure to various risks:</strong></h4><h4>1. Security Vulnerabilities</h4><p>Non-LTS versions stop receiving security updates as soon as they reach their end of life. Without these critical patches, your system becomes an easy target for attackers exploiting known vulnerabilities. This can compromise your entire infrastructure.</p><h4>2. Stability Issues</h4><p>Non-LTS versions lack the long-term maintenance and refinement of LTS releases. As a result, you may encounter bugs and performance issues that are never fixed, leading to instability in critical environments.</p><h4>3. Compatibility Challenges</h4><p>Over time, third-party applications, libraries, and tools may stop supporting non-LTS versions. This incompatibility can disrupt workflows and require time-consuming workarounds or migrations.</p><h4>4. Dependency Problems</h4><p>Running updates on non-LTS versions often fails due to unavailable or unsupported repositories. This can leave your server with outdated and broken dependencies, further complicating maintenance and upgrades.</p><h4>5. Lack of Vendor Support</h4><p>When using a non-LTS version, you forfeit access to vendor assistance for troubleshooting, bug fixes, and patches. In a production environment, this lack of support can result in prolonged downtime and increased operational costs.</p><blockquote>In summary, LTS is the only practical, secure, and stable option for production servers. Choosing non-LTS versions for your server setup may seem like a shortcut, but it’s a mistake that will lead to more pain than it’s worth.</blockquote><h3><strong>The Problem: Outdated Servers Running an End-of-Life OS</strong></h3><p>The server was running an Ubuntu version that had already reached its end-of-life (EOL). The repositories for the distribution had been shut down, and I was attempting to run</p><pre>sudo apt update</pre><p><strong>Error Output:</strong></p><pre><br>Hit:1 https://repos.insights.digitalocean.com/apt/do-agent main InRelease<br>Ign:2 http://mirrors.digitalocean.com/ubuntu mantic InRelease                  <br>Ign:3 http://security.ubuntu.com/ubuntu mantic-security InRelease              <br>Ign:4 http://mirrors.digitalocean.com/ubuntu mantic-updates InRelease          <br>Hit:5 https://repos-droplet.digitalocean.com/apt/droplet-agent main InRelease  <br>Ign:6 http://mirrors.digitalocean.com/ubuntu mantic-backports InRelease        <br>Err:7 http://mirrors.digitalocean.com/ubuntu mantic Release                    <br>  404  Not Found [IP: my server ip address]<br>Err:8 http://security.ubuntu.com/ubuntu mantic-security Release                <br>  404  Not Found [IP: my server ip address]</pre><p>The output described a series of errors indicating missing repositories. The most glaring was the error about the “404 Not Found” status for the package sources. It was clear: the server was not only out of date but had become a ticking time bomb for potential vulnerabilities.</p><h3>The Action: The Path to Recovery</h3><h3><strong>Step 1: Identify the OS Version and Plan the Upgrade</strong></h3><p>First, I identified the exact version of Ubuntu running on the server:</p><pre>lsb_release -a</pre><p>Output:</p><pre>No LSB modules are available.<br>Distributor ID: Ubuntu<br>Description:    Ubuntu 23.04<br>Release:        23.04<br>Codename:       mantic</pre><p>Once I confirmed the system was running a non-LTS version, I recognized the need to upgrade to a supported LTS version.</p><h3>Step 2: Back Up the System</h3><p>Before making any changes, I created a full backup to ensure recovery options if something went wrong</p><pre>sudo rsync -av --exclude=/proc --exclude=/sys --exclude=/tmp / /backup</pre><h3>Step 3: Update Repository Sources</h3><p>Since the current release was no longer supported, I updated the sources.list file to point to the <strong>old-releases</strong> archive:</p><ol><li><strong>Open the file for editing:</strong></li></ol><pre>sudo nano /etc/apt/sources.list</pre><p><strong>2</strong>. <strong>Replace instances of the current mirrors with the old-releases.ubuntu.com URLs</strong>.</p><p>In the case of the mantic (23.04) release, you would replace your existing sources with this:</p><pre>deb http://old-releases.ubuntu.com/ubuntu mantic main restricted universe multiverse<br>deb http://old-releases.ubuntu.com/ubuntu mantic-updates main restricted universe multiverse<br>deb http://old-releases.ubuntu.com/ubuntu mantic-security main restricted universe multiverse</pre><p>3.<strong> Save and exit </strong>(Ctrl+O, Enter, Ctrl+X).</p><blockquote>With the old-releases repository, I could access the required packages and patches needed to proceed with the upgrade.</blockquote><p>After updating the sources, I refreshed the package list</p><pre>sudo apt update<br>sudo apt upgrade -y</pre><h3>Step 4: Enable LTS Upgrades</h3><p>I modified the release-upgrade configuration to allow upgrades to LTS versions:</p><pre>sudo nano /etc/update-manager/release-upgrades</pre><p>Ensure the Prompt line reads:</p><pre>Prompt=lts</pre><p>Save and exit.</p><h3>Step 5: Perform the Upgrade</h3><p>I initiated the upgrade process:</p><pre>sudo do-release-upgrade</pre><p>P.S: If no new LTS release is detected, add the -d flag to force the upgrade:</p><pre>sudo do-release-upgrade -d</pre><p>During the upgrade, most of the prompts are self-explanatory, carefully read them and proceed. Once the upgrade is completed, Reboot the system when asked.</p><h3>Step 6: Post-Upgrade Cleanup</h3><p>After completing the upgrade, I cleaned up unnecessary packages:</p><pre>sudo apt autoremove -y</pre><h3>Step 7: Verify the Upgrade</h3><p>To confirm the upgrade, I checked the kernel and OS version again with uname -mrs and lsb_release -a:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/637/1*xYAYzEWXs3aJUAKJu3h8qA.jpeg" /></figure><p>For good measure, I just checked to make sure I had the latest of every package:</p><pre>sudo apt update<br>sudo apt upgrade -y</pre><p>This came back all clear!</p><h3>Step 8: Security Audit</h3><p>To ensure the server was secure post-upgrade, I ran a security audit using <a href="https://cisofy.com/lynis/">Lynis</a>:</p><pre>echo &quot;deb http://packages.cisofy.com/community/lynis/deb/ stable main&quot; | sudo tee /etc/apt/sources.list.d/cisofy-lynis.list<br>sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 86B72ED56D4F3D2B<br>sudo apt update<br>sudo apt install lynis -y<br>sudo lynis audit system</pre><p>When you run sudo lynis audit system, Lynis will execute various checks and provide recommendations related to system security, configurations, and vulnerabilities. It will output a detailed report in the terminal and store the logs in /var/log/lynis.log.</p><h3>The Aftermath: A Secure, Stable System</h3><p>Inheriting a legacy system running an unsupported version of Ubuntu was both a challenge and an opportunity to demonstrate the importance of proactive infrastructure management. The outdated server posed significant risks: missing security updates, unstable infrastructure, and compatibility issues — all of which reinforced a crucial lesson: <strong>non-LTS versions have no place in production environments.</strong></p><p>The solution required a methodical approach. From identifying the problem and backing up data to updating repository sources and upgrading to a stable LTS release, each step was crucial in restoring the system’s integrity.</p><p>The result? A secure, robust, and scalable solution ready to support the client’s future needs with confidence.</p><p>This experience is a stark reminder that running non-LTS systems may seem convenient initially, but it’s a gamble fraught with risk. The costs — security vulnerabilities, downtime, and operational headaches — far outweigh any perceived benefits. For infrastructure managers, the message is clear: <strong>don’t wait for vulnerabilities or failures to force your hand.</strong></p><p>Take charge of your systems before they take control of you. Adopt LTS versions, conduct regular system audits, and prioritize security. Future-proof your infrastructure now, because in the ever-evolving world of tech, staying current isn’t just an option; it’s a necessity.</p><p><strong>Ready to secure your systems and safeguard your infrastructure?</strong> Start by auditing your servers today — your future self will thank you.</p><p><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure).</em></p><p><em>Follow me for insights and technical tips: </em><a href="https://www.linkedin.com/in/covenantireneufia"><em>LinkedIn</em></a><em> | </em><a href="https://github.com/UfiairENE"><em>Github</em></a></p><p><strong>Thanks</strong> to <a href="https://www.linkedin.com/in/elisha-ukpong?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=ios_app">Elisha Ukpong</a> and <a href="https://www.linkedin.com/in/onionsman?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=ios_app">Onionsman</a> for reading drafts and making suggestions.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a4a28a8b81a9" width="1" height="1" alt=""><hr><p><a href="https://blog.devops.dev/why-running-non-lts-ubuntu-servers-is-a-risk-a4a28a8b81a9">Why Running Non-LTS Ubuntu Servers Is a Risk:</a> was originally published in <a href="https://blog.devops.dev">DevOps.dev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Reverse Proxies]]></title>
            <link>https://devopsinsight.medium.com/understanding-reverse-proxies-f8bdad4bc6ad?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8bdad4bc6ad</guid>
            <category><![CDATA[traefik]]></category>
            <category><![CDATA[web-server]]></category>
            <category><![CDATA[nginx]]></category>
            <category><![CDATA[forward-proxy]]></category>
            <category><![CDATA[reverse-proxy]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Fri, 20 Dec 2024 11:50:52 GMT</pubDate>
            <atom:updated>2024-12-20T11:50:52.833Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/815/1*2oJ4as_5M6AZyUgtWsdxpQ.png" /></figure><p>In modern web infrastructure, proxies play a crucial role in managing traffic, enhancing security, and improving performance. But before going deep into reverse proxies, let’s first define what a proxy server is and how it works.</p><h3>What Is a Proxy Server?</h3><p>A <strong>proxy server</strong> is an intermediary between a client (like your browser) and the internet. It handles requests on behalf of the client and then forwards them to the destination server. When the server responds, the proxy sends the data back to the client. This helps with:</p><ul><li><strong>Security:</strong> The proxy can hide the client’s real IP address.</li><li><strong>Performance:</strong> Proxies can cache data to reduce response times.</li><li><strong>Control:</strong> Proxies can filter content or monitor traffic.</li></ul><h4>Forward Proxy vs. Reverse Proxy</h4><p>Now that we understand what a proxy is, let’s look at the two common types: <strong>forward proxy and reverse proxy</strong>.</p><h4>Forward Proxy</h4><p>A forward proxy sits between the client and the internet. It’s used primarily by clients (like browsers) to reach websites. Some common use cases include:</p><ul><li><strong>Hiding IPs:</strong> A forward proxy can mask the client’s IP address, offering anonymity.</li><li><strong>Content Filtering:</strong> It can block access to certain websites, commonly used in corporate environments.</li><li><strong>Caching:</strong> It stores frequently accessed content to reduce traffic and speed up browsing.</li><li><strong>Common use cases:</strong> Anonymizing traffic, bypassing firewalls, accessing geo-restricted content.</li></ul><blockquote>For example, in a corporate network, employees’ internet traffic goes through a forward proxy, which filters out harmful websites and hides the employees’ IP addresses.</blockquote><h4>Reverse Proxy</h4><p>A reverse proxy, on the other hand, serves as an intermediary between the client and your backend servers. When a client makes a request, the reverse proxy forwards it to the appropriate server. Some key benefits of a reverse proxy include:</p><ul><li><strong>Load Balancing: </strong>Distributes incoming traffic across multiple servers, preventing any one server from becoming overwhelmed.</li><li><strong>SSL Termination: </strong>Handles the encryption and decryption of SSL/TLS traffic, offloading this task from your backend servers.</li><li><strong>Security:</strong> Protects your backend servers by masking their identities from the outside world.</li><li><strong>Simplified Infrastructure</strong>: With a reverse proxy, clients don’t need to know about the backend servers. The proxy handles requests and routes them to the appropriate server, reducing the complexity of your infrastructure.</li><li><strong>Caching</strong>: Reverse proxies can cache responses from backend servers, reducing the load on the servers and speeding up response times for frequently accessed content.</li><li><strong>Common use cases:</strong> Load balancing, caching, security, and hiding server identities.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*atG3Y8QPUYDu7Tqrj5kFbw.png" /></figure><blockquote><strong>The primary difference is that while a forward proxy aids the client, a reverse proxy helps the server infrastructure. With a reverse proxy, clients interact with a single entry point, which then decides how to route the request to the appropriate server.</strong></blockquote><h3>Why Choose NGINX or Traefik for Reverse Proxy?</h3><p>Two of the most popular solutions for reverse proxies are <strong>NGINX</strong> and <strong>Traefik</strong>. Both offer robust features, but they cater to different use cases.</p><h4>NGINX</h4><p><strong>NGINX</strong> is known for its performance, flexibility, and scalability. It’s a popular choice for high-traffic websites and complex web applications. NGINX provides extensive configuration options, allowing you to fine-tune how your reverse proxy behaves.</p><p><strong>Key Features of NGINX:</strong></p><ul><li><strong>Manual Configuration</strong>: NGINX requires manual setup, giving you fine-grained control over your reverse proxy.</li><li><strong>Load Balancing</strong>: NGINX supports various load balancing algorithms like round-robin and least-connections.</li><li><strong>SSL Termination</strong>: NGINX can handle SSL/TLS encryption and decryption, offloading these tasks from backend servers.</li><li><strong>Caching</strong>: You can configure NGINX to cache responses for even faster subsequent requests.</li></ul><h4><strong>Setting Up NGINX as a Reverse Proxy</strong></h4><ol><li><strong>Install NGINX</strong>:</li></ol><pre>sudo apt update<br>sudo apt install nginx</pre><p>2. <strong>Basic Reverse Proxy Configuration</strong>: Create a configuration file (e.g., /etc/nginx/sites-available/my-site.conf) with the following content:</p><pre>server {<br>    listen 80;<br>    server_name example.com;<br><br>    location / {<br>        proxy_pass http://your-backend-server:8080;<br>        proxy_set_header Host $host;<br>        proxy_set_header X-Real-IP $remote_addr;<br>        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;<br>        proxy_set_header X-Forwarded-Proto $scheme;<br>    }<br>}</pre><p>3. <strong>Test and Reload NGINX</strong>:</p><pre>sudo nginx -t<br>sudo systemctl reload nginx</pre><h4>Traefik</h4><p><strong>Traefik</strong> is designed for dynamic, cloud-native environments such as microservices and containerized applications. It automatically discovers services and adapts to changes in real time, making it ideal for modern DevOps environments.</p><p><strong>Key Features of Traefik:</strong></p><ul><li><strong>Automatic Service Discovery</strong>: Traefik automatically detects services running in containers (e.g., Docker or Kubernetes) without manual configuration.</li><li><strong>Dynamic Configuration</strong>: It seamlessly adapts to changes in infrastructure, which is perfect for microservices that are frequently deployed and updated.</li><li><strong>SSL/TLS Automation</strong>: Traefik integrates directly with Let’s Encrypt, automatically generating and renewing SSL certificates.</li></ul><h4><strong>Setting Up Traefik with Docker</strong></h4><ol><li><strong>Configure Traefik in Docker</strong>: Create a docker-compose.yml file with the following configuration:</li></ol><pre>version: &#39;3&#39;<br>services:<br>  traefik:<br>    image: traefik:v2.5<br>    command:<br>      - &quot;--api.insecure=true&quot;<br>      - &quot;--providers.docker=true&quot;<br>      - &quot;--entryPoints.web.address=:80&quot;<br>      - &quot;--entryPoints.websecure.address=:443&quot;<br>    ports:<br>      - &quot;80:80&quot;<br>      - &quot;443:443&quot;</pre><p><strong>2. Configure SSL with Let’s Encrypt:</strong> Add labels to enable automatic SSL;</p><pre>labels:<br>  - &quot;traefik.http.routers.web.rule=Host(example.com)&quot;<br>  - &quot;traefik.http.routers.web.tls=true&quot;<br>  - &quot;traefik.http.routers.web.tls.certresolver=myresolver&quot;</pre><p>3. <strong>Define Certificate Resolver</strong>:</p><pre>certificatesResolvers:<br>  myresolver:<br>    acme:<br>      email: your-email@example.com<br>      storage: /letsencrypt/acme.json<br>      httpChallenge:<br>        entryPoint: web</pre><p>Traefik excels in dynamic and containerized environments, automatically adapting to the lifecycle of services as they are launched or stopped.</p><h3>NGINX vs. Traefik: Which One Should You Choose?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/667/1*f4kbqUKxuTi2QxUUsRZiLw.png" /><figcaption>Key differences between NGINX and Traefik</figcaption></figure><h3>Conclusion</h3><p>Proxies play a pivotal role in modern web infrastructure by acting as intermediaries between clients and servers. They enhance <strong>security</strong>, improve <strong>performance</strong>, and provide greater <strong>control</strong> over traffic management.</p><ul><li><strong>Forward Proxies</strong>: Primarily serve clients by masking IPs, filtering content, and caching data.</li><li><strong>Reverse Proxies</strong>: Aid server infrastructures by enabling load balancing, SSL termination, and protecting backend servers.</li></ul><p>When it comes to reverse proxies:</p><ul><li><strong>NGINX</strong> is the go-to solution for high-traffic, traditional environments, offering extensive customization, caching, and load balancing options.</li><li><strong>Traefik</strong> excels in dynamic, containerized ecosystems, automating service discovery and SSL setups, making it a favorite for modern DevOps and cloud-native architectures.</li></ul><p>Choosing the right proxy depends on your specific needs, whether you’re managing a traditional web application or scaling a microservices-based infrastructure. Proxies are indispensable for building secure, efficient, and scalable systems.</p><p><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure).</em></p><p><em>Follow me for insights and technical tips: </em><a href="https://www.linkedin.com/in/covenantireneufia"><em>LinkedIn</em></a><em> | </em><a href="https://github.com/UfiairENE"><em>Github</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8bdad4bc6ad" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Configure Caddy with an External SSL Certificate Using Ansible]]></title>
            <link>https://medium.com/devsecops-community/how-to-configure-caddy-with-an-external-ssl-certificate-using-ansible-b51ab67e7aa1?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/b51ab67e7aa1</guid>
            <category><![CDATA[ssl-certificate]]></category>
            <category><![CDATA[ansible]]></category>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[caddy]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Sat, 30 Nov 2024 14:27:11 GMT</pubDate>
            <atom:updated>2025-04-01T13:47:13.696Z</atom:updated>
            <content:encoded><![CDATA[<h4>Ansible Configuration With Caddy</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/565/1*mJi1wO7QN39qS3wpAz4CVQ@2x.jpeg" /></figure><p>In this article, we’ll walk you through configuring <a href="https://caddyserver.com/docs/">Caddy</a> (A powerful, easy-to-use web server that automatically handles SSL certificates and reverse proxying ) to use an external SSL/TLS certificate from a commercial Certificate Authority (CA).</p><p>While Caddy can handle automatic certificate management with Let’s Encrypt, there are situations where you may need to use a certificate provided by a third-party CA.</p><p>We’ll demonstrate how to deploy and configure this type of certificate with Caddy, including the necessary steps to ensure it works correctly.</p><p>We’ll automate the setup using <a href="https://docs.ansible.com/">Ansible</a> ( A popular automation tool for configuring systems and deploying applications with simple, human-readable YAML files ) to simplify and streamline the process for production environments.</p><h3>Prerequisites</h3><p>Before you begin, ensure that you have:</p><ol><li>A valid SSL/TLS certificate and corresponding private key from your CA.</li><li>Ansible installed for automation.</li><li>Root or sudo privileges on the server to install packages and modify system configurations.</li></ol><h3>Step 1: Preparing Your Certificate Files</h3><p>When you receive an SSL certificate from a commercial Certificate Authority, it often consists of multiple files, such as:</p><ol><li>The leaf certificate (your server’s certificate) — usually ends with .crt or .pem</li><li>The intermediate certificate (which bridges the trust between your leaf certificate and the root certificate) — ends with .crt or .pem</li><li>The private key associated with the leaf certificate — usually ends with .key</li></ol><p>Sometimes these certificates are provided separately, and sometimes in a single file (full chain). In most cases, the leaf certificate needs to be combined with the intermediate certificate to form the full certificate chain. This ensures that browsers and other clients can validate the entire trust path, from the root CA to your leaf certificate.</p><h3>Step 2: Setting Up Ansible to Automate the Configuration</h3><p>For this guide, we’ll use Ansible to automate the deployment of your SSL certificate onto the Caddy server. The Ansible playbook will copy your certificate files, concatenate the leaf and intermediate certificates (if needed), and configure Caddy to use them.</p><p>Here is an example Ansible Playbook that automates the process of installing dependencies, configuring Caddy, and deploying the certificate:</p><pre>- hosts: all<br>  become: yes<br>  tasks:<br>    - name: Update apt packages<br>      become: true<br>      apt:<br>        update_cache: yes<br>    <br>    - name: Install Caddy and fail2ban<br>      become: true<br>      apt:<br>        pkg:<br>          - caddy<br>          - fail2ban<br><br>    - name: Copy server certificate file (example.com.crt)<br>      copy:<br>        src: ../templates/example.com.crt<br>        dest: /etc/ssl/certs/example.com.crt<br>        mode: ‘0644&#39;<br><br>    - name: Set correct ownership for the certificate file<br>      file:<br>        path: /etc/ssl/certs/example.com.crt<br>        owner: caddy<br>        group: caddy<br>        mode: ‘0644&#39;<br><br>    - name: Copy intermediate certificate (DigiCertCA.crt)<br>      copy:<br>        src: ../templates/DigiCertCA.crt<br>        dest: /etc/ssl/certs/DigiCertCA.crt<br>        mode: ‘0644&#39;<br><br>    - name: Set correct ownership for the intermediate certificate<br>      file:<br>        path: /etc/ssl/certs/DigiCertCA.crt<br>        owner: caddy<br>        group: caddy<br>        mode: ‘0644&#39;<br><br>    - name: Concatenate server certificate and intermediate certificate to form a full chain<br>      shell: &quot;cat /etc/ssl/certs/example.com.crt /etc/ssl/certs/DigiCertCA.crt &gt; /etc/ssl/certs/example.com_fullchain.crt&quot;<br>      args:<br>        creates: /etc/ssl/certs/example.com_fullchain.crt<br><br>    - name: Copy private key file (example.com.key)<br>      copy:<br>        src: ../templates/example.com.key<br>        dest: /etc/ssl/private/example.com.key<br>        mode: ‘0600&#39;<br><br>    - name: Set correct ownership for the private key file<br>      file:<br>        path: /etc/ssl/private/example.com.key<br>        owner: caddy<br>        group: caddy<br>        mode: ‘0600&#39;<br><br>    - name: Set correct permissions for the /etc/ssl/private directory<br>      file:<br>        path: /etc/ssl/private<br>        owner: caddy<br>        group: caddy<br>        mode: ‘0750&#39;<br><br>    - name: Copy Caddy configuration file<br>      template:<br>        src: ../templates/Caddyfile<br>        dest: /etc/caddy/Caddyfile<br><br>    - name: Format Caddyfile<br>      ansible.builtin.shell: /usr/bin/caddy fmt --overwrite /etc/caddy/Caddyfile<br><br>    - name: Reload Caddy service to apply changes<br>      systemd:<br>        name: caddy<br>        state: reloaded</pre><h3>Step 3: Explanation of Key Steps</h3><p>1. Copying Certificate Files<br>After the installation, we begin by copying the necessary certificate files to their proper locations. These files typically include:</p><ul><li>Leaf Certificate (example.com.crt): This is the public certificate issued for your domain.</li><li>Intermediate Certificate (DigiCertCA.crt): This bridges the trust between your leaf certificate and the root certificate.</li><li>Private Key (example.com.key): This is the private key that matches your leaf certificate.</li></ul><p>These files are placed in the appropriate directories (/etc/ssl/certs and /etc/ssl/private) with correct file permissions to ensure proper access control. The playbook will set ownership to the caddy user, which is important for security.</p><p>2. Concatenating the Full Chain<br>In most cases, the leaf certificate needs to be combined with the intermediate certificate to form a full certificate chain. This ensures that clients can trace the certificate back to a trusted root authority.</p><p>Here’s the command used to concatenate the certificates:</p><pre>cat /etc/ssl/certs/example.com.crt /etc/ssl/certs/DigiCertCA.crt &gt; /etc/ssl/certs/example.com_fullchain.crt</pre><blockquote><strong><em>The full chain includes the leaf certificate first, followed by the intermediate certificate. This order is important because it ensures the correct certificate trust path.</em></strong></blockquote><p>3. Configuring Caddy with the Certificates<br>Next, the template Caddyfile is configured to use the full certificate chain and the private key. The Caddyfile is a simple configuration file where we specify the certificate locations.</p><p>Here’s the relevant section in the Caddyfile:</p><pre>example.com {<br>    tls /etc/ssl/certs/example.com_fullchain.crt /etc/ssl/private/example.com.key<br>    reverse_proxy localhost:8080<br>}</pre><p>The tls directive tells Caddy to use the full chain certificate and the private key for SSL/TLS encryption. The reverse_proxy directive forwards traffic to your application running on localhost:8080.</p><p>4. Reloading Caddy</p><p>Finally, the playbook reloads the Caddy service using systemd to apply the new configuration and certificate changes:</p><pre>- name: Reload Caddy service to apply changes<br>  systemd:<br>    name: caddy<br>    state: reloaded</pre><h3>Step 4: Running the Playbook</h3><p>To apply the changes, you’ll run the Ansible playbook on your server with the following command:</p><pre>ansible-playbook -i your_inventory_file configure_caddy.yml</pre><p>This will automate the entire process, including copying the certificate files, setting up Caddy, and reloading the service.</p><h3>Step 5: Validation via Command Line</h3><p>After deploying the certificate using Ansible, you can use the openssl command to validate the expiration of the SSL certificate from your local machine or a remote server:</p><p>1. Using openssl to Check SSL Expiration:</p><p>This command will connect to your server and display the expiration date of the SSL certificate:</p><pre>openssl s_client -connect yourdomain.com:443 -servername yourdomain.com &lt;/dev/null 2&gt;/dev/null | openssl x509 -noout -enddate</pre><p>Output: The command will return a line like this:</p><pre>notAfter=Dec 31 23:59:59 2024 GMT</pre><h3>Conclusion</h3><p>In this article, we’ve demonstrated how to configure Caddy with an external SSL/TLS certificate from a commercial Certificate Authority. Using Ansible, we’ve automated copying the certificate files, concatenating the full chain, and configuring Caddy to use the certificate for encrypted communication. By following this guide, you can ensure that your Caddy server is securely configured with external certificates, making it ready for production with minimal manual intervention.</p><p>By automating this process, you can easily scale and maintain secure configurations for multiple servers, saving you time and reducing the chance of errors.</p><p><em>Irene Ufia is a software engineer specializing in DevSecOps (Blockchain Infrastructure).</em></p><p><em>Follow me for insights and technical tips: </em><a href="https://www.linkedin.com/in/covenantireneufia"><em>LinkedIn</em></a><em> | </em><a href="https://github.com/UfiairENE"><em>Github</em></a></p><h3>DevSecOps — Community 🚀</h3><p><em>Thank you for being a part of the </em><a href="https://medium.com/devsecops-community/devopsin90days/home"><strong><em>DevSecOps — Community</em></strong></a><strong><em> </em></strong><em>community! Before you go:</em></p><ul><li>Be sure to <strong>clap</strong> and <strong>follow</strong> ️ the Author👏<strong>️️</strong></li><li>Follow: <a href="https://medium.com/devsecops-community/newsletters/devsecops"><strong>Newsletter</strong></a> |<a href="https://www.linkedin.com/groups/14547253/"> <strong>LinkedIn Group</strong></a><strong>s </strong>|</li><li>More content at <a href="https://medium.com/devsecops-community/devopsin90days/home"><strong>DevSecOps — Community</strong></a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b51ab67e7aa1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/devsecops-community/how-to-configure-caddy-with-an-external-ssl-certificate-using-ansible-b51ab67e7aa1">How to Configure Caddy with an External SSL Certificate Using Ansible</a> was originally published in <a href="https://medium.com/devsecops-community">devsecops-community</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Rise of Embedded Finance: Blockchain’s Role in Shaping the Future of Financial Integration]]></title>
            <link>https://devopsinsight.medium.com/the-rise-of-embedded-finance-blockchains-role-in-shaping-the-future-of-financial-integration-7ef2839ee9fe?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/7ef2839ee9fe</guid>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[defi]]></category>
            <category><![CDATA[embedded-finance]]></category>
            <category><![CDATA[banking]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Mon, 08 Jan 2024 12:21:13 GMT</pubDate>
            <atom:updated>2025-01-25T06:52:28.385Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nRdOqQ3GzhTwVqOe" /><figcaption>Photo by <a href="https://unsplash.com/@kommumikation?utm_source=medium&amp;utm_medium=referral">Mika Baumeister</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Have you noticed how <em>finance</em> isn’t just about <em>banks</em> and <em>money</em> anymore? Remember when banking was limited to banks?</p><p>Well, those days are long gone. We’re witnessing a remarkable shift where financial services are seamlessly woven into our everyday apps and platforms—<em>an era of embedded finance.</em></p><p>This transformative concept involves integrating financial services within other industries, allowing businesses to offer financial products and services as part of their core offerings. The integration is seamless, offering customers a streamlined and more convenient experience. <br>Most of us have probably used embedded finance without necessarily knowing it. For example, companies like Uber and Lyft allow users to seamlessly pay for rides through the app; they provide payment processing within their platforms, integrating financial transactions with their core service.</p><p>At its essence, embedded finance empowers industries like retail, e-commerce, and even gaming to provide tailored financial services such as <strong><em>payments</em></strong>, <strong><em>lending</em>, <em>insurance</em>, </strong>and <strong><em>investments</em>,</strong> leveraging the underlying infrastructure of established financial institutions.</p><h3><strong>Impact of Blockchain on Embedded Finance</strong></h3><p>Blockchain, with its <strong><em>decentralized</em></strong><em> </em>and <strong><em>immutable</em></strong> ledger system, offers a secure and transparent environment for financial transactions. This technology has become a revolutionary innovation that’s amplifying the potential of embedded finance. Its adoption and impact on embedded finance are significant, primarily through enhanced security and tokenization.</p><blockquote>Tokenization, a pivotal aspect of blockchain, involves the conversion of real-world assets or rights into digital tokens. These tokens can represent anything of value — from currencies and stocks to real estate and even art.</blockquote><p>By tokenizing assets, their ownership can be divided, traded, and transferred swiftly and securely on a blockchain network, opening new avenues for liquidity and accessibility previously unimaginable in traditional finance.</p><h3><strong>Advantages of Blockchain and Tokenization in Embedded Finance</strong></h3><ol><li><strong>Accelerated Settlements:</strong> Using blockchain technology, transactions can be settled more quickly and accurately.</li><li><strong>Enhanced Security:</strong> Blockchain’s cryptographic principles ensure tamper-proof transactions, reducing the risks of fraud and enhancing security and trust in financial dealings.</li><li><strong>Increased Efficiency: </strong>Smart contracts and automated self-executing contracts on the blockchain enable the automatic execution of predefined actions when specific conditions are met, streamlining processes and reducing administrative overhead.</li><li><strong>Improved Accessibility:</strong> Tokenization facilitates fractional ownership, enabling broader access to high-value assets that were previously out of reach for many individuals.</li></ol><h3>Influence of Blockchain on Embedded Finance</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/695/1*tZTvjSsPxMhtqLb-bFrImw.png" /><figcaption>Defi Layered Architecture</figcaption></figure><h4><strong>Real-world Applications:</strong></h4><p>Blockchain-powered embedded finance has made substantial strides across industries. Digital wallets are one of the most prominent examples of embedded banking.<br>PayPal’s acceptance of Bitcoin as a form of payment is a prime example of the convergence of DeFi and embedded finance in the traditional economy.</p><p>Platforms like <a href="https://realt.co/">RealT </a>and <a href="https://propy.com/home/">Propy</a> have innovated real estate by utilizing blockchain for property tokenization, contributing to the projected annual growth rate (CAGR 2024–2028) of 3.41%, resulting in a market volume of US$729.40 trillion by 2028, as reported by<a href="https://www.statista.com/outlook/fmo/real-estate/worldwide"> Statista</a>.</p><blockquote>This breakthrough allows properties to be digitally divided, offering fractional ownership, liquidity, and increased investor accessibility.</blockquote><p>Expanding beyond real estate, blockchain’s transformative impact continues to reshape financial landscapes. Leveraging blockchain’s capabilities, key players like <a href="https://interstellar.cm">Interstellar</a> have revolutionized cross-border payments within Africa by providing the underlying blockchain infrastructure that facilitates direct transactions using local currencies, promoting financial inclusion and efficiency.</p><p>In the dynamic Nigerian blockchain ecosystem, Convexity’s introduction of the cNGN initiative stands out.<br><em> </em><strong><em>The </em></strong><a href="https://medium.com/@AfricaStablecoinConsortium/3b32318844f4"><strong><em>cNGN stablecoin</em></strong></a><strong><em>, anchored to the Nigerian naira, aims to fortify financial stability and enable seamless digital transactions within the economy.</em></strong><em><br></em> The recent adoption of stablecoin initiatives by the Central Bank of Nigeria underscores the nation’s commitment to embracing blockchain for enhancing financial accessibility and stability.</p><h4><strong>Global Trends:</strong></h4><p>Across different regions, blockchain’s impact on embedded finance varies but presents transformative potential. In Southeast Asia, blockchain-based remittance services, like those offered by companies such as <a href="https://www.instarem.com/">InstaReM</a>, have gained momentum. Reports by Juniper Research suggest that blockchain-based remittance solutions have the potential to reduce costs by 50% compared to traditional methods.</p><p>In Africa, initiatives such as <a href="https://sytemap.com/">Sytemap</a> by HouseAfrica have leveraged blockchain for transparent and secure land registries, ensuring immutable records of property ownership and thereby addressing challenges related to land disputes.</p><h4><strong>Regulatory Adaptation:</strong></h4><p>Global regulatory frameworks are evolving to embrace blockchain-based finance. In Africa, progressive steps are being taken to accommodate this transformative technology.</p><p>For instance, Nigeria’s Securities and Exchange Commission (SEC) has implemented a regulatory framework for digital assets, categorizing cryptocurrencies as securities and ensuring investor protection and market integrity. South Africa’s Financial Sector Conduct Authority (FSCA) has released guidelines outlining the regulatory framework for crypto assets and service providers, promoting responsible innovation and consumer protection.<br>Countries like Kenya and Ghana are actively exploring regulatory frameworks to harness the potential of blockchain technology in various sectors. Kenya’s Capital Markets Authority (CMA) has expressed interest in blockchain’s potential for capital markets, while Ghana’s central bank has initiated discussions on a digital currency pilot project. These initiatives reflect Africa’s growing interest in fostering a conducive regulatory environment for blockchain-based innovations.</p><p>Collaborative efforts within the African continent, such as the African Union’s African Blockchain and Digital Assets Framework, aim to facilitate discussions on regulatory standards and frameworks, promoting uniformity and fostering innovation across the region’s blockchain landscape.</p><h4><strong>User-centric Adoption:</strong></h4><p>Initiatives focused on user experience and education are driving blockchain adoption. Mobile applications like Coinsher, MetaMask and Trust Wallet offer simplified access to blockchain-based financial services.<br>Educational workshops and initiatives like ConsenSys Academy and Binance Academy are empowering users with the knowledge needed to navigate and utilize blockchain technologies effectively. Data from Statista indicates a rising trend in the number of blockchain wallet users globally, demonstrating increasing user engagement.</p><h3>Bottom Line and Way Forward</h3><p>The rise of embedded finance, empowered by blockchain technology, heralds a new era of seamless financial integration across diverse industries. Blockchain’s role in enabling tokenization, enhancing security, and fostering innovation has revolutionized financial services.</p><p>As financial services intertwine with everyday apps, protecting sensitive user data and ensuring compliance with stringent data privacy regulations like GDPR is paramount to ensure sustainable growth. Innovative technologies like zero-knowledge proofs are emerging as shields against data breaches, allowing secure verification without compromising confidentiality.</p><p>By implementing robust encryption protocols and aligning with regulatory frameworks, businesses not only fortify user privacy but also avert potential legal repercussions, bolstering trust in embedded financial services.</p><p>To address blockchain’s scalability and interoperability hurdles, innovative solutions are emerging.</p><blockquote>Reports show significant market growth for projects prioritizing interoperability, underscoring the rising importance of such solutions in the blockchain space.</blockquote><p>Layer 2 scaling solutions like the Lightning Network with Ethereum’s consensus layer – Ethereum 2.0 upgrades aim to boost transaction speed. Bantu Blockchain also offers high throughput and low transaction costs, enhancing scalability with its efficient consensus mechanism. <br>Interoperability protocols such as Polkadot, Cosmos, and Bantu’s inter-chain communication facilitate seamless interaction between different blockchains.</p><p>Overall, the convergence of embedded finance and blockchain technology presents vast opportunities for financial inclusion, transparency, and efficiency, signaling a promising future for a more interconnected and accessible global financial ecosystem.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7ef2839ee9fe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What happens when you type https://www.google.com in your browser and press ‘Enter’]]></title>
            <link>https://devopsinsight.medium.com/what-happens-when-you-type-https-www-google-com-in-your-browser-and-press-enter-37c6ff3d504c?source=rss-5acd9462a16c------2</link>
            <guid isPermaLink="false">https://medium.com/p/37c6ff3d504c</guid>
            <category><![CDATA[web-infrastructure]]></category>
            <category><![CDATA[network]]></category>
            <category><![CDATA[system-administration]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[url]]></category>
            <dc:creator><![CDATA[Irene Ufia]]></dc:creator>
            <pubDate>Mon, 17 Oct 2022 00:33:56 GMT</pubDate>
            <atom:updated>2024-11-30T16:32:17.180Z</atom:updated>
            <content:encoded><![CDATA[<p><strong><em>An in-depth explanation of how the web stack works on top of the internet</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*odJye4ErrnhrN1je1cKqvA.png" /><figcaption><strong>Photo Credit:</strong><a href="https://www.linkedin.com/in/covenantireneufia"><strong> Irene Ufia</strong></a></figcaption></figure><p>This question appears to be one of the oldest interview questions for most software engineering positions. An attempt to answer this question would lead to covering a wide range of topics such as <strong>DNS request, TCP/IP, Load-balancer, Firewall, SSL, HTTP/HTTPS, Web and Application servers and Database. </strong>What really happens behind the scene when you type <a href="https://www.google.com">https://www.google.com</a> in your browser and press ‘Enter’? How is information transferred via the internet? Let’s take a look.</p><p>When we type the website name or address — or more technically called a URL, for example, <a href="https://www.google.com">https://www.google.com</a> into our browser (Google, Safari, Firefox or any browser) and press Enter, the first thing the browser does is break down the URL in pieces — The URL(Uniform Resource Locator) is nothing more than the address of a given unique resource on the Web. The URL address above basically is composed of different parts as seen below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-p6Ya6h11C6fMo9lUmjpAg.jpeg" /></figure><p>The first part of the URL is the <em>scheme</em>, which indicates the protocol (a protocol is a set method for exchanging or transferring data around a computer network)that the browser must use to request the resource. Usually, for websites, the protocol is HTTPS or HTTP (its unsecured version). The separator between the scheme and authority is ://. The colon separates the scheme from the next part of the URL, while // indicates that the next part of the URL is the authority. The domain indicates which Web server is being requested.</p><p>Usually, asides from the domain name, an <a href="https://developer.mozilla.org/en-US/docs/Glossary/IP_Address">IP address</a> may also be used (but this is rare as it is much less convenient because words are easily remembered by humans than numbers, like the way you save contacts on your phone, Domain Name Servers are the phonebook of the internet).</p><p>The browser checks the hostname/domain name for characters that are not in a-z, A-Z, 0-9, -, or .. Since the hostname is google.com there won’t be any, but if there were the browser would apply <a href="https://en.wikipedia.org/wiki/Punycode">Punycode</a> encoding to the hostname portion of the URL( A way of convertin<strong>g</strong> non-ASCII Unicode characters in the hostname).</p><p>The next step is the <strong>HSTS (HTTP Strict Transport Security)</strong> <strong>list check. </strong>The browser checks its preloaded HSTS list. This is a list of websites that have requested to be contacted via HTTPS only. If the website is on the list, the browser sends its request via HTTPS instead of HTTP. Otherwise, the initial request is sent via HTTP. (Note that a website can still use the HSTS policy <em>without</em> being in the HSTS list. The first HTTP request to the website by a user will receive a response requesting that the user only send HTTPS requests. However, this single HTTP request could potentially leave the user vulnerable to a <a href="http://en.wikipedia.org/wiki/SSL_stripping">downgrade attack</a>, which is why the HSTS list is included in modern web browsers.)</p><p>The next step is the DNS Lookup and a series of queries by the DNS Resolver that we will highlight below:</p><p>Before the page and any resource on the page are loaded, the DNS must be resolved so the browser can establish a TCP connection to make the HTTP request. <strong>Since the operating system doesn’t know where “www.google.com” is, it queries a DNS resolver.</strong> (A DNS resolver, also called a recursive resolver, is <strong>a server designed to receive DNS queries from web browsers and other applications</strong>. The resolver receives a hostname — for example, <a href="http://www.example.com">www.example.com</a> — and is responsible for tracking down the IP address for that hostname). Browser checks if the domain is in its cache (to see the DNS Cache in Chrome, go to chrome://net-internals/#dns). If not found, the browser calls gethostbyname the library function (varies by OS) to do the lookup. gethostbyname checks if the hostname can be resolved by reference in the local hosts file (whose location <a href="https://en.wikipedia.org/wiki/Hosts_%28file%29#Location_in_the_file_system">varies by OS</a>) before trying to resolve the hostname through DNS. At this point, the resolver goes through a process called recursion to convert the domain name into an IP address.</p><p><strong>DNS Resolver Iterative Query to the Root Server:</strong></p><p>The DNS resolver starts by querying one of <a href="http://www.iana.org/domains/root/servers">the root DNS servers</a> for the IP of “www.google.com.” This query does not have the recursive flag and therefore is an “iterative query,” meaning its response must be an address, the location of an authoritative name server, or an error.</p><p><strong>Root Server Response:</strong></p><p>These root servers hold the locations of <a href="http://data.iana.org/TLD/tlds-alpha-by-domain.txt">all of the top-level domains</a> (TLDs) such as .com, .cm, .io, and newer generic TLDs such as .camera. The root usually doesn’t have the IP info for “www.google.com,” but it knows that .com might know, so it returns the location of the .com servers.</p><p><strong>DNS Resolver Iterative Query to the TLD Server:</strong></p><p>Like the Root Servers, each of the TLDs has 4–13 clustered name servers existing in many locations. In this case, we will be using the gTLD servers controlled by Verisign, who run the .com, .net, .edu, and .gov among gTLDs. In google.com, the TLD server is “com”. So, the resolver queries one of the .com name servers for the location of google.com. The request is then sent to the authoritative nameserver.</p><p><strong>TLD Server Response:</strong></p><p>Each TLD server holds a list of all of the authoritative name servers for each domain in the TLD. For example, each of the 13 .com gTLD servers has a list with all of the name servers for every single .com domain. The .com gTLD server does not have the IP addresses for google.com, but it knows the location of google.com’s name servers. The .com gTLD server responds with a list of all of google.com’s NS records. In this case, Google has four name servers, “ns1.google.com” to “ns4.google.com.”</p><p><strong>DNS Resolver Iterative Query to the Google.com NS:</strong></p><p>Finally, the DNS resolver queries one of Google’s name servers for the IP of “www.google.com.”</p><p><strong>Google.com NS Response: </strong>This time the queried Name Server knows the IPs and responds with an A or AAAA address record (depending on the query type) for IPv4 and IPv6, respectively.</p><p><strong>DNS Resolver Response to OS: </strong>At this point, the resolver has finished the recursion process and is able to respond to the end user’s operating system with an IP address.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lgn_jL4vhN_HIy1PtlwU1g.jpeg" /><figcaption>Diagram showing how the web stack works when you type a URL and hit enter</figcaption></figure><h3>Internet Protocol Suite</h3><p>Finally, the browser knows where to find <a href="http://www.google.com/">www.google.com</a> and it’s now time to make a connection, to access the website requested. Browsers use internet protocols to build such connections.</p><p>Internet Protocol Suite aka TCP/IP (TCP stand for Transmission Control Protocol) is the most common protocol used for many types of HTTP requests. It’s a set of rules governing the format of data sent via the internet or local network, such as sending e-mails, streaming videos, or connecting to a website.</p><h3>Traffic and Security Control</h3><p>Once the TCP connection is established, it is time to begin transferring data! But not so fast, first, we need some traffic control — meet the load balancer…</p><p><strong>A load balancer</strong>, like HAProxy, is a server that helps handle more web traffic and avoid downtime. The load balancer receives traffic from the internet and then distributes it among multiple servers so as to not overload any particular server with too many requests and example of an algorithm that we can use is the <strong>round-robin</strong>, which distributes the requests alternating between all the servers evenly and consequentially, or the <strong>least-connection</strong>, which distributes requests depending on the current server loads. Load balancers are essential for websites with a lot of traffic such as google.com! But in a day and age when online security concerns are the top priority of computer users, not anyone can gain access. Firewalls provide you with the necessary safety and protection.…</p><p><strong>A firewall</strong> is a software or hardware device that blocks unauthorised access to or from private networks. It acts as a barrier between a secured internal network and the most vulnerable network, e.g. the internet. Firewalls are set up at every connection to the Internet, therefore subjecting all data flow to careful monitoring. Firewalls can also be tuned to follow “rules”. These Rules are simply security rules that can be set up by yourself or by the network administrators to allow traffic to their web servers, FTP servers, and Telnet servers, thereby giving the computer owners/administrators immense control over the traffic that flows in &amp; out of their systems or networks. Rules will decide who can connect to the internet, what kind of connections can be made, and which or what kind of files can be transmitted in out. Basically, all traffic in &amp; out can be watched and controlled thus giving the firewall installer a high level of security &amp; protection. In the case of our example, when the browser asks for the website at the address 197.210.54.75, that request has been processed by a firewall which will decide if it’s safe, or if it’s a threat to the server’s security.</p><p><strong>Let&#39;s talk about the Secure Socket Layer (SSL)</strong></p><p>As opposed to unsecured HTTP URLs which begin with “http://” and use port 80 by default, secure HTTPS URLs begin with “https://” and use port 443 by default. HTTP is insecure and is subject to eavesdropping attacks which, if critical information like credit card details and account logins is transmitted and picked up, can let attackers gain access to online accounts and sensitive information. SSL is designed on top of TCP. It is a transparent protocol which requires little interaction from the end user when establishing a secure session. Ensuring data is either sent or posted through the browser using HTTPS is ensuring that such information is encrypted and secure. Behind the scenes, the browser retrieves the SSL certificate whenever it connects to a secure site. The browser checks to make sure that the certificate has not expired, whether or not the issuing authority is one that the browser trusts, and that the certificate is being used by the same website to which it was issued. If either safety check fails, the browser will let the user know that the site is not secured by SSL through a warning message. The user has the choice of trusting the site or leaving</p><h4>The browser sends the HTTP request to the server</h4><p>Now that the browser has a connection to the server, it follows the rules of communication for the HTTP(s) protocol. HTTP stands for HyperText Transfer Protocol and is perhaps the most popular application protocol used by the World Wide Web. It’s used by the browser and web server to communicate. It is a stateless, text-based protocol. It starts with the browser sending an HTTP request to the server to request the contents of the page. The HTTP request contains a request line, headers (or metadata about the request), and a body. The request line contains information that the server can use to determine what the client (in this case, your browser) wants to do.</p><p>An <strong>application server </strong>is a software program responsible for operating applications, communicating with the database servers, managing user information, and more. It works with web servers and is able to serve a dynamic application using the static content from the web server.</p><p>Another crucial component in the client-server computing environment is the <strong>database server</strong>, which consists of hardware and software that run a database. A <strong>database</strong> is a collection of data stored in an orderly manner and the database server is the program that interacts with the database. To run a system efficiently, you’d need an effective memory of the past and present records that went into and/or came out of that particular system. The two main ones are <strong>relational </strong>databases(e.g MySQL, Oracle, PostgreSQL) and <strong>non-relational </strong>databases(e.g MongoDB, Cassandra).</p><h4>The server breaks down the request into the following parameters:</h4><ul><li>HTTP Request Method (either GET, HEAD, POST, PUT, PATCH, DELETE, CONNECT, OPTIONS, or TRACE). In the case of a URL entered directly into the address bar, this will be GET.</li><li>Domain, in this case — google.com.</li><li>Requested path/page, in this case — / (as no specific path/page was requested, / is the default path).</li><li>The server verifies that there is a Virtual Host configured on the server that corresponds with google.com.</li><li>The server verifies that google.com can accept GET requests.</li><li>The server verifies that the client is allowed to use this method (by IP, authentication, etc.).</li><li>If the server has a rewrite module installed (like mod_rewrite for Apache or URL Rewrite for IIS), it tries to match the request against one of the configured rules. If a matching rule is found, the server uses that rule to rewrite the request.</li><li>The server goes to pull the content that corresponds with the request, in our case, it will fall back to the index file, as “/” is the main file (some cases can override this, but this is the most common method).</li></ul><blockquote>It is important to note that the above actions happen in very few seconds in quick succession as the snap of a finger.</blockquote><p>We covered the relationship between websites, servers, and IP addresses and stepped through each of the steps that your browser goes through when you type a URL into your browser and press enter.</p><p><strong>For review, here are those six steps:</strong></p><ol><li>You type a URL in your browser and press Enter</li><li>The browser looks up the IP address for the domain</li><li>The browser initiates a TCP connection with the server</li><li>The browser sends the HTTP request to the server</li><li>The server processes the request and sends back a response</li><li>The browser renders the content mostly <a href="https://www.hostinger.com/tutorials/what-is-html">HTML</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=37c6ff3d504c" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>