# Terminal

## Basic Podman Commands

### Containers

**List running containers**

```bash
podman ps
```

**List all containers**

```bash
podman ps -a
```

**Start container**

```bash
podman start <container>
```

**Stop container**

```bash
podman stop <container>
```

**Restart container**

```bash
podman restart <container>
```

**Delete container**

```bash
podman rm <container>
```

**Delete forcefully**

```bash
podman rm -f <container>
```

### Images

**List images**

```bash
podman images
```

**Pull image**

```bash
podman pull postgres:16
```

**Build image**

```bash
podman build -t myapp .
```

**Remove image**

```bash
podman rmi <image>
```

### Logs & Debugging

**View logs**

```bash
podman logs <container>
```

**Follow logs**

```bash
podman logs -f <container>
```

**Inspect container**

```bash
podman inspect <container>
```

**Container resource usage**

```bash
podman stats
```

### Shell Access

**Open shell inside container**

```bash
podman exec -it <container> bash
```

**If bash isn't installed**

```bash
podman exec -it <container> sh
```

**Example**

```bash
podman exec -it backend bash
```

### Podman Compose

**Start**

```bash
podman compose up -d
```

**Stop**

```bash
podman compose stop
```

**Start stopped services**

```bash
podman compose start
```

**Restart**

```bash
podman compose restart
```

**Rebuild**

```bash
podman compose up -d --build
```

**Destroy everything**

```bash
podman compose down
```

### Cleanup

**Remove stopped containers**

```bash
podman container prune
```

**Remove unused images**

```bash
podman image prune
```

**Remove everything unused**

```bash
podman system prune -a
```

### Commands You'll Use Most Often During Development

```bash
podman compose up -d
podman ps
podman compose logs -f
podman exec -it <container> bash
podman compose restart
podman compose down
```

These six commands cover about 90% of day-to-day backend development with Podman Compose.

## Issue 1: PostgreSQL Port Conflict (5433)

### Error

```text
rootlessport listen tcp4 0.0.0.0:5433:
bind: address already in use
```

### Root Cause

The PostgreSQL container attempted to expose:

```yaml
5433:5432
```

but port **5433** on the host machine was already occupied by another process.

### Investigation Commands

**Find which process owns the port**

```bash
netstat -ano | findstr :5433
```

**Get process details**

```bash
tasklist /FI "PID eq <PID>"
```

### Resolution

The port conflict was removed (either by stopping the existing process/container or freeing the port), allowing PostgreSQL to start successfully.

## Issue 2: Redpanda/Kafka Port Conflict (9092)

### Error

```text
rootlessport listen tcp4 0.0.0.0:9092:
bind: address already in use
```

### Root Cause

The Redpanda container attempted to expose:

```yaml
9092:9092
```

but port **9092** was already occupied.

### Investigation Commands

**Check port ownership**

```bash
netstat -ano | findstr :9092
```

**Result**

```text
127.0.0.1:9092 LISTENING PID 16788
```

**Find process**

```bash
tasklist /FI "PID eq 16788"
```

### Resolution

The port was eventually released. Later checks showed:

```bash
netstat -ano | findstr :9092
```

returned no results, meaning the port was no longer in use.

## Issue 3: Podman Connection Failure

### Error

```text
Cannot connect to Podman

unable to connect to Podman socket:
dial tcp 127.0.0.1:52324
```

### Initial Assumption

It appeared that:

*   Podman Machine was stopped
    
*   Podman socket was unavailable
    

### Investigation

**Check Podman**

```bash
podman info
```

**Check machine status**

```bash
podman machine list
```

**Check WSL status**

```bash
wsl -l -v
```

**Output**

```text
podman-machine-default Running
```

To troubleshoot further:

```bash
wsl --shutdown
```

### Observation

There was a contradiction:

*   Machine = Running
    
*   Podman Socket = Unreachable
    

This suggested one of the following:

*   Stale socket
    
*   Podman service restart required
    
*   Temporary VM networking issue
    

### Verification

Later, `podman info` returned successfully:

```yaml
remoteSocket:
  exists: true
```

and:

```yaml
running: 0
stopped: 17
```

which confirmed:

*   ✅ Podman VM running
    
*   ✅ Podman API reachable
    
*   ✅ Podman socket healthy
    
*   ✅ No active containers
    

## Kubernetes Locally Using WSL2, Ubuntu

In this setup, we created a local Kubernetes environment on a Windows machine using WSL2 (Windows Subsystem for Linux), Ubuntu, Docker, and Minikube. The goal was to build a clean development environment for learning and experimenting with Kubernetes.

* * *

### Step 1: Verifying WSL2

We first checked whether WSL2 was installed:

```bash
wsl --status
```

This confirmed that WSL2 was already enabled and running.

* * *

### Step 2: Installing Ubuntu on WSL2

We installed Ubuntu as our Linux environment:

```bash
wsl --install -d Ubuntu
```

This gave us a proper Linux-based development environment inside Windows.

* * *

### Step 3: Basic Linux Verification

Once inside Ubuntu, we verified the system:

```bash
uname -a
pwd
ls -la
```

This ensured we were running inside a Linux kernel (WSL2).

* * *

### Step 4: Installing Minikube

We downloaded and installed Minikube:

```bash
cd ~
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
```

Verification:

```bash
minikube version
```

* * *

### Step 5: Installing Docker

Minikube requires a container runtime, so we installed Docker:

```bash
sudo apt update
sudo apt install -y docker.io
sudo service docker start
sudo usermod -aG docker $USER
```

After this, we restarted the shell and verified:

```bash
docker --version
```

* * *

### Step 6: Starting Kubernetes Cluster

Finally, we started the local Kubernetes cluster using Docker as the driver:

```bash
minikube start --driver=docker
```

To verify the cluster:

```bash
kubectl get nodes
```

## How to Build and Run Docker Images Locally in Kubernetes (Without Docker Hub)

When developing applications for Kubernetes locally, pushing images to a remote registry like Docker Hub for every single code change is a massive bottleneck. This guide walks through how we bypassed Docker Hub using **Minikube** and resolved a common WSL terminal syntax trap.

* * *

### The Problem

By default, Kubernetes looks for images in public registries. If you build an image on your host machine and try to deploy it, Kubernetes throws an `ErrImagePull` or `ImagePullBackOff` error because it cannot find the image in the cloud.

To fix this, we need to inject our local Docker image directly into Minikube's internal cluster environment.

* * *

### **The Troubleshooting Journey & Fixes**

1\. Fixing the Bash Substitution Error

Our first attempt was to point our local terminal's Docker daemon to Minikube using command substitution. We ran into this error:

```bash
$ eval ${minikube docker-env}
-bash: ${minikube docker-env}: bad substitution

```

*   **Why it happened:** In Bash, `${...}` is used for variable expansion, not executing commands.
    
*   **The Fix:** Switch curly braces to parentheses `$(...)` for proper command substitution:
    

```bash
eval $(minikube docker-env)

```

2\. Bypassing WSL Context Issues (The Ultimate Fix)

Even after fixing the syntax, running `docker ps` showed we were still looking at the host machine's Docker daemon instead of Minikube's. This is a common quirk when using **WSL (Windows Subsystem for Linux)**.

Instead of fighting the environment variables, we bypassed the `eval` command entirely by using Minikube’s dedicated build CLI. We just had to remember the trailing dot `.` to specify the build context (current directory):

```bash
minikube image build -t go-k8s-app:local .

```

This forces Minikube to grab the local directory, ship it to its internal cluster daemon, and build it natively inside Kubernetes.

* * *

### Summary of Commands Used

| Command | Purpose |
| --- | --- |
| `minikube start` | Spins up the local Kubernetes cluster. |
| `minikube image build -t go-k8s-app:local .` | Builds the Docker image **directly** inside Minikube's environment (replaces `docker build`). |
| `minikube image ls` | Verifies that the image successfully exists inside the cluster cache. |
| `kubectl apply -f <file>.yaml` | Deploys the application manifests to the cluster. |
| `minikube service go-app-service` | Exposes and opens the application endpoint in your browser. |

* * *

### Critical Rules for Local YAML Manifests

When deploying local images without a registry, you **must** update your Deployment YAML container spec with two things:

1.  Use a local tag (e.g., `image: go-k8s-app:local`).
    
2.  Set `imagePullPolicy: Never` (or `IfNotPresent`). This explicitly tells Kubernetes to stop looking on Docker Hub and pull it from the local Minikube cache instead.
    

```yaml
spec:
  containers:
  - name: go-app
    image: go-k8s-app:local
    imagePullPolicy: Never # 👈 The secret sauce

```
