I'm Running My Infra ACTUALLY Free Now
Well. I did it. I’ve been on a mission to run my entire infrastructure for free. Not just cheap, but actually $0 per month. AWS got me partway there, but between surprise charges and fees just to check usage, it wasn’t cutting it. We’re still running some AWS stuff. But it’s not enough. Trying to protect yourself from overspending in AWS is hard. Ironically, their Cost Explorer API costs money, and I ended up getting too granular trying to squeeze every cent… which ended up costing me more than the EC2 usage itself.
This post focuses on one specific piece: the FoundryVTT server I spin up and down on a schedule to save money. It needs IPv4 and DNS to serve… and that costs money. Watching your usage? Also costs money. I can’t do this anymore.
Here’s where the costs stack up the most:
The public IPv4 address
Monitoring AWS costs with any meaningful granularity

So we’re migrating.
No more AWS nickel-and-diming. Welcome to multi-cloud.
Enter: IPv6 + GCP Free Tier
At JCK Labs™ we’ve been doing some digging. Why use just one cloud when you can go multi-cloud?
Most cloud providers (even AWS!) give you IPv6 for free. But forget AWS for this one… we’re moving the Foundry game server to Google Cloud:
- t3.micro equivalent VM
- 30 GB boot disk
- 1 GB egress
- Free IPv6
- All within the free tier
Yes, 1 GB egress is tight. But with good caching and offloading heavy stuff to S3, it’s doable.
Now, I know what you’re thinking:
“But most people’s home networks don’t even support IPv6…”
Cloudflare to the rescue.
Cloudflare’s proxies can terminate IPv6 and forward to IPv4: effectively giving you dual-stack support.
The Catch: Foundry’s IPv4 Licensing Shenanigans
There’s one critical problem:
FoundryVTT’s license server doesn’t support IPv6.
Not only does it require IPv4… it waits to reach out until after you accept the EULA, after the server starts. Beautiful.
BUT:
GCP allows 1 hour of IPv4 per month for free.
So… what did I do?
The Frankenstein Bootstrap Flow
I wrote a custom script that:
- Temporarily attaches an ephemeral IPv4
- Spins up Foundry + Caddy
- Waits for it to come online
- Accepts the EULA automatically
- Removes the IPv4
Yes. It’s cursed.
But it works.
Here it is in all its glory:
bash
#!/bin/bash
set -euo pipefail
# ---- CONFIG ----
INSTANCE_NAME="${INSTANCE_NAME:-foundry-vtt}"
ZONE="${ZONE}"
PROJECT_ID="${PROJECT_ID:-$(gcloud config get-value project)}"
COMPOSE_CMD="docker compose up -d"
WAIT_SECONDS="${WAIT_SECONDS}"
FQDN="${FQDN}"
PORT="${PORT}"
ACCESS_CONFIG_NAME="${ACCESS_CONFIG_NAME:-external-nat}"
# ---- FUNCTIONS ----
wait_for_ipv4() {
echo "Waiting for external IPv4 access..."
for ((i=0; i<30; i++)); do
if curl -4s --connect-timeout 2 http://ifconfig.co > /dev/null; then
echo "IPv4 external access is ready."
return 0
fi
echo "Waiting... (${i}s)"
sleep 1
done
echo "Timed out waiting for IPv4 access."
return 1
}
wait_for_foundry() {
echo "Waiting for Foundry to start (port ${PORT})..."
for ((i=0; i<60; i+=2)); do
if docker logs foundryvtt 2>&1 | grep -q "Server started and listening on port ${PORT}"; then
echo "Foundry started."
return 0
fi
echo "Waiting... (${i}s)"
sleep 2
done
echo "Timeout: Foundry did not start in time."
return 1
}
accept_eula() {
echo "Attempting to accept EULA..."
SESSION_COOKIE=$(curl -s -c - "http://${FQDN}/license" | grep session | awk '{print $6}')
if [ -n "$SESSION_COOKIE" ]; then
curl -s -X POST "http://${FQDN}/license" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Referer: http://${FQDN}/license" \
-H "Origin: http://${FQDN}" \
-b "session=$SESSION_COOKIE" \
--data "agree=on&accept="
echo "EULA accepted."
else
echo "Could not obtain session cookie. EULA not accepted."
fi
}
# ---- MAIN ----
echo "Associating ephemeral IPv4 with ${INSTANCE_NAME}..."
gcloud compute instances add-access-config "$INSTANCE_NAME" \
--zone="$ZONE" \
--project="$PROJECT_ID" \
--network-interface=nic0
IP_ADDR=$(gcloud compute instances describe "$INSTANCE_NAME" \
--zone="$ZONE" \
--project="$PROJECT_ID" \
--format="get(networkInterfaces[0].accessConfigs[0].natIP)")
echo "Assigned ephemeral IP: $IP_ADDR"
wait_for_ipv4
echo "Running: $COMPOSE_CMD"
eval "$COMPOSE_CMD"
if wait_for_foundry; then
accept_eula
fi
echo "Removing ephemeral IP from $INSTANCE_NAME..."
gcloud compute instances delete-access-config "$INSTANCE_NAME" \
--zone="$ZONE" \
--project="$PROJECT_ID" \
--network-interface=nic0 \
--access-config-name="$ACCESS_CONFIG_NAME"
Before, I could only host my Foundry server for ~4 hours a month… but now? I can host 24/7 for the entire month for FREE as long as I don’t go above 1gb egress… which is totally doable.
I can even have it snapshot my persistent storage for free as well. I have it scheduled to snapshot JUST after my sessions.
I even moved my budget lamda into Cloud Run, so now I can calculate aws and gcp budget in the same place.
Here is my updated cloud diagram:

Coming next: a zero-cost Discord bot that lives in the cloud rent free.