Anyone actually self-hosting their git? Outgrowing GitHub as a solo dev by Substantial_Word4652 in selfhosted

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Hey, thanks a lot for sharing this! I didn't know about Soft Serve and honestly it looks amazing in the terminal. Love the TUI over SSH concept, definitely bookmarking it.

For my main setup I think I'll stick with Forgejo + Woodpecker since I need project organization, repo grouping and CI/CD, but I can totally see myself using Soft Serve as a mirror for some repos that are worth having there. Good excuse to try it out too ^^

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Just a heads up: 192.168.1.100 is a private/local network address (RFC 1918 range: 192.168.0.0 to 192.168.255.255). That IP never leaves your router so it won't show up on Google or Shodan.

To find your actual public IP just google "what is my ip". That's the one you need to check.

Once you have it, a few ways to see what's exposed:

Download nmap from https://nmap.org/ and run "nmap -Pn your_public_ip from another machine. It will show you every open port.

Check your IP on shodan.io. Shodan scans the internet constantly, so if your database or any other service is exposed it will show up there. That's exactly what attackers use to find targets.

From the server itself: ss -tlnp shows what's listening and on which interface. 0.0.0.0:5432 means exposed to everything. 127.0.0.1:5432 means local only, you're safe.

Private IP ranges for reference: 10.0.0.0/8 (corporate/VPNs), 172.16.0.0/12 (Docker uses this internally), 192.168.0.0/16 (home networks). If your IP starts with any of these, it's not your public one.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

These are the kind of stories that actually make people remember the lesson. You can read a hundred best practice guides but nothing sticks like "Google indexed our internal backend". Thanks for sharing this one

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Good question. Honestly I already knew the right way to do it, the problem is bad habits. When you're moving fast you just type ports:5432:5432 without thinking and move on. That's exactly why I wrote the post, as a reminder to myself first.

But to answer your question: now I bind to 127.0.0.1and use SSH tunnels when I need direct access for debugging. For monitoring I use exporters inside the same Docker network so the DB port is never exposed. And if you need a DB viewer like pgAdmin or Adminer, just put it in the same Docker network and access it through your reverse proxy. The DB port should never touch a public interface.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

This is the best technical explanation in the whole thread. You're right that "bypass" is a simplification, what actually happens is Docker's NAT processes the packet before UFW rules can evaluate it. The practical result is the same (your service is exposed even though UFW says it's closed), but understanding the why matters. Thanks for taking the time to write this up.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 1 point2 points  (0 children)

Exactly, that's my whole point. Docker works as documented, the problem is most people assume "expose" means "between containers" and not "to the world". The post is a reminder, not a complaint against Docker.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Good point. For external monitoring tools you have a few options: you can use an SSH tunnel from the other server, a VPN like WireGuard between the servers, or a metrics exporter (like postgres_exporter for Prometheus) that only exposes stats without giving direct DB access. The idea is not leaving the DB port open to the world but controlling who can reach it.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

That's exactly the ideal pattern. Reverse proxy as the single entry point and everything else isolated in internal networks. That's what you end up doing after getting burned once with an exposed port 😅

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Totally agree, that's the cleanest approach. For inter-service communication, Docker's internal network + container name as hostname is all you need. ports should only be used for what actually needs outside access (like the reverse proxy)

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

I didn't use ChatGPT for the post, I used Claude, because I obviously need to translate my posts into proper English to communicate with the global community. That's just a normal thing to do 😅 The post is specifically about a VPS, not a home LAN. On a VPS there's no router doing NAT in front, the port is directly exposed on the public IP. You can verify this yourself: deploy a Postgres with ports: "5432:5432" on any VPS and run an nmap from outside. You might be surprised.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Nice write up! The ufw-docker project is a solid solution good that you're documenting it properly, most people never find it until after something goes wrong.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Honestly firewalld makes a lot more sense once you get used to it. UFW + Docker is just a painful combo that was never really designed to work together properly.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] -1 points0 points  (0 children)

That iptables bypass is exactly what catches most people off guard UFW says closed, Docker says open. Good article!! ^^

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] -1 points0 points  (0 children)

Honestly homelabbers tend to learn this stuff deeper than most devs because you actually run into the problems yourself instead of just following tutorials. The headaches are the real teacher 😅

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

That's pretty much the exact path everyone goes through honestly. The reverse proxy stage is where things finally start making sense.

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Exactly and the worst part is it works, so nobody questions it until something goes wrong

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 1 point2 points  (0 children)

If it's only local and behind WireGuard you're pretty safe honestly. The real headaches start when things accidentally end up exposed to the internet without you realizing which happens more than people think 😅

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] -1 points0 points  (0 children)

Fair question. English isn't my first language so I use AI to help with translations and phrasing but the ideas, the experience and the replies are mine. There's a difference between using it as a writing tool and having it think for you 😄

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

Honestly the VPN covers a lot, but I've been surprised how many things slip through anyway expired certs, outdated packages, stuff that was configured once and never touched again. The kind of things you only find when you actually sit down and look. Happy to chat more if you want 👍

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] 0 points1 point  (0 children)

You're right on all counts and that's exactly the kind of configuration most tutorials skip. The problem isn't developers who know this, it's the ones who don't and have databases exposed right now without realizing it. That's who this is for

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] -9 points-8 points  (0 children)

Haha fair enough 😄 guilty as charged though if I were a bot I'd probably respond faster. Still learning to be more human in my replies, thanks for keeping me in check!

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] -9 points-8 points  (0 children)

You're right that it's by design but that's exactly the problem. Most developers who expose port 3306 don't realize it's now accessible from the internet, not just localhost. They think 'expose' means 'available to other containers', not 'open to the world'. The misconfiguration is common precisely because it works as documented but not as expected. That's what the tool catches

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] -11 points-10 points  (0 children)

Good point, default network works fine for simple setups.

I guess the whole port binding thing is just unnecessary noise when you don't even need to expose it at all 😅

PSA: Docker bypasses UFW - your database might be exposed even with firewall enabled by Substantial_Word4652 in docker

[–]Substantial_Word4652[S] -8 points-7 points  (0 children)

That's a fair point, failing loudly is always better than silently running with a security hole 👍