diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 91b72a6de0c5a9544ae438e24c0dd6127afdfcd3..f8760bbd918a797b062baa12df31da5afce65d44 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -185,6 +185,7 @@ variables:
 ## DEPLOYMENT_NAME
 ## NAMESPACE
 # Optional vars:
+## INGRESS_FILE
 ## OPT_KUBECTL_CMD
 ## MOUNT
 ## MOUNT_PARAMS # repocopy will replace current file
@@ -217,6 +218,7 @@ variables:
     - kubectl rollout restart deployment -n $NAMESPACE $DEPLOYMENT_NAME
     - kubectl rollout status deployment -n $NAMESPACE $DEPLOYMENT_NAME
     - echo "only deployment $DEPLOYMENT_NAME in namespace $NAMESPACE restarted. please restart any helper deployments (like databases) manually"
+    - if ! [ -z "$INGRESS_FILE" ]; then if [ "$PROD" = "true" ]; then kubectl apply -f "$INGRESS_FILE"; else kubectl apply -f ${INGRESS_FILE/ingress/testingress}; fi; fi;
 
 
 # prepare env scripts
@@ -321,8 +323,6 @@ prepare_scripts:
   artifacts:
     expire_in: 1 week
     paths:
-      - prod_ingress_config.yaml
-      - test_ingress_config.yaml
       - distribution_ingress_config.yaml
       - ingress_deployment.yaml
       - endpoints.yaml
@@ -334,24 +334,34 @@ prepare_scripts:
       - gitlab.yaml
       - gitlab_sa.yaml
       - gitlab_pvs.yaml
+      - gitlab_ingress.yaml
+      - gitlab_testingress.yaml
       - nfs.yaml
       - nfs_sa.yaml
       - nfs_pvs.yaml
       - synapse.yaml
       - synapse_sa.yaml
       - synapse_pvs.yaml
+      - synapse_ingress.yaml
+      - synapse_testingress.yaml
       - turn.yaml
       - turn_sa.yaml
       - turn_pvs.yaml
       - wordpress.yaml
       - wordpress_sa.yaml
       - wordpress_pvs.yaml
+      - wordpress_ingress.yaml
+      - wordpress_testingress.yaml
       - nextcloud.yaml
       - nextcloud_sa.yaml
       - nextcloud_pvs.yaml
+      - nextcloud_ingress.yaml
+      - nextcloud_testingress.yaml
       - docker-registry.yaml
       - docker-registry_pvs.yaml
       - docker-registry_sa.yaml
+      - docker-registry_ingress.yaml
+      - docker-registry_testingress.yaml
       - gitlab-runner-kubernetes.yaml
       - gitlab-runner-kubernetes_pvs.yaml
       - gitlab-runner-kubernetes_sa.yaml
@@ -361,18 +371,26 @@ prepare_scripts:
       - synapse-admin.yaml
       - synapse-admin_pvs.yaml
       - synapse-admin_sa.yaml
+      - synapse-admin_ingress.yaml
+      - synapse-admin_testingress.yaml
       - ddclient.yaml
       - ddclient_pvs.yaml
       - ddclient_sa.yaml
       - wordpress-cli-10001.yaml
       - wordpress-cli-10001_pvs.yaml
       - wordpress-cli-10001_sa.yaml
+      - wordpress-cli-10001_ingress.yaml
+      - wordpress-cli-10001_testingress.yaml
       - wordpress-cli-10002.yaml
       - wordpress-cli-10002_pvs.yaml
       - wordpress-cli-10002_sa.yaml
+      - wordpress-cli-10002_ingress.yaml
+      - wordpress-cli-10002_testingress.yaml
       - wordpress-cli-10003.yaml
       - wordpress-cli-10003_pvs.yaml
       - wordpress-cli-10003_sa.yaml
+      - wordpress-cli-10003_ingress.yaml
+      - wordpress-cli-10003_testingress.yaml
       - mautrix-telegram.yaml
       - mautrix-telegram_pvs.yaml
       - mautrix-telegram_sa.yaml
@@ -382,12 +400,18 @@ prepare_scripts:
       - my-synapse.yaml
       - my-synapse_sa.yaml
       - my-synapse_pvs.yaml
+      - my-synapse_ingress.yaml
+      - my-synapse_testingress.yaml
       - element.yaml
       - element_sa.yaml
       - element_pvs.yaml
+      - element_ingress.yaml
+      - element_testingress.yaml
       - streama.yaml
       - streama_sa.yaml
       - streama_pvs.yaml
+      - streama_ingress.yaml
+      - streama_testingress.yaml
       - gitlab-shared-runner-0.yaml
       - gitlab-shared-runner-0_sa.yaml
       - gitlab-shared-runner-0_pvs.yaml
@@ -397,9 +421,13 @@ prepare_scripts:
       - vaultwarden.yaml
       - vaultwarden_sa.yaml
       - vaultwarden_pvs.yaml
+      - vaultwarden_ingress.yaml
+      - vaultwarden_testingress.yaml
       - joos-io-homepage.yaml
       - joos-io-homepage_sa.yaml
       - joos-io-homepage_pvs.yaml
+      - joos-io-homepage_ingress.yaml
+      - joos-io-homepage_testingress.yaml
       - gitlab-runner-docker.yaml
       - gitlab-runner-docker_pvs.yaml
       - gitlab-runner-docker_sa.yaml
@@ -409,6 +437,8 @@ prepare_scripts:
       - sonarqube.yaml
       - sonarqube_pvs.yaml
       - sonarqube_sa.yaml
+      - sonarqube_ingress.yaml
+      - sonarqube_testingress.yaml
   script:
     - >
       python3 deploy/generate_scripts/generate_deployment_from_middle.py \
@@ -534,6 +564,7 @@ deploy_gitlab:
     DEPLOYMENT_FILE: gitlab.yaml
     PVS_FILE: gitlab_pvs.yaml 
     SA_FILE: gitlab_sa.yaml
+    INGRESS_FILE: gitlab_ingress.yaml
     DEPLOYMENT_NAME: gitlab
     NAMESPACE: gitlab
     MOUNT: "true"
@@ -552,6 +583,7 @@ deploy_synapse:
     DEPLOYMENT_FILE: synapse.yaml
     PVS_FILE: synapse_pvs.yaml 
     SA_FILE: synapse_sa.yaml
+    INGRESS_FILE: synapse_ingress.yaml
     DEPLOYMENT_NAME: synapse
     NAMESPACE: synapse
     MOUNT: "true"
@@ -585,6 +617,7 @@ deploy_element:
     DEPLOYMENT_FILE: element.yaml
     PVS_FILE: element_pvs.yaml 
     SA_FILE: element_sa.yaml
+    INGRESS_FILE: element_ingress.yaml
     DEPLOYMENT_NAME: element
     NAMESPACE: element
 
@@ -603,6 +636,7 @@ deploy_wordpress:
     DEPLOYMENT_FILE: wordpress.yaml
     PVS_FILE: wordpress_pvs.yaml 
     SA_FILE: wordpress_sa.yaml
+    INGRESS_FILE: wordpress_ingress.yaml
     DEPLOYMENT_NAME: wordpress-server
     NAMESPACE: wordpress
     MOUNT: "true"
@@ -615,6 +649,7 @@ deploy_nextcloud:
     DEPLOYMENT_FILE: nextcloud.yaml
     PVS_FILE: nextcloud_pvs.yaml 
     SA_FILE: nextcloud_sa.yaml
+    INGRESS_FILE: nextcloud_ingress.yaml
     DEPLOYMENT_NAME: nextcloud-server
     NAMESPACE: nextcloud
     MOUNT: "true"
@@ -626,6 +661,7 @@ deploy_docker-registry:
     DEPLOYMENT_FILE: docker-registry.yaml
     PVS_FILE: docker-registry_pvs.yaml
     SA_FILE: docker-registry_sa.yaml
+    INGRESS_FILE: docker-registry_ingress.yaml
     DEPLOYMENT_NAME: docker-registry-server
     NAMESPACE: docker-registry
     MOUNT: "true"
@@ -692,6 +728,7 @@ deploy_synapse_admin:
     DEPLOYMENT_FILE: synapse-admin.yaml
     PVS_FILE: synapse-admin_pvs.yaml
     SA_FILE: synapse-admin_sa.yaml
+    INGRESS_FILE: synapse-admin_ingress.yaml
     DEPLOYMENT_NAME: synapse-admin
     NAMESPACE: synapse-admin
 
@@ -710,6 +747,7 @@ deploy_wordpress-cli-10001:
     DEPLOYMENT_FILE: wordpress-cli-10001.yaml
     PVS_FILE: wordpress-cli-10001_pvs.yaml
     SA_FILE: wordpress-cli-10001_sa.yaml
+    INGRESS_FILE: wordpress-cli-10001_ingress.yaml
     DEPLOYMENT_NAME: wordpress-server
     NAMESPACE: wordpress-cli-10001
     MOUNT: "true"
@@ -721,6 +759,7 @@ deploy_wordpress-cli-10002:
     DEPLOYMENT_FILE: wordpress-cli-10002.yaml
     PVS_FILE: wordpress-cli-10002_pvs.yaml
     SA_FILE: wordpress-cli-10002_sa.yaml
+    INGRESS_FILE: wordpress-cli-10002_ingress.yaml
     DEPLOYMENT_NAME: wordpress-server
     NAMESPACE: wordpress-cli-10002
     MOUNT: "true"
@@ -735,6 +774,7 @@ deploy_my-synapse:
     DEPLOYMENT_FILE: my-synapse.yaml
     PVS_FILE: my-synapse_pvs.yaml 
     SA_FILE: my-synapse_sa.yaml
+    INGRESS_FILE: my-synapse_ingress.yaml
     DEPLOYMENT_NAME: synapse
     NAMESPACE: my-synapse
     MOUNT: "true"
@@ -747,6 +787,7 @@ deploy_streama:
     DEPLOYMENT_FILE: streama.yaml
     PVS_FILE: streama_pvs.yaml 
     SA_FILE: streama_sa.yaml
+    INGRESS_FILE: streama_ingress.yaml
     DEPLOYMENT_NAME: streama-server
     NAMESPACE: streama
     MOUNT: "true"
@@ -769,6 +810,7 @@ deploy_vaultwarden:
     DEPLOYMENT_FILE: vaultwarden.yaml
     PVS_FILE: vaultwarden_pvs.yaml 
     SA_FILE: vaultwarden_sa.yaml
+    INGRESS_FILE: vaultwarden_ingress.yaml
     DEPLOYMENT_NAME: vaultwarden
     NAMESPACE: vaultwarden
     MOUNT: "true"
@@ -780,6 +822,7 @@ deploy_wordpress-cli-10003:
     DEPLOYMENT_FILE: wordpress-cli-10003.yaml
     PVS_FILE: wordpress-cli-10003_pvs.yaml
     SA_FILE: wordpress-cli-10003_sa.yaml
+    INGRESS_FILE: wordpress-cli-10003_ingress.yaml
     DEPLOYMENT_NAME: wordpress-server
     NAMESPACE: wordpress-cli-10003
     MOUNT: "true"
@@ -791,6 +834,7 @@ deploy_sonarqube:
     DEPLOYMENT_FILE: sonarqube.yaml
     PVS_FILE: sonarqube_pvs.yaml 
     SA_FILE: sonarqube_sa.yaml
+    INGRESS_FILE: sonarqube_ingress.yaml
     DEPLOYMENT_NAME: sonarqube
     NAMESPACE: sonarqube
     MOUNT: "true"
@@ -804,6 +848,7 @@ deploy_joos.io_homepage:
     DEPLOYMENT_FILE: joos-io-homepage.yaml
     PVS_FILE: joos-io-homepage_pvs.yaml
     SA_FILE: joos-io-homepage_sa.yaml
+    INGRESS_FILE: joos-io-homepage_ingress.yaml
     DEPLOYMENT_NAME: nginx
     NAMESPACE: joos-io-homepage
     MOUNT: "true"
@@ -839,17 +884,6 @@ configure_ingress_entries:
     - kubectl delete -f endpoints.yaml --ignore-not-found=true
     - kubectl apply -f endpoints.yaml
     - kubectl apply -f distribution_ingress_config.yaml
-    - >
-      if [ "$PROD" = "true" ]; then
-        echo "applying prod ingress config"
-        $CHANGE_KUBECTL_CONTEXT_PROD_CMD
-        kubectl apply -f prod_ingress_config.yaml
-      else
-        $CHANGE_KUBECTL_CONTEXT_TEST_CMD
-        echo "applying test ingress config"
-        kubectl apply -f test_ingress_config.yaml
-        $CHANGE_KUBECTL_CONTEXT_PROD_CMD
-      fi
 
     # - $KUBECTL_USE_CONTEXT_TEST_CMD
     # - kubectl apply -f test_ingress_config.yaml
diff --git a/deploy/generate_scripts/generate_deployment_from_middle.py b/deploy/generate_scripts/generate_deployment_from_middle.py
index c10a038cc82440a4995116ed67c15dbf431c3121..c3644e90321c1871a34a2c76f4318e57d7ed9d3a 100644
--- a/deploy/generate_scripts/generate_deployment_from_middle.py
+++ b/deploy/generate_scripts/generate_deployment_from_middle.py
@@ -18,7 +18,6 @@ TESTCLUSTER_DEVICE_IP = None
 
 BUILD_DIR = 'deploy'
 EXTERNAL_PATH = f'{BUILD_DIR}/external.json'
-SIDELOADED_PATH = f'{BUILD_DIR}/sideloaded.json'
 INGRESS_DIR = 'ingress'
 INGRESS_TEMPLATE_PATH = f'{INGRESS_DIR}/nginx-ingress-v1.1.0.yaml'
 INGRESS_CONFIG_FILENAME = f'nginx.tmpl'
@@ -126,21 +125,27 @@ def make_deployment_scripts(middle_deployment_scripts: list, middle_deployments:
   nginx_bridges = []
   if middle_deployment_scripts is not None:
     for middle_deployment_script in middle_deployment_scripts:
-      project_name, deployment_file_content, persistent_volumes_file_content, service_account_file_content, current_nginx_bridges = make_deployment_script_from_script(middle_deployment_script)
-      nginx_bridges.extend(current_nginx_bridges)
+      project_name, namespace, deployment_file_content, persistent_volumes_file_content, service_account_file_content, current_nginx_bridges = make_deployment_script_from_script(middle_deployment_script)
+      if current_nginx_bridges:
+        nginx_bridges.append((project_name, namespace, current_nginx_bridges))
 
       dump_files(project_name, deployment_file_content, persistent_volumes_file_content, service_account_file_content)
 
   for middle_deployment in middle_deployments:
-    project_name, deployment_file_content, persistent_volumes_file_content, service_account_file_content, current_nginx_bridges = make_deployment_script_from_object(middle_deployment)
-    nginx_bridges.extend(current_nginx_bridges)
+    project_name, namespace, deployment_file_content, persistent_volumes_file_content, service_account_file_content, current_nginx_bridges = make_deployment_script_from_object(middle_deployment)
+    if current_nginx_bridges:
+      nginx_bridges.append((project_name, namespace, current_nginx_bridges))
 
     dump_files(project_name, deployment_file_content, persistent_volumes_file_content, service_account_file_content)
 
-  prod_ingress, test_ingress, distribution_ingress, ingress_deployment_template, endpoints, prod_issuer, staging_issuer = make_ingresses(nginx_bridges)
+  prod_ingresses, test_ingresses, distribution_ingress, ingress_deployment_template, endpoints, prod_issuer, staging_issuer = make_ingresses(nginx_bridges)
+
+  for project_name, prod_ingress in prod_ingresses:
+    dump_file([prod_ingress], project_name + "_ingress")
+
+  for project_name, test_ingress in test_ingresses:
+    dump_file([test_ingress], project_name + "_testingress")
 
-  dump_file([prod_ingress], PROD_INGRESS_DEPLOY_FILENAME)
-  dump_file([test_ingress], TEST_INGRESS_DEPLOY_FILENAME)
   dump_file([distribution_ingress], DISTRIBUTION_INGRESS_DEPLOY_FILENAME)
   dump_file(endpoints, ENDPOINTS_FILENAME)
   dump_file([prod_issuer], PROD_ISSUER_FILENAME)
@@ -177,18 +182,18 @@ def make_deployment_script(middle_deployment: dict):
   service_account_file_content.append(ns)
 
   for deployment in deployments:
-    deployment_name, bridge_service, http_service, env_config_map, cluster_ip_service, lb_services, node_port_service, kubernetes_volumes, config_map_volumes, service_account, role, role_binding, uris, max_upload_size = make_deployment_components(ns_name, deployment)
+    deployment_name, _, http_service, env_config_map, cluster_ip_service, lb_services, node_port_service, kubernetes_volumes, config_map_volumes, service_account, role, role_binding, uris, max_upload_size = make_deployment_components(ns_name, deployment)
     kubernetes_deployment = make_deployment(deployment_name, ns_name, deployment, kubernetes_volumes, config_map_volumes, service_account, env_config_map)
 
     persistent_volumes = [pv for pv, pvc, volume_name in kubernetes_volumes]
     persistent_volume_claims = [pvc for pv, pvc, volume_name in kubernetes_volumes]
     config_map_volumes = [volume for volume, volume_name in config_map_volumes]
 
-    deployment_file_content.extend(make_deployment_file_content(bridge_service, http_service, env_config_map, cluster_ip_service, lb_services, node_port_service, config_map_volumes, kubernetes_deployment))
+    deployment_file_content.extend(make_deployment_file_content(http_service, env_config_map, cluster_ip_service, lb_services, node_port_service, config_map_volumes, kubernetes_deployment))
     persistent_volumes_file_content.extend(make_persistent_volumes_file_content(persistent_volumes, persistent_volume_claims))
     service_account_file_content.extend(make_service_account_file_content(service_account, role, role_binding))
-    if bridge_service or http_service or uris != []:
-      nginx_bridges.append((bridge_service, http_service, uris, max_upload_size))
+    if http_service or uris != []:
+      nginx_bridges.append((http_service, uris, max_upload_size))
 
     # image_pull_secrets ugly workaround
     image_pull_secret_names = deployment.get(IMAGE_PULL_SECRETS_FIELD, None)
@@ -209,7 +214,7 @@ def make_deployment_script(middle_deployment: dict):
 
     deployment_file_content.extend(image_pull_secrets)
 
-  return project_name, deployment_file_content, persistent_volumes_file_content, service_account_file_content, nginx_bridges
+  return project_name, ns, deployment_file_content, persistent_volumes_file_content, service_account_file_content, nginx_bridges
 
 def make_deployment_components(ns_name, deployment: dict):
   deployment_name = deployment[NAME_FIELD]
@@ -890,10 +895,10 @@ def make_node_port_service(deployment_name: str, ns_name: str, ports):
 def make_env_config_map(specs: dict, deployment_name: str, ns_name: str):
   return make_config_map('env', specs, ns_name, deployment_name)
 
-def make_deployment_file_content(bridge_service: dict, http_service: dict, env: dict, cluster_ip_service: dict, 
+def make_deployment_file_content(http_service: dict, env: dict, cluster_ip_service: dict, 
                                   lb_services: list, node_port_service: list, config_map_volumes: list, deployment: dict):
 
-  return make_file_content(bridge_service, http_service, env, cluster_ip_service, lb_services, node_port_service, config_map_volumes, deployment)
+  return make_file_content(http_service, env, cluster_ip_service, lb_services, node_port_service, config_map_volumes, deployment)
 
 
 def make_persistent_volumes_file_content(pvs: list, pvcs: list):
@@ -1124,7 +1129,7 @@ def make_ingress_rule(uri: str, service_name: str, service_port: int):
   return rule
 
 
-def make_ingress(name: str, hosts: list, rules: list, certificate_name: str, secretName: str = SECRETNAME_DEFAULT, redirect_https: bool=False):
+def make_ingress(name: str, hosts: list, rules: list, certificate_name: str, secretName: str = SECRETNAME_DEFAULT, redirect_https: bool=False, namespace=KUBERNETES_NAMESPACE_DEFAULT):
   annotations = {
     "cert-manager.io/cluster-issuer": certificate_name,
     "kubernetes.io/ingress.class": "nginx",
@@ -1147,7 +1152,7 @@ def make_ingress(name: str, hosts: list, rules: list, certificate_name: str, sec
     KUBERNETES_API_VERSION_KEY: KUBERNETES_API_VERSION_INGRESS_CONFIG_DEFAULT_VALUE,
     KUBERNETES_KIND_KEY: KUBERNETES_KIND_VALUE_INGRESS,
     KUBERNETES_METADATA_KEY: {
-      KUBERNETES_NAMESPACE_KEY: KUBERNETES_NAMESPACE_DEFAULT,
+      KUBERNETES_NAMESPACE_KEY: namespace,
       KUBERNETES_NAME_KEY: name,
       KUBERNETES_ANNOTATIONS_KEY: annotations,
     },
@@ -1187,41 +1192,34 @@ def make_ingress_entry_rules(uri: str, endpoint_name: str, service_port: int, cr
   return (prod_rule, uri), (test_rule, test_uri)
 
 
-def make_prod_test_ingress(ingress_bridges: list, sideloaded: dict):
-  prod_hosts = []
-  prod_rules = []
-  test_hosts = []
-  test_rules = []
+def make_prod_test_ingress(ingress_bridges: list):
+  prod_configs = []
+  test_configs = []
   upload_size_configs = []
-  for bridge_service, http_service, uris, max_upload_size in ingress_bridges:
-    bridge_name = bridge_service[KUBERNETES_METADATA_KEY][KUBERNETES_NAME_KEY]
-    service_port = http_service[KUBERNETES_SPEC_KEY][KUBERNETES_PORTS_KEY][0][KUBERNETES_PORT_KEY]
-
-    for uri in uris:
-      (prod_rule, prod_uri), (test_rule, test_uri) = make_ingress_entry_rules(uri, bridge_name, service_port)
-
-      prod_hosts.append(prod_uri)
-      prod_rules.append(prod_rule)
-
-      test_hosts.append(test_uri)
-      test_rules.append(test_rule)
+  for project_name, namespace, ingress_config in ingress_bridges:
+    ns_name = namespace[KUBERNETES_METADATA_KEY][KUBERNETES_NAME_KEY]
+    prod_rules = []
+    prod_hosts = []
+    test_hosts = []
+    test_rules = []
+    for http_service, uris, max_upload_size in ingress_config:
+      service_name = http_service[KUBERNETES_METADATA_KEY][KUBERNETES_NAME_KEY]
+      service_port = http_service[KUBERNETES_SPEC_KEY][KUBERNETES_PORTS_KEY][0][KUBERNETES_PORT_KEY]    
 
-    upload_size_configs.append((bridge_name, max_upload_size))
+      for uri in uris:
+        (prod_rule, prod_uri), (test_rule, test_uri) = make_ingress_entry_rules(uri, service_name, service_port)
+        prod_hosts.append(prod_uri)
+        prod_rules.append(prod_rule)
 
-  for uri, sideload_config in sideloaded.items():
-    bridge_name = sideload_config[EXTERNALS_ENDPOINT_FIELD]
-    max_upload_size = sideload_config[MAX_UPLOAD_SIZE_FIELD]
-    (prod_rule, uri), (test_rule, test_uri) = make_ingress_entry_rules(uri, bridge_name, service_port)
+        test_hosts.append(test_uri)
+        test_rules.append(test_rule)
 
-    upload_size_configs.append((bridge_name, max_upload_size))
+    prod_configs.append((project_name, ns_name, prod_hosts, prod_rules))
+    test_configs.append((project_name, ns_name, test_hosts, test_rules))
 
-    prod_hosts.append(uri)
-    prod_rules.append(prod_rule)
+    upload_size_configs.append((service_name, max_upload_size))
 
-    test_hosts.append(test_uri)
-    test_rules.append(test_rule)
-
-  return (prod_hosts, prod_rules), (test_hosts, test_rules), upload_size_configs
+  return prod_configs, test_configs, upload_size_configs
 
 def make_distribution_ingress(externals: dict, external_endpoints: dict, test_hosts: list, test_rules: list, test_service: dict, test_max_upload_size: str):
   external_hosts = []
@@ -1266,10 +1264,8 @@ def make_distribution_ingress(externals: dict, external_endpoints: dict, test_ho
 
 
 def make_ingresses(ingress_bridges: list):
-  sideloaded = {}
-  with open(SIDELOADED_PATH, 'r', encoding='utf-8') as f:
-    sideloaded = json.load(f)
-
+  prod_ingresses = []
+  test_ingresses = []
   externals = {}
   with open(EXTERNAL_PATH, 'r', encoding='utf-8') as f:
     externals = json.load(f)
@@ -1285,14 +1281,27 @@ def make_ingresses(ingress_bridges: list):
     external_endpoint, external_service, external_max_upload_size = external_endpoint_config
     endpoints.extend([external_endpoint, external_service])
 
-  (prod_hosts, prod_rules), (test_hosts, test_rules), prod_test_upload_size_configs = make_prod_test_ingress(ingress_bridges, sideloaded)
+  prod_configs, test_configs, prod_test_upload_size_configs = make_prod_test_ingress(ingress_bridges)
+  test_hosts = []
+  test_rules = []
+  for _, _, hosts, rules in test_configs:
+    test_hosts.extend(hosts)
+    test_rules.extend(rules)
+  
   distribution_hosts, distribution_rules, distribution_upload_size_configs = make_distribution_ingress(externals[EXTERNALS_REDIRECTS_FIELD], externals[EXTERNALS_ENDPOINTS_FIELD],  test_hosts, test_rules, test_service, test_max_upload_size)
   
   upload_size_configs = prod_test_upload_size_configs
   upload_size_configs.extend(distribution_upload_size_configs)
 
-  prod_ingress = make_ingress(DEFAULT_INGRESS_NAME, prod_hosts, prod_rules, INGRESS_CERTIFICATE_PROD, INGRESS_SECRETNAME_PROD, redirect_https=False)
-  test_ingress = make_ingress(TEST_INGRESS_NAME, test_hosts, test_rules, INGRESS_CERTIFICATE_STAGING, INGRESS_SECRETNAME_TEST, redirect_https=False) # when here prod, https should work / test, distribution ingress separate
+  for project_name, project_namespace, prod_hosts, prod_rules in prod_configs:
+    prod_ingress = make_ingress(project_name, prod_hosts, prod_rules, INGRESS_CERTIFICATE_PROD, INGRESS_SECRETNAME_PROD, redirect_https=False, namespace=project_namespace)
+    prod_ingresses.append((project_name, prod_ingress))
+
+  for project_name, project_namespace, test_hosts, test_rules in test_configs:
+    test_ingress = make_ingress(project_name, test_hosts, test_rules, INGRESS_CERTIFICATE_STAGING, INGRESS_SECRETNAME_TEST, redirect_https=False, namespace=project_namespace)
+    test_ingresses.append((project_name, test_ingress))
+
+  # test_ingress = make_ingress(TEST_INGRESS_NAME, test_hosts, test_rules, INGRESS_CERTIFICATE_STAGING, INGRESS_SECRETNAME_TEST, redirect_https=False) # when here prod, https should work / test, distribution ingress separate
   distribution_ingress = make_ingress(DISTRIBUTION_INGRESS_NAME, distribution_hosts, distribution_rules, INGRESS_CERTIFICATE_PROD, INGRESS_SECRETNAME_DISTRIBUTION, redirect_https=True)
 
   upload_size_config = make_upload_size_config(upload_size_configs)
@@ -1336,7 +1345,7 @@ def make_ingresses(ingress_bridges: list):
 
   ingress_deployment_content.append(nginx_config_config_map)
 
-  return prod_ingress, test_ingress, distribution_ingress, ingress_deployment_content, endpoints, prod_issuer, staging_issuer
+  return prod_ingresses, test_ingresses, distribution_ingress, ingress_deployment_content, endpoints, prod_issuer, staging_issuer
 
 
 def make_testenv_uri(original_uri: str):
diff --git a/deploy/sideloaded.json b/deploy/sideloaded.json
deleted file mode 100644
index 544b7b4ddde01a730b456b39d168580fbc83b99e..0000000000000000000000000000000000000000
--- a/deploy/sideloaded.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    
-}
\ No newline at end of file