Skip to content

06. Use a local package and service-to-service dependency

So far, each tutorial cluster has had one service. This tutorial adds the first service-to-service relationship.

You will run the 06-service-dep example from kix-examples: an nginx gateway proxies to a backend echo-server. The gateway package asks Kix for a backend dependency, then uses the backend’s public out values to build its nginx config. You will use and inspect the local package here; the next tutorial will spend more time on package anatomy.

This tutorial returns to a checked-in example, so you do not need to keep the files from tutorial 04 staged.

Open:

tutorials/06-service-dep/cluster.nix
tutorials/06-service-dep/reverse-proxy-package.nix

The cluster has two instances in the tutorial-06 namespace:

InstancePackageJob
backendpackages.echo-serveranswers HTTP with a fixed message
gatewaylocal reverse-proxy-package.nixproxies HTTP traffic to backend

When you curl the gateway, the request path is:

localhost:8080 -> gateway pod -> backend Service -> backend pod

No Ingress or LoadBalancer is involved. This is just two ClusterIP Services and one dependency edge.

The previous tutorials used a catalog package from kixpkgs: packages.echo-server.

This example also imports a package from the example folder:

tutorials/06-service-dep/cluster.nix (L32–L34)
let
reverseProxyPackage = import ./reverse-proxy-package.nix;
in

View source on GitHub ↗

let ... in ... creates a local binding. Here it means: evaluate ./reverse-proxy-package.nix once, call it reverseProxyPackage, and use that name later in the cluster definition.

This keeps cluster composition and package implementation separate:

  • cluster.nix says which package instances are installed;
  • reverse-proxy-package.nix says how the local package builds Kubernetes resources.

The cluster installs two package instances:

tutorials/06-service-dep/cluster.nix
backend = {
package = packages.echo-server;
config = {
message = "Hello from the backend!";
};
};
gateway = {
package = reverseProxyPackage;
};

The backend instance is a normal echo-server. The gateway instance uses the local reverse-proxy package.

Notice what the gateway instance does not say: it does not include a Service name, namespace, DNS name, or port for the backend. The package asks for a backend dependency, and Kix resolves that request to the instance named backend in the same namespace.

That same-namespace name match is the first dependency resolution rule you need to learn. Later tutorials will make cross-namespace dependencies explicit.

Open tutorials/06-service-dep/reverse-proxy-package.nix. The package’s build function receives named arguments from Kix:

tutorials/06-service-dep/reverse-proxy-package.nix (L39–L46)
build =
{
self,
scope,
kix,
backend,
...
}:

View source on GitHub ↗

Do not try to unpack every argument yet. The important new one is backend. That is the dependency. Inside the package, backend exposes an out API with values the package can use safely.

For now, treat out as the public interface another instance exposes. It gives you names, DNS names, ports, selectors, and similar values without hardcoding them.

The reverse proxy writes an nginx config into a ConfigMap:

tutorials/06-service-dep/reverse-proxy-package.nix (L70–L86)
configmap = scope.mkResource {
apiVersion = "v1";
kind = "ConfigMap";
inherit name;
data."default.conf" = ''
server {
listen 80;
location /healthz {
default_type text/plain;
return 200 'ok\n';
}
location / {
proxy_pass http://${backend.out.fqdn}:${backend.out.port}/;
}
}
'';
};

View source on GitHub ↗

The important line is the proxy_pass target:

proxy_pass http://${backend.out.fqdn}:${backend.out.port}/;

That line does two jobs:

  • it builds a real nginx upstream URL using the backend Service DNS name and port;
  • it consumes the backend’s public values instead of repeating Kubernetes names by hand.

You do not need to hand-copy the backend Service name into the gateway config. The package dependency creates the relationship; the package code reads the backend’s public interface.

Before deploying, ask Kix to evaluate and check the cluster:

Run in kix-examples/
❱ kix check 06-service-dep
 TOOL         RESULT  DETAILS                                                       
 eval         pass    14 manifests evaluated                                        
 kubeconform  pass    skipped (this validation tool is not yet integrated with Kix) 
 pluto        pass    skipped (this validation tool is not yet integrated with Kix) 
 kyverno      pass    skipped (this validation tool is not yet integrated with Kix) 
 scorecard    pass    0 errors, 9 warnings, 2 info

Deploy the example:

Run in kix-examples/
❱ kix deploy 06-service-dep -y Show output
Building cluster '06-service-dep'...
Cluster 06-service-dep: 14 manifests
Connecting to cluster...
No previous activation on cluster — first deploy.
Reading live cluster state...

  _cluster
    ~ cluster-level resources (1 added, 2 removed)
  tutorial-02
    - hello-world 1.27 (3 resources)
  tutorial-04
    - hello-world 1.27 (3 resources)
  tutorial-06
    + backend 1.27 (3 resources)
    + gateway 0.0.1 (3 resources)

  Plan: cluster-level changes, 2 added, 2 removed, 1 unchanged
  Resources: 3 real content, 0 dep-affected
  10 orphaned (kept; pass --prune to delete)
    - Deployment/hello-world@tutorial-02
    - Namespace/tutorial-02
    - ConfigMap/hello-world@tutorial-04
    - ConfigMap/hello-world@tutorial-02
    - PackageInstance/hello-world@tutorial-02
    - Service/hello-world@tutorial-04
    - PackageInstance/hello-world@tutorial-04
    - Service/hello-world@tutorial-02
    - Deployment/hello-world@tutorial-04
    - Namespace/tutorial-04
plan: 14 nodes
  + Namespace/tutorial-06 created
  ✔ Namespace/tutorial-06 ready
  + ConfigMap/backend@tutorial-06 created
  ✔ ConfigMap/backend@tutorial-06 ready
  + Deployment/backend@tutorial-06 created
  ✔ Deployment/backend@tutorial-06 ready
  + Service/backend@tutorial-06 created
  ✔ Service/backend@tutorial-06 ready
  + PackageInstance/backend@tutorial-06 created
  ✔ PackageInstance/backend@tutorial-06 ready
  + ConfigMap/gateway@tutorial-06 created
  ✔ ConfigMap/gateway@tutorial-06 ready
  + Deployment/gateway@tutorial-06 created
  ✔ Deployment/gateway@tutorial-06 ready
  + Service/gateway@tutorial-06 created
  ✔ Service/gateway@tutorial-06 ready
  + PackageInstance/gateway@tutorial-06 created
  ✔ PackageInstance/gateway@tutorial-06 ready
  + Activation/06-service-dep-gfqhjshmmm8b created
  ✔ Activation/06-service-dep-gfqhjshmmm8b ready

prune: 10 orphaned resources kept (warn-only; pass --prune to delete)
  - PackageInstance/hello-world@tutorial-04
  - Service/hello-world@tutorial-04
  - Deployment/hello-world@tutorial-04
  - ConfigMap/hello-world@tutorial-04
  - Namespace/tutorial-04
  - PackageInstance/hello-world@tutorial-02
  - Service/hello-world@tutorial-02
  - Deployment/hello-world@tutorial-02
  - ConfigMap/hello-world@tutorial-02
  - Namespace/tutorial-02
  • activation '06-service-dep-gfqhjshmmm8b' → Active

Deploy complete: 10 created, 0 configured, 4 unchanged, 0 failed

Port-forward to the gateway:

Run in kix-examples/
❱ kix pf 06-service-dep gateway 8080:80

In another terminal:

❱ curl http://localhost:8080/
Hello from the backend!

The response comes from the backend pod. The gateway only proxies the request.

Stop the port-forward with Ctrl-C.

Ask Kix to show the dependency graph:

Run in kix-examples/
❱ kix graph 06-service-dep --format tree Show output
CustomResourceDefinition/activations.kix.run
└── Activation/06-service-dep-ijyb6jl72rsh
CustomResourceDefinition/packageinstances.kix.run
├── PackageInstance/gateway@tutorial-06
│   └── Activation/06-service-dep-ijyb6jl72rsh
├── PackageInstance/backend@tutorial-06
│   └── Activation/06-service-dep-ijyb6jl72rsh
└── PackageInstance/platform-dns@kube-system (import)
    ├── Activation/06-service-dep-ijyb6jl72rsh
    └── Deployment/gateway@tutorial-06
        └── Service/gateway@tutorial-06
            └── PackageInstance/gateway@tutorial-06
                └── Activation/06-service-dep-ijyb6jl72rsh
Namespace/kube-system
└── PackageInstance/platform-dns@kube-system (import)
    ├── Activation/06-service-dep-ijyb6jl72rsh
    └── Deployment/gateway@tutorial-06
        └── Service/gateway@tutorial-06
            └── PackageInstance/gateway@tutorial-06
                └── Activation/06-service-dep-ijyb6jl72rsh
Namespace/tutorial-06
├── Service/gateway@tutorial-06
│   └── PackageInstance/gateway@tutorial-06
│       └── Activation/06-service-dep-ijyb6jl72rsh
├── Service/backend@tutorial-06
│   ├── ConfigMap/gateway@tutorial-06
│   │   └── Deployment/gateway@tutorial-06
│   │       └── Service/gateway@tutorial-06
│   │           └── PackageInstance/gateway@tutorial-06
│   │               └── Activation/06-service-dep-ijyb6jl72rsh
│   └── PackageInstance/backend@tutorial-06
│       └── Activation/06-service-dep-ijyb6jl72rsh
├── ConfigMap/gateway@tutorial-06
│   └── Deployment/gateway@tutorial-06
│       └── Service/gateway@tutorial-06
│           └── PackageInstance/gateway@tutorial-06
│               └── Activation/06-service-dep-ijyb6jl72rsh
├── ConfigMap/backend@tutorial-06
│   └── Deployment/backend@tutorial-06
│       └── Service/backend@tutorial-06
│           ├── ConfigMap/gateway@tutorial-06
│           │   └── Deployment/gateway@tutorial-06
│           │       └── Service/gateway@tutorial-06
│           │           └── PackageInstance/gateway@tutorial-06
│           │               └── Activation/06-service-dep-ijyb6jl72rsh
│           └── PackageInstance/backend@tutorial-06
│               └── Activation/06-service-dep-ijyb6jl72rsh
├── PackageInstance/gateway@tutorial-06
│   └── Activation/06-service-dep-ijyb6jl72rsh
├── PackageInstance/backend@tutorial-06
│   └── Activation/06-service-dep-ijyb6jl72rsh
├── Deployment/gateway@tutorial-06
│   └── Service/gateway@tutorial-06
│       └── PackageInstance/gateway@tutorial-06
│           └── Activation/06-service-dep-ijyb6jl72rsh
└── Deployment/backend@tutorial-06
    └── Service/backend@tutorial-06
        ├── ConfigMap/gateway@tutorial-06
        │   └── Deployment/gateway@tutorial-06
        │       └── Service/gateway@tutorial-06
        │           └── PackageInstance/gateway@tutorial-06
        │               └── Activation/06-service-dep-ijyb6jl72rsh
        └── PackageInstance/backend@tutorial-06
            └── Activation/06-service-dep-ijyb6jl72rsh
14 resources, 24 dependencies

Look for the gateway instance and the backend resources it depends on.

You can also render the manifests and inspect the generated nginx config:

Run in kix-examples/
❱ kix build 06-service-dep Show output
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    kix.run/identity-hash: gvrlspcfgh9a2qnsx5kqxw9f4l3x52jj
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
  labels:
    app.kubernetes.io/managed-by: kix
  name: activations.kix.run
spec:
  group: kix.run
  names:
    kind: Activation
    listKind: ActivationList
    plural: activations
    singular: activation
  scope: Cluster
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        properties:
          apiVersion:
            type: string
          kind:
            type: string
          metadata:
            type: object
          spec:
            type: object
            x-kubernetes-preserve-unknown-fields: true
          status:
            type: object
            x-kubernetes-preserve-unknown-fields: true
        type: object
    served: true
    storage: true
    subresources:
      status: {}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    kix.run/identity-hash: pk4hih6jm4yj336rlaqk2qycz2k46xvs
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
  labels:
    app.kubernetes.io/managed-by: kix
  name: packageinstances.kix.run
spec:
  group: kix.run
  names:
    kind: PackageInstance
    listKind: PackageInstanceList
    plural: packageinstances
    singular: packageinstance
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        properties:
          apiVersion:
            type: string
          kind:
            type: string
          metadata:
            type: object
          spec:
            type: object
            x-kubernetes-preserve-unknown-fields: true
          status:
            type: object
            x-kubernetes-preserve-unknown-fields: true
        type: object
    served: true
    storage: true
    subresources:
      status: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc,wlzmynapx327962105rsvvnmaqyw2vyn'
    kix.run/identity-hash: cqx7f7f2w1pa7llx2zrk7p3qb374if76
    kix.run/package: backend
    kix.run/package-namespace: tutorial-06
  labels:
    app.kubernetes.io/instance: backend
    app.kubernetes.io/managed-by: kix
    app.kubernetes.io/name: backend
  name: backend
  namespace: tutorial-06
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: backend
      app.kubernetes.io/name: backend
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: backend
        app.kubernetes.io/name: backend
    spec:
      containers:
      - image: nginxinc/nginx-unprivileged:1.27-alpine
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 8080
          periodSeconds: 10
        name: nginx
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        readinessProbe:
          failureThreshold: 1
          httpGet:
            path: /healthz
            port: 8080
          periodSeconds: 5
        resources:
          limits:
            cpu: '100m'
            memory: '64Mi'
          requests:
            cpu: '50m'
            memory: '32Mi'
        securityContext:
          runAsNonRoot: true
        volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: config
          readOnly: true
      volumes:
      - configMap:
          name: backend
        name: config
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc,by3dv0xzvky726i7a8b27mmqv46rgkhy,requires:jh345cnnffy1bnj4cz5x0hwq6ibxvkkr'
    kix.run/identity-hash: d8lsi37jfr7i49svzfc52nqgzpjb97i3
    kix.run/package: gateway
    kix.run/package-namespace: tutorial-06
  labels:
    app.kubernetes.io/instance: gateway
    app.kubernetes.io/managed-by: kix
    app.kubernetes.io/name: gateway
  name: gateway
  namespace: tutorial-06
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: gateway
      app.kubernetes.io/name: gateway
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: gateway
        app.kubernetes.io/name: gateway
    spec:
      containers:
      - image: nginx:1.27-alpine
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        readinessProbe:
          httpGet:
            path: /healthz
            port: 80
          periodSeconds: 5
        volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: config
          readOnly: true
      volumes:
      - configMap:
          name: gateway
        name: config
---
apiVersion: kix.run/v1alpha1
kind: Activation
metadata:
  annotations:
    kix.run/built-via: /nix/store/hnlf8ghnyr7khhvgkhvjz1alnscqiir6-k8s-activation-06-service-dep
    kix.run/depends-on: hk1cigl67rdmdp9yi6l0cy6dd09n874y,jh345cnnffy1bnj4cz5x0hwq6ibxvkkr,rrr57m2k9ihrv8pppy2y6cfd60yz6r8x,requires:gvrlspcfgh9a2qnsx5kqxw9f4l3x52jj
    kix.run/identity-hash: ijyb6jl72rshzxfx2y87xrr1998hkjan
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
  labels:
    app.kubernetes.io/managed-by: kix
    kix.run/cluster: '06-service-dep'
  name: '06-service-dep-ijyb6jl72rsh'
spec:
  instances:
    kube-system:
      platform-dns: platform-dns
    tutorial-06:
      backend: backend
      gateway: gateway
---
apiVersion: kix.run/v1alpha1
kind: PackageInstance
metadata:
  annotations:
    kix.run/depends-on: sj0fv5bs2hnh9zcqdh62ph34l2wm0b1m,requires:pk4hih6jm4yj336rlaqk2qycz2k46xvs
    kix.run/identity-hash: jh345cnnffy1bnj4cz5x0hwq6ibxvkkr
    kix.run/import-apiversion: apps/v1
    kix.run/import-fqdn: kube-dns.kube-system.svc.cluster.local
    kix.run/import-kind: Deployment
    kix.run/import-name: coredns
    kix.run/mode: import
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
  labels:
    app.kubernetes.io/instance: platform-dns
    app.kubernetes.io/managed-by: kix
  name: platform-dns
  namespace: kube-system
spec:
  instanceName: platform-dns
  mode: import
  namespaceName: kube-system
---
apiVersion: kix.run/v1alpha1
kind: PackageInstance
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc,7iprxwy73s26bjhm4cyx5agmpz2q14lz,requires:pk4hih6jm4yj336rlaqk2qycz2k46xvs'
    kix.run/identity-hash: rrr57m2k9ihrv8pppy2y6cfd60yz6r8x
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
    kix.run/root: backend
  labels:
    app.kubernetes.io/instance: backend
    app.kubernetes.io/managed-by: kix
  name: backend
  namespace: tutorial-06
spec:
  instanceName: backend
  namespaceName: tutorial-06
  version: '1.27'
---
apiVersion: kix.run/v1alpha1
kind: PackageInstance
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc,fsvvbizzzlqmzya0ccprxxci2dfqym28,requires:pk4hih6jm4yj336rlaqk2qycz2k46xvs'
    kix.run/identity-hash: hk1cigl67rdmdp9yi6l0cy6dd09n874y
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
    kix.run/root: gateway
  labels:
    app.kubernetes.io/instance: gateway
    app.kubernetes.io/managed-by: kix
  name: gateway
  namespace: tutorial-06
spec:
  instanceName: gateway
  namespaceName: tutorial-06
  version: '0.0.1'
---
apiVersion: v1
data:
  default.conf: |
    server {
        listen 8080;
        location / {
            default_type text/plain;
            return 200 'Hello from the backend!\n';
        }
        location /healthz {
            default_type text/plain;
            return 200 'ok\n';
        }
    }
kind: ConfigMap
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc'
    kix.run/identity-hash: wlzmynapx327962105rsvvnmaqyw2vyn
    kix.run/package: backend
    kix.run/package-namespace: tutorial-06
  labels:
    app.kubernetes.io/instance: backend
    app.kubernetes.io/managed-by: kix
  name: backend
  namespace: tutorial-06
---
apiVersion: v1
data:
  default.conf: |
    server {
        listen 80;
        location /healthz {
            default_type text/plain;
            return 200 'ok\n';
        }
        location / {
            proxy_pass http://backend.tutorial-06.svc.cluster.local:80/;
        }
    }
kind: ConfigMap
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc,7iprxwy73s26bjhm4cyx5agmpz2q14lz'
    kix.run/identity-hash: by3dv0xzvky726i7a8b27mmqv46rgkhy
    kix.run/package: gateway
    kix.run/package-namespace: tutorial-06
  labels:
    app.kubernetes.io/instance: gateway
    app.kubernetes.io/managed-by: kix
  name: gateway
  namespace: tutorial-06
---
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    kix.run/identity-hash: sj0fv5bs2hnh9zcqdh62ph34l2wm0b1m
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
  labels:
    app.kubernetes.io/managed-by: kix
    kubernetes.io/metadata.name: kube-system
  name: kube-system
---
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    kix.run/identity-hash: '1wz2372bgznyyc56m28alsibkgfcq4dc'
    kix.run/package: _cluster
    kix.run/package-namespace: _cluster
  labels:
    app.kubernetes.io/managed-by: kix
    kubernetes.io/metadata.name: tutorial-06
  name: tutorial-06
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc,cqx7f7f2w1pa7llx2zrk7p3qb374if76'
    kix.run/identity-hash: '7iprxwy73s26bjhm4cyx5agmpz2q14lz'
    kix.run/package: backend
    kix.run/package-namespace: tutorial-06
  labels:
    app.kubernetes.io/instance: backend
    app.kubernetes.io/managed-by: kix
  name: backend
  namespace: tutorial-06
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app.kubernetes.io/instance: backend
    app.kubernetes.io/name: backend
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    kix.run/depends-on: '1wz2372bgznyyc56m28alsibkgfcq4dc,d8lsi37jfr7i49svzfc52nqgzpjb97i3'
    kix.run/identity-hash: fsvvbizzzlqmzya0ccprxxci2dfqym28
    kix.run/package: gateway
    kix.run/package-namespace: tutorial-06
  labels:
    app.kubernetes.io/instance: gateway
    app.kubernetes.io/managed-by: kix
  name: gateway
  namespace: tutorial-06
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app.kubernetes.io/instance: gateway
    app.kubernetes.io/name: gateway
  type: ClusterIP

In the gateway ConfigMap, the proxy_pass URL should contain the backend’s cluster DNS name. The package code did not hardcode that name; it came from backend.out.fqdn.

In tutorials/06-service-dep/cluster.nix, rename the backend instance to api:

tutorials/06-service-dep/cluster.nix
api = {
package = packages.echo-server;
config = {
message = "Hello from the backend!";
};
};

Then run:

Run in kix-examples/
❱ kix check 06-service-dep Show output
 TOOL  RESULT  DETAILS                                                                                                                                                               
 eval  fail    could not read the built resources and their dependencies: nix build failed: warning: not writing modified lock file of flake 'path:kix-examples': 
               • Updated input 'kixpkgs':                                                                                                                                            
                   'git+https://github.com/kix-run/kixpkgs?ref=refs/heads/main&rev=9dcf5b3e33b728ef3fc76a693e4feda2921b1913' (2026-09-10)                                            
                 → 'path:/nix/store/1m3ijw2kvyj8z7cnnjac5h4qpl21wr1b-source/docs/..?lastModified=0&narHash=sha256-UxPEEja%2BlQ7yUWkJDR9yAydETmMgbnf8eRZ8%2Bx6m4%2BY%3D' (1970-01-01) 
               error:                                                                                                                                                                
                      … while calling the 'derivationStrict' builtin                                                                                                                 
                        at <nix/derivation-internal.nix>:37:12:                                                                                                                      
                          36|                                                                                                                                                        
                          37|   strict = derivationStrict drvAttrs;                                                                                                                  
                            |            ^                                                                                                                                           
                          38|                                                                                                                                                        
                                                                                                                                                                                     
                      … while evaluating the derivation attribute 'name'                                                                                                             
                        at /nix/store/4rg99msfmkk9gppakagpgkzcixwg7yxq-source/pkgs/stdenv/generic/make-derivation.nix:624:11:                                                        
                         623|         derivationArg = removeAttrs attrs removedOrReplacedAttrNames // {                                                                              
                         624|           ${if (attrs ? name || (attrs ? pname && attrs ? version)) then "name" else null} =                                                           
                            |           ^                                                                                                                                            
                         625|             let                                                                                                                                        
                                                                                                                                                                                     
                      (stack trace truncated; use '--show-trace' to show the full, detailed trace)                                                                                   
                                                                                                                                                                                     
                      error: dependency 'backend' was not found for namespace 'tutorial-06'. Add an instance with that name or alias, or set deps.backend explicitly.
(exit code: 1)

Kix should fail because the gateway package asks for backend, but there is no same-namespace instance with that name anymore.

Change api back to backend before continuing. Later tutorials assume this example is back in its working state.

You added the first real edge to the tutorial path:

  • a cluster can import a local package;
  • an instance installs that local package just like a catalog package;
  • a package can ask for another instance by argument name;
  • Kix resolves that argument to a matching same-namespace instance;
  • out lets one package use another package’s public values without hardcoded Service names.

The next dependency tutorial puts the two services in different namespaces and uses ref to make the wiring explicit.