Add v5 architecture docs and update dev bootstrap, seeding, and tests to use bridged Lima .local hosts with a container-accessible SSH key.
5.6 KiB
coold Dev Environment Notes
This file documents the current local v5/coold dev setup in Coolify.
Roles
scripts/dev.shis the main developer-facing entrypoint. Use it for normal local workflows such as starting/stopping the stack, creating fresh dev state, inspecting Corrosion, managing firewall allow rules, and running example containers.scripts/coold-vm.shis a lower-level Lima VM helper used byscripts/dev.sh. It exists separately to keep VM lifecycle and guest setup details out of the main dev orchestration script. Call it directly only when debugging or operating an individual VM, for exampleshell,status,logs-agent, ordelete.- Lima VMs act like real deployment servers.
coolify init bootstrapowns host wiring:- WireGuard
- Podman mesh networks
- Corrosion config/schema/service
- coold install/service
- builder install/config
- default-deny firewall service
- Coolify/Laravel dev owns Flux-specific wiring:
- starts Flux inside the Coolify container
- mints dev host JWTs
- installs
/etc/coolify/host-jwtinto each VM - adds a
coold.servicesystemd drop-in withCOOLIFY_COOLD_FLUX_URL
Main commands
scripts/dev.sh up
scripts/dev.sh down
scripts/dev.sh clean-vms
scripts/dev.sh list
clean-vms deletes the Lima VM instances and VM-local state, including disks,
containers, WireGuard keys, Corrosion DB, installed binaries, and firewall state.
It does not delete the Coolify repo.
coolify helper
scripts/dev.sh coolify install
scripts/dev.sh coolify path
scripts/dev.sh coolify bootstrap-command
scripts/dev.sh coolify run <args>
The helper runs the coolify CLI from the Coolify development container. Lima
VMs are addressed by their bridged mDNS names (<vm>.local), so the same
addresses are used by bootstrap and by the v5 dev server seeder.
Because Docker Desktop does not reliably pass mDNS multicast into containers,
scripts/dev.sh up resolves each <vm>.local name on the host and writes the
resolved records into the Coolify container /etc/hosts before bootstrapping.
The generated bootstrap command uses the container CLI, the repo-local copy of the Lima SSH key, and dev WireGuard endpoint overrides, for example:
spin exec -T coolify /usr/local/bin/coolify init bootstrap \
--nodes "coold-dev.local,coold-dev-2.local" \
--ssh-key "/var/www/html/.dev/lima/ssh_key" \
--ssh-user "coolify" \
--wg-listen-port-overrides "coold-dev.local=51821,coold-dev-2.local=51822" \
--wg-endpoint-overrides "coold-dev.local=coold-dev.local:51821,coold-dev-2.local=coold-dev-2.local:51822" \
--coold-version "nightly" \
--corrosion-version "v1.0.0" \
--yes
Lima does not allow direct root SSH by default, so dev uses the normal Lima user
with passwordless sudo. coolify wraps remote commands in sudo -n bash -lc
when the SSH user is not root.
Default dev topology
After coolify init bootstrap, defaults are:
| VM | WireGuard IP | WireGuard endpoint | Podman subnet | Gateway |
|---|---|---|---|---|
coold-dev |
100.64.0.1 |
coold-dev.local:51821 |
10.210.0.0/24 |
10.210.0.1 |
coold-dev-2 |
100.64.0.2 |
coold-dev-2.local:51822 |
10.210.1.0/24 |
10.210.1.1 |
Checking state
scripts/dev.sh corrosion check
scripts/dev.sh corrosion containers
scripts/dev.sh corrosion config
scripts/dev.sh corrosion logs 1
scripts/dev.sh corrosion logs 2
corrosion containers shows both Corrosion service_endpoints and rootful /
rootless Podman containers.
Example nginx containers
scripts/dev.sh example-nginx up
scripts/dev.sh example-nginx check-dns
scripts/dev.sh example-nginx down
The example containers are started with coold DNS:
--dns <local-mesh-gateway>
--dns-search default.coolify.internal
Expected service discovery format:
<container-name>.default.coolify.internal
Example:
coolify-example-nginx-2.default.coolify.internal -> 10.210.1.x
Firewall behavior
The mesh firewall is default-deny for inter-container traffic. Host-to-host WireGuard traffic can work while container-to-container traffic is blocked.
Allow traffic:
scripts/dev.sh firewall allow 10.210.0.2 10.210.1.2 tcp 80
scripts/dev.sh firewall list
Revoke traffic:
scripts/dev.sh firewall revoke
scripts/dev.sh firewall revoke <rule-id>
Why dev adds allow rules to both hosts
business traffic from container A on host 1 to container B on host 2 crosses
forwarding/firewall logic on both sides:
10.210.0.2
-> source host bridge/firewall
-> coold-dev wg0
-> WireGuard
-> coold-dev-2 wg0
-> destination host bridge/firewall
-> 10.210.1.2
The default-deny hooks can drop the packet on either the source or destination
host. For the two-node dev setup, scripts/dev.sh firewall allow writes the
same allow tuple to every coold VM so the path works reliably.
Production should become topology-aware instead of blindly writing to every host:
- cross-host traffic: write allow rules to the source and destination hosts
- same-host traffic: write the allow rule only to that host
- larger clusters: do not install unrelated allow rules on unaffected hosts
Manual connectivity checks
Before allow rule, this should time out:
scripts/dev.sh shell 1
sudo podman exec coolify-example-nginx wget -T 3 -qO- http://10.210.1.2
After allow rule, this should return nginx HTML:
scripts/dev.sh firewall allow 10.210.0.2 10.210.1.2 tcp 80
scripts/dev.sh shell 1
sudo podman exec coolify-example-nginx wget -T 5 -qO- http://10.210.1.2 | head -n 1
Expected:
<!DOCTYPE html>