diff --git a/apps/canvas/src/lib/config.ts b/apps/canvas/src/lib/config.ts
new file mode 100644
index 0000000..f2a0784
--- /dev/null
+++ b/apps/canvas/src/lib/config.ts
@@ -0,0 +1,390 @@
+import { AppNode, Env, GatewayHttpsNode, Message, MessageType, NodeType, ServiceType, VolumeType } from "./state";
+
+export type AuthDisabled = {
+    enabled: false;
+};
+
+export type AuthEnabled = {
+    enabled: true;
+    groups: string[];
+    noAuthPathPatterns: string[];
+};
+
+export type Auth = AuthDisabled | AuthEnabled;
+
+export type Ingress = {
+    network: string;
+    subdomain: string;
+    port: { name: string; } | { value: string; };
+    auth: Auth;
+};
+
+export type Domain = {
+    network: string;
+    subdomain: string;
+};
+
+export type PortValue = {
+    name: string;
+} | {
+    value: number;
+};
+
+export type PortDomain = Domain & {
+    port: PortValue;
+}
+
+export type Service = {
+    type: ServiceType;
+    name: string;
+    source: {
+        repository: string;
+        branch: string;
+        rootDir: string;
+    };
+    ports?: {
+        name: string;
+        value: number;
+        protocol: "TCP" | "UDP";
+    }[];
+    env?: {
+        name: string;
+        alias?: string;
+    }[]
+    ingress?: Ingress;
+    expose?: PortDomain[];
+    volume?: string[];
+};
+
+export type Volume = {
+    name: string;
+    accessMode: VolumeType;
+    size: string;
+};
+
+export type PostgreSQL = {
+    name: string;
+    size: string;
+    expose?: Domain[];
+};
+
+export type MongoDB = {
+    name: string;
+    size: string;
+    expose?: Domain[];
+};
+
+export type Config = {
+    service?: Service[];
+    volume?: Volume[];
+    postgresql?: PostgreSQL[];
+    mongodb?: MongoDB[];
+};
+
+export function generateDodoConfig(nodes: AppNode[], env: Env): Config | null {
+    try {
+        const networkMap = new Map(env.networks.map((n) => [n.domain, n.name]));
+        const ingressNodes = nodes.filter((n) => n.type === "gateway-https").filter((n) => n.data.https !== undefined);
+        const tcpNodes = nodes.filter((n) => n.type === "gateway-tcp").filter((n) => n.data.exposed !== undefined);
+        const findExpose = (n: AppNode): PortDomain[] => {
+            return n.data.ports.map((p) => [n.id, p.id, p.name]).flatMap((sp) => {
+                return tcpNodes.flatMap((i) => (i.data.exposed || []).filter((t) => t.serviceId === sp[0] && t.portId === sp[1]).map(() => ({
+                    network: networkMap.get(i.data.network!)!,
+                    subdomain: i.data.subdomain!,
+                    port: { name: sp[2] },
+                })));
+            });
+        };
+        return {
+            service: nodes.filter((n) => n.type === "app").map((n): Service => {
+                return {
+                    type: n.data.type,
+                    name: n.data.label,
+                    source: {
+                        repository: nodes.filter((i) => i.type === "github").find((i) => i.id === n.data.repository.id)!.data.address,
+                        branch: n.data.repository.branch,
+                        rootDir: n.data.repository.rootDir,
+                    },
+                    ports: (n.data.ports || []).map((p) => ({
+                        name: p.name,
+                        value: p.value,
+                        protocol: "TCP", // TODO(gio)
+                    })),
+                    env: (n.data.envVars || []).filter((e) => "name" in e).map((e) => ({
+                        name: e.name,
+                        alias: "alias" in e ? e.alias : undefined,
+                    })),
+                    ingress: ((i: GatewayHttpsNode | undefined) => {
+                        if (i === undefined) {
+                            return undefined;
+                        }
+                        return {
+                            network: networkMap.get(i.data.network!)!,
+                            subdomain: i.data.subdomain!,
+                            port: {
+                                name: n.data.ports.find((p) => p.id === i.data.https!.portId)!.name,
+                            },
+                            auth: { enabled: false },
+                        };
+                    })(ingressNodes.find((i) => i.data.https!.serviceId === n.id)),
+                    expose: findExpose(n),
+                };
+            }),
+            volume: nodes.filter((n) => n.type === "volume").map((n): Volume => ({
+                name: n.data.label,
+                accessMode: n.data.type,
+                size: n.data.size,
+            })),
+            postgresql: nodes.filter((n) => n.type === "postgresql").map((n): PostgreSQL => ({
+                name: n.data.label,
+                size: "1Gi", // TODO(gio)
+                expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
+            })),
+            mongodb: nodes.filter((n) => n.type === "mongodb").map((n): MongoDB => ({
+                name: n.data.label,
+                size: "1Gi", // TODO(gio)
+                expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
+            })),
+        };
+    } catch (e) {
+        console.log(e);
+        return null;
+    }
+}
+
+export interface Validator {
+    (nodes: AppNode[]): Message[];
+}
+
+function CombineValidators(...v: Validator[]): Validator {
+    return (n) => v.flatMap((v) => v(n));
+}
+
+function MessageTypeToNumber(t: MessageType) {
+    switch (t) {
+        case "FATAL": return 0;
+        case "WARNING": return 1;
+        case "INFO": return 2;
+    }
+}
+
+function NodeTypeToNumber(t?: NodeType) {
+    switch (t) {
+        case "github": return 0;
+        case "app": return 1;
+        case "volume": return 2;
+        case "postgresql": return 3;
+        case "mongodb": return 4;
+        case "gateway-https": return 5;
+        case undefined: return 100;
+    }
+}
+
+function SortingValidator(v: Validator): Validator {
+    return (n) => {
+        const nt = new Map(n.map((n) => [n.id, NodeTypeToNumber(n.type)]))
+        return v(n).sort((a, b) => {
+            const at = MessageTypeToNumber(a.type);
+            const bt = MessageTypeToNumber(b.type);
+            if (a.nodeId === undefined && b.nodeId === undefined) {
+                if (at !== bt) {
+                    return at - bt;
+                }
+                return a.id.localeCompare(b.id);
+            }
+            if (a.nodeId === undefined) {
+                return -1;
+            }
+            if (b.nodeId === undefined) {
+                return 1;
+            }
+            if (a.nodeId === b.nodeId) {
+                if (at !== bt) {
+                    return at - bt;
+                }
+                return a.id.localeCompare(b.id);
+            }
+            const ant = nt.get(a.id)!;
+            const bnt = nt.get(b.id)!;
+            if (ant !== bnt) {
+                return ant - bnt;
+            }
+            return a.id.localeCompare(b.id);
+        });
+    };
+}
+
+export function CreateValidators(): Validator {
+    return SortingValidator(
+        CombineValidators(
+            EmptyValidator, 
+            GitRepositoryValidator,
+            ServiceValidator,
+            GatewayHTTPSValidator,
+            GatewayTCPValidator,
+        )
+    );
+}
+
+function EmptyValidator(nodes: AppNode[]): Message[] {
+    if (nodes.length > 0) {
+        return [];
+    }
+    return [{   
+        id: "no-nodes",
+        type: "FATAL",
+        message: "Start by importing application source code",
+        onHighlight: (store) => store.setHighlightCategory("repository", true),
+        onLooseHighlight: (store) => store.setHighlightCategory("repository", false),
+    }];
+}
+
+function GitRepositoryValidator(nodes: AppNode[]): Message[] {
+    const git = nodes.filter((n) => n.type === "github");
+    const noAddress: Message[] = git.filter((n) => n.data == null || n.data.address == null || n.data.address === "").map((n) => ({
+        id: `${n.id}-no-address`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Configure repository address",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    } satisfies Message));
+    const noApp = git.filter((n) => !nodes.some((i) => i.type === "app" && i.data?.repository?.id === n.id)).map((n) => ({
+        id: `${n.id}-no-app`,
+        type: "WARNING",
+        nodeId: n.id,
+        message: "Connect to service",
+        onHighlight: (store) => store.setHighlightCategory("Services", true),
+        onLooseHighlight: (store) => store.setHighlightCategory("Services", false),
+} satisfies Message));
+    return noAddress.concat(noApp);
+}
+
+function ServiceValidator(nodes: AppNode[]): Message[] {
+    const apps = nodes.filter((n) => n.type === "app");
+    const noName = apps.filter((n) => n.data == null || n.data.label == null || n.data.label === "").map((n): Message => ({
+        id: `${n.id}-no-name`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Name the service",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+        onClick: (store) => {
+            store.updateNode(n.id, { selected: true });
+            store.updateNodeData<"app">(n.id, { 
+                activeField: "name" ,
+            });
+        },
+    }));
+    const noSource = apps.filter((n) => n.data == null || n.data.repository == null || n.data.repository.id === "").map((n): Message => ({
+        id: `${n.id}-no-repo`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Connect to source repository",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const noRuntime = apps.filter((n) => n.data == null || n.data.type == null).map((n): Message => ({
+        id: `${n.id}-no-runtime`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Choose runtime",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+        onClick: (store) => {
+            store.updateNode(n.id, { selected: true });
+            store.updateNodeData<"app">(n.id, { 
+                activeField: "type" ,
+            });
+        },
+    }));
+    const noPorts = apps.filter((n) => n.data == null || n.data.ports == null || n.data.ports.length === 0).map((n): Message => ({
+        id: `${n.id}-no-ports`,
+        type: "INFO",
+        nodeId: n.id,
+        message: "Expose ports",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const noIngress = apps.flatMap((n): Message[] => {
+        if (n.data == null) {
+            return [];
+        }
+        return (n.data.ports || []).filter((p) => !nodes.filter((i) => i.type === "gateway-https").some((i) => {
+            if (i.data && i.data.https && i.data.https.serviceId === n.id && i.data.https.portId === p.id) {
+                return true;
+            }
+            return false;
+        })).map((p): Message => ({
+            id: `${n.id}-${p.id}-no-ingress`,
+            type: "WARNING",
+            nodeId: n.id,
+            message: `Connect to ingress: ${p.name} - ${p.value}`,
+            onHighlight: (store) => {
+                store.updateNode(n.id, { selected: true });
+                store.setHighlightCategory("gateways", true);
+            },
+            onLooseHighlight: (store) => {
+                store.updateNode(n.id, { selected: false });
+                store.setHighlightCategory("gateways", false);    
+            },
+        }));
+    });
+    const multipleIngress = apps.filter((n) => n.data != null && n.data.ports != null).flatMap((n) => n.data.ports.map((p): Message | undefined => {
+        const ing = nodes.filter((i) => i.type === "gateway-https").filter((i) => i.data && i.data.https && i.data.https.serviceId === n.id && i.data.https.portId === p.id);
+        if (ing.length < 2) {
+            return undefined;
+        }
+        return {
+            id: `${n.id}-${p.id}-multiple-ingress`,
+            type: "FATAL",
+            nodeId: n.id,
+            message: `Can not expose same port using multiple ingresses: ${p.name} - ${p.value}`,
+            onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+            onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),        
+        };
+    })).filter((m) => m !== undefined);
+    return noName.concat(noSource).concat(noRuntime).concat(noPorts).concat(noIngress).concat(multipleIngress);
+}
+
+function GatewayHTTPSValidator(nodes: AppNode[]): Message[] {
+    const ing = nodes.filter((n) => n.type === "gateway-https");
+    const noNetwork: Message[] = ing.filter((n) => n.data == null || n.data.network == null || n.data.network == "" || n.data.subdomain == null || n.data.subdomain == "").map((n): Message => ({
+        id: `${n.id}-no-network`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Network and subdomain must be defined",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const notConnected: Message[] = ing.filter((n) => n.data == null || n.data.https == null || n.data.https.serviceId == null || n.data.https.serviceId == "" || n.data.https.portId == null || n.data.https.portId == "").map((n) => ({
+        id: `${n.id}-not-connected`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Connect to a service port",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    return noNetwork.concat(notConnected);
+}
+
+function GatewayTCPValidator(nodes: AppNode[]): Message[] {
+    const ing = nodes.filter((n) => n.type === "gateway-tcp");
+    const noNetwork: Message[] = ing.filter((n) => n.data == null || n.data.network == null || n.data.network == "" || n.data.subdomain == null || n.data.subdomain == "").map((n): Message => ({
+        id: `${n.id}-no-network`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Network and subdomain must be defined",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const notConnected: Message[] = ing.filter((n) => n.data == null || n.data.exposed == null || n.data.exposed.length === 0).map((n) => ({
+        id: `${n.id}-not-connected`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Connect to a service port",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    return noNetwork.concat(notConnected);
+}
\ No newline at end of file
