Networking
Private networking between VMs and deployments. Organization VPCs, regional subnets, firewall rules, exposed ports, and deployment references for service discovery.
Every VM in your organization shares a private network. Services talk to each other over internal IPs with no extra configuration. When you need finer control, firewall rules, exposed ports, and deployment references give you precise networking between deployments.
Private network¶
When you provision your first VM, JuhJuh automatically creates a private network for your organization. Every subsequent VM joins this network. Services running on different VMs can connect to each other using internal IP addresses, the same way services on a local network would.
Each region where you run VMs gets its own subnet. Subnets are allocated automatically. You do not need to plan CIDR blocks or configure routing between regions.
graph LR
subgraph Organization VPC
subgraph Region A
VM1[VM: app-server]
VM2[VM: worker-server]
end
subgraph Region B
VM3[VM: db-server]
end
end
VM1 <-->|internal IP| VM2
VM1 <-->|internal IP| VM3Key points:
- One private network per organization, created automatically on first VM provision
- Each region gets its own subnet (auto-allocated)
- All VMs in the organization can reach each other over internal IPs
- No manual network setup, VPN configuration, or peering required
Firewall rules¶
Firewall rules control which ports on your VMs accept traffic and from where. Every rule targets a single port and specifies whether the port is open to the public internet or restricted to your private network.
Access levels¶
| Access | Behavior |
|---|---|
public |
Port is reachable from the internet. Default when no access level is set |
internal |
Port is reachable only from within your organization's private network |
Defining rules in the JuhJuh File¶
Firewall rules can be defined at the root level (applied to all VMs) or on individual resources and services.
Root-level rules apply to every VM in the deployment:
yaml
firewall:
- port: 80
label: HTTP
description: Public web traffic
- port: 443
label: HTTPS
description: Public web traffic (TLS)
- port: 5432
access: internal
label: PostgreSQL
description: Database, private network only
Resource-level rules attach to a specific managed resource:
yaml
resources:
postgres:
type: postgres
firewall:
- port: 5432
access: internal
label: PostgreSQL
Rule fields¶
| Field | Required | Description |
|---|---|---|
port |
Yes | Port number (integer) |
protocol |
No | tcp (default) or udp |
access |
No | public (default) or internal |
allowedSources |
No | List of CIDR ranges allowed to connect. Default: ["0.0.0.0/0"] for public. Legacy alias: source_ranges |
label |
No | Short name shown in the infrastructure diagram |
description |
No | Longer description for documentation |
Restricting source ranges¶
For public ports that should only accept traffic from specific IPs (like a monitoring service or a partner API), set allowedSources:
yaml
firewall:
- port: 9090
label: Metrics
allowedSources:
- "203.0.113.0/24"
- "198.51.100.5/32"
Infrastructure diagram¶
Public firewall rules appear in the infrastructure diagram on the PaaS dashboard. JuhJuh draws connection lines from the internet zone to the service or proxy that accepts the traffic. Internal rules stay within the private network zone. This gives your team a visual map of what is exposed and what is not.
Exposed ports¶
When a deployment runs a service that other deployments need to connect to, you expose specific ports on the organization network with a named alias. This is how one deployment discovers another.
yaml
deployments:
database:
vm: db-server
resources: [postgres]
network: app-network
expose:
- port: 5432
alias: postgres
protocol: tcp
| Field | Required | Description |
|---|---|---|
port |
Yes | Port number being exposed |
alias |
Yes | Unique name for this service endpoint. Used in deployment references |
protocol |
No | tcp (default) or udp |
Aliases must be unique within a deployment. You can expose multiple ports from the same deployment, each with a different alias.
Deployment references¶
Once a deployment exposes a port, other deployments can reference it using the ${deployment.<name>.<attribute>} syntax. JuhJuh resolves these references to actual IP addresses and port numbers at deploy time.
Available attributes¶
| Attribute | Returns | Example |
|---|---|---|
host |
Internal IP address of the deployment's VM | 10.0.1.5 |
status |
Current deployment status | HEALTHY |
network |
Network name assigned to the deployment | app-network |
port.<alias> |
Port number for an exposed alias | 5432 |
endpoint.<alias> |
Full host:port string |
10.0.1.5:5432 |
Wiring services together¶
A common pattern: one deployment runs your database, another runs the application. The application deployment references the database's exposed port:
```yaml deployments: database: vm: db-server network: app-network expose: - port: 5432 alias: postgres
app: vm: app-server network: app-network dependsOn: - deployment: database condition: healthy
envGroups: app-env: clear: DATABASE_HOST: "${deployment.database.host}" DATABASE_PORT: "${deployment.database.port.postgres}" DATABASE_URL: "postgres://user:pass@${deployment.database.endpoint.postgres}/mydb" ```
JuhJuh resolves ${deployment.database.endpoint.postgres} to something like 10.0.1.5:5432 when deploying the app. The dependsOn field ensures the database is healthy before the app starts.
Requirements for deployment references:
- The target deployment must be listed in the referencing deployment's
dependsOnfield - Port and endpoint references require the target deployment to expose that alias
- The target deployment must be provisioned and reporting a status before references resolve
Named networks¶
For deployments that need to communicate with each other, define a named network in the networks section of your JuhJuh File and assign it to each deployment.
```yaml networks: app-network: scope: organization driver: bridge subnet: auto
deployments: database: vm: db-server network: app-network expose: - port: 5432 alias: postgres
app: vm: app-server network: app-network ```
Network fields¶
| Field | Default | Description |
|---|---|---|
scope |
organization |
Network scope. All deployments in the organization can join |
driver |
bridge |
Network driver |
subnet |
auto |
Subnet allocation. Use auto for automatic CIDR assignment, or specify a range like 10.0.0.0/16 |
Deployments on the same named network can communicate with each other. Use expose to make specific ports discoverable across the network.
Config-level network settings¶
You can also set network properties in the config section. This applies a default network to all services in the orchestration output:
yaml
config:
network:
name: my-app-network
driver: bridge
This is useful when all your services should share a single network without repeating the network name in every deployment.
Dashboard management¶
The PaaS dashboard shows your organization's network status:
- Infrastructure diagram. A visual map of your VMs, deployments, firewall rules, and network connections. Public ports show internet-facing connection lines. Internal ports stay within the private network zone.
- VM details. Each VM displays its static IP, internal IP, and the region subnet it belongs to.
- Deployment details. Each deployment shows its exposed ports, network attachment, and the resolved deployment references.
Firewall rules can be added during VM creation through the dashboard wizard or defined in the JuhJuh File. Both paths produce the same result.
Full example¶
A two-VM setup with a database and an application server, connected over a private network:
```yaml name: my-app
networks: internal: scope: organization driver: bridge subnet: auto
firewall: - port: 80 label: HTTP - port: 443 label: HTTPS - port: 5432 access: internal label: PostgreSQL
resources: postgres: type: postgres plan: standard config: max_connections: 200
vms: db-server: cpu: 2 memory_gb: 8 disk_gb: 100 app-server: cpu: 4 memory_gb: 16 disk_gb: 50
deployments: database: vm: db-server resources: [postgres] network: internal expose: - port: 5432 alias: postgres
app: vm: app-server image: registry.example.com/my-app tag: v1.0.0 network: internal services: [web, worker] dependsOn: - deployment: database condition: healthy
envGroups: app-env: clear: DATABASE_URL: "postgres://app:secret@${deployment.database.endpoint.postgres}/mydb"
services: web: type: web port: 8000 env_from: [app-env] worker: type: worker env_from: [app-env] ```
This configuration:
- Creates two VMs in your organization's private network
- Opens HTTP and HTTPS publicly, keeps the database port internal
- Exposes the database on the organization network with the alias
postgres - Wires the application to the database using deployment references
- Ensures the database is healthy before the application starts
Related¶
- Deployments: ship container images to VMs with network attachment and exposed ports
- VMs: provision the machines that join your private network
- JuhJuh File: define networks, firewall rules, and deployment references in code
- Infrastructure Overview: see how networking fits into the full infrastructure stack
- Vault: inject secrets into deployments alongside network configuration
- CLI: provision and manage infrastructure from your terminal