Buy Me a Coffee

Heyđź‘‹ I’m Oscar

Welcome to my technical blog!
Here, you’ll find useful insights and knowledge to help you stay ahead in the industry.
Thanks for stopping by, and I hope you enjoy what you read.
Find about me more ⬇️

Understanding TCP in Go - Common Misconceptions and Practical Examples

[Golang] Understanding TCP: Debunking Misconceptions with Practical Examples

TCP might seem straightforward, especially when using Go. You set up a net.Conn, call Write to send data, Read to receive it, and everything just seems to work. It’s straightforward, minimal, and very Go-like. However, this simplicity can lead to misunderstandings because the details beneath the surface are easy to overlook. This blog post aims to demystify the real workings of TCP using practical examples, tackling common myths, all within the context of Go development. ...

Layered network security diagram on Oracle Cloud Infrastructure.

[OCI] How to Open a Port on an OCI Instance

Ever spent hours wrestling with an application that seems perfectly fine, only to hit a roadblock that feels completely invisible? Chances are, your application isn’t the problem. When deploying services on Oracle Cloud Infrastructure (OCI), connection failure is usually not a coding issue. It’s a network issue. Traffic, before it can reach your running code, must pass through a series of security checkpoints, each acting like a protective gate. The biggest mistake new users make is thinking that opening a port is a single action. In reality, OCI uses a layered security model, and if even one gate is closed, the connection fails. ...

Go Defer Trap Avoided

[Golang] Avoid Using `defer mu.Unlock()` Inside Loops

In Go, using a mutex with defer might seem like an elegant and safe way to manage your code by ensuring resources are properly released. However, a common mistake lurks when this pattern is used inside loops. When working with mutexes, never do this: func broadcast(ctx context.Context, msgCh <-chan Message) { for { select { case msg := <-msgCh: s.mu.Lock() defer s.mu.Unlock() // ❌ Avoid this // Use the shared resource here case <-ctx.Done(): return } } } This seemingly harmless pattern can cause unexpected behavior and should be avoided. Let’s look into why this happens and how to handle it correctly. ...

Understanding Kubernetes Storage Management

[Kubernetes] Wait… Why Does Kubernetes Still Ask Me to Create a PersistentVolume? - The Storage Confusion Most Kubernetes Learners Hit

Introduction When I first learned Kubernetes storage, my mental model was very simple. In real clusters, we, as developers, usually have a StorageClass configured by Kubernetes administrators. So the workflow I saw everywhere looked like this: flowchart TB A["User creates a PersistentVolumeClaim (PVC)"] --> B["Kubernetes calls the CSI provisioner"] B --> C["Storage system creates a new disk"] C --> D["Kubernetes creates a PersistentVolume (PV) automatically"] D --> E["PVC binds to the PV"] In other words: PersistentVolumeClaim is enough. ...

Golang API Design - Illustration depicting a clear and safe API design for Go

[Golang] Stop Returning `(nil, nil)` in Go: A Small API Design Choice That Prevents Big Bugs

When designing Go APIs, you might think it’s harmless to return (nil, nil) when an object isn’t found. Many developers do this because it feels like “not found” shouldn’t be treated as an error. However, this approach often leads to one of the most frustrating runtime crashes in Go: panic: invalid memory address or nil pointer dereference In this post, we’ll cover: The problem — how (nil, nil) breeds fragile code Why this design creates real-world headaches Two solutions: Best practice (recommended): return a predefined error instead Alternative pattern: use an explicit existence flag An evolved, safer version of the code The goal isn’t just to fix mistakes, but to enhance API design to prevent misuse down the line. ...

[TLS] PEM vs CRT vs KEY Explained: Stop Guessing TLS Certificate Formats

If you have worked with TLS certificates, you may have encountered files with the extensions .pem, .crt, and .key. You might be wondering what they are, what differences they have, and how to use them effectively. The good news is that these formats aren’t as complicated as they seem once you understand the basics: PEM, CRT, and KEY are not different certificate types — they are different ways of packaging the same data. ...

Local HTTPS with Nginx in Minutes: A Practical Dev & Debug Setup (No Domain, No Public IP)

Setting up a local HTTPS environment is essential for developers wanting to test web applications under conditions that closely resemble production settings. This guide will help you establish a local Nginx reverse proxy using Docker Compose without the need for a domain or public IP, focusing specifically on Portainer as a sample application. Why You Want a Local Nginx Setup for Debugging When developing or debugging services like web dashboards or APIs, having an environment that closely mimics production is critical. A local Nginx reverse proxy enables you to: ...

Golang errors.Join illustration

The Pragmatic Way to Handle Multiple Errors in Go (Before and After Go 1.20)

Introduction For many Go developers, a recurring challenge has been: “What is the right way to handle multiple errors?” Whether it’s running several cleanup steps, processing batches of data, or validating various inputs, ensuring errors are handled correctly and efficiently has been crucial. Before Go 1.20, developers did not have a unified approach; each team created its own solution, often leading to awkward, unidiomatic, or even incorrect patterns. With Go 1.20, we now have a standard, pragmatic solution: errors.Join. This article will explore why older techniques were problematic, how the Go team designed a better approach, and how to apply this new solution effectively in your code. ...

Extracting Data from a Docker Volume Using a Third Container

[Docker] How to Safely Extract Data from a Docker Volume Using a Third Container

Introduction If you work with Docker long enough, you will eventually face this situation: You want to migrate data to a new server You want to back up a Docker volume before a risky change You are decommissioning a container but need to keep its data You need to inspect or recover files from a broken container You want to move data out of Docker into the host filesystem Docker volumes are intentionally abstracted away from the host. This is good for portability and safety, but it also means: ...

Traefik Docker Swarm Logout Issue Illustration

Refreshing Web Page Logs Out the User When Using Traefik in Docker Swarm

1. Introduction If you use Traefik as the reverse proxy in a Docker Swarm cluster, and your application is server-side rendered (SSR), you may encounter the following issue: You can log in successfully But when you refresh the page or navigate to another page, you are suddenly logged out The behavior feels random: sometimes it works, sometimes it doesn’t This issue usually does not appear: when running the app locally when using only one container before scaling the service in Docker Swarm Once you add multiple replicas, the problem starts to show up. This post will explore the reasons behind this behavior and how to effectively address it. ...

DigitalOcean Referral Badge
Sign up to get $200, 60-day account credit !