diff --git a/services/simcore/.gitignore b/services/simcore/.gitignore
index a6cefdd5..82b18f93 100644
--- a/services/simcore/.gitignore
+++ b/services/simcore/.gitignore
@@ -1,3 +1,4 @@
.env
docker-compose.deploy.yml
+docker-compose.yml
dask-sidecar/**
diff --git a/services/simcore/Makefile b/services/simcore/Makefile
index 5d10e67b..57713848 100644
--- a/services/simcore/Makefile
+++ b/services/simcore/Makefile
@@ -36,6 +36,11 @@ compose-aws: .env ${TEMP_COMPOSE}-aws ## Create docker-compose.deploy for AWS
.PHONY: compose-master
compose-master: .env ${TEMP_COMPOSE}-master ## Create docker-compose.deploy for Master
+.PHONY: docker-compose.yml
+docker-compose.yml: .venv .env
+ @$(call jinja, docker-compose.yml.j2, .env, docker-compose.yml.unlinted) && \
+ $(_yq) docker-compose.yml.unlinted > docker-compose.yml; \
+ rm docker-compose.yml.unlinted >/dev/null 2>&1;
.PHONY: ${TEMP_COMPOSE}-local
${TEMP_COMPOSE}-local: docker-compose.yml docker-compose.deploy.local.yml
diff --git a/services/simcore/configs/fallback-service-nginx/api/503.json b/services/simcore/configs/fallback-service-nginx/api/503.json
new file mode 100644
index 00000000..aa2fbb2c
--- /dev/null
+++ b/services/simcore/configs/fallback-service-nginx/api/503.json
@@ -0,0 +1,3 @@
+{
+ "errors": ["Oops! Something went wrong. Please try again."]
+}
diff --git a/services/simcore/configs/fallback-service-nginx/api/default.conf b/services/simcore/configs/fallback-service-nginx/api/default.conf
new file mode 100644
index 00000000..428fd4f0
--- /dev/null
+++ b/services/simcore/configs/fallback-service-nginx/api/default.conf
@@ -0,0 +1,19 @@
+server {
+ listen 80;
+ listen [::]:80;
+ server_name localhost;
+
+ error_page 503 /503.json;
+
+ location / {
+ return 503;
+ }
+
+ location = /503.json {
+ default_type application/json;
+
+ add_header Retry-After "10" always; # https://serverfault.com/a/647552
+
+ root /usr/share/nginx/api;
+ }
+}
diff --git a/services/simcore/configs/fallback-service-nginx/web/503.html b/services/simcore/configs/fallback-service-nginx/web/503.html
new file mode 100644
index 00000000..440c1cc3
--- /dev/null
+++ b/services/simcore/configs/fallback-service-nginx/web/503.html
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Oops
+
+
+
+
+
+
+
+ Oops! Something went wrong.
Please try again.
+
+
+
+
+
diff --git a/services/simcore/configs/fallback-service-nginx/web/default.conf b/services/simcore/configs/fallback-service-nginx/web/default.conf
new file mode 100644
index 00000000..2f0b0d96
--- /dev/null
+++ b/services/simcore/configs/fallback-service-nginx/web/default.conf
@@ -0,0 +1,19 @@
+server {
+ listen 80;
+ listen [::]:80;
+ server_name localhost;
+
+ error_page 503 /503.html;
+
+ location / {
+ return 503;
+ }
+
+ location = /503.html {
+ default_type text/html;
+
+ add_header Retry-After "10" always; # https://serverfault.com/a/647552
+
+ root /usr/share/nginx/html;
+ }
+}
diff --git a/services/simcore/docker-compose.yml b/services/simcore/docker-compose.yml.j2
similarity index 88%
rename from services/simcore/docker-compose.yml
rename to services/simcore/docker-compose.yml.j2
index 6aa997fb..f6f0ff89 100644
--- a/services/simcore/docker-compose.yml
+++ b/services/simcore/docker-compose.yml.j2
@@ -53,7 +53,9 @@ services:
agent:
networks:
- monitored
+{%- raw %}
hostname: "{{.Node.Hostname}}-{{.Service.Name}}"
+{%- endraw %}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
@@ -270,9 +272,10 @@ services:
<<: *webserver_resources
extra_hosts: []
-
wb-db-event-listener:
+{%- raw %}
hostname: "{{.Service.Name}}"
+{%- endraw %}
environment:
- WEBSERVER_LOGLEVEL=${WEBSERVER_LOGLEVEL}
networks:
@@ -311,7 +314,9 @@ services:
- default
- interactive_services_subnet
- monitored
+{%- raw %}
hostname: "{{.Service.Name}}"
+{%- endraw %}
deploy:
update_config:
parallelism: 2
@@ -538,7 +543,9 @@ services:
cpus: '0.1'
efs-guardian:
+{%- raw %}
hostname: "{{.Service.Name}}"
+{% endraw %}
networks:
- monitored
deploy:
@@ -644,7 +651,9 @@ services:
networks:
- monitored
- public
+{%- raw %}
hostname: "{{.Service.Name}}"
+{% endraw %}
deploy:
# NOTE: https://github.com/ITISFoundation/osparc-simcore/pull/4286
# NOTE: this MUSTN'T change, or weird things might happen
@@ -768,6 +777,7 @@ services:
reservations:
memory: 128M
cpus: '0.1'
+
traefik_api:
# NOTE: this is a trick to allow to access the internal traefik REST API
# A comment
@@ -813,6 +823,7 @@ services:
reservations:
memory: 8M
cpus: '0.1'
+
whoami:
image: "containous/whoami:v1.5.0"
networks:
@@ -851,6 +862,7 @@ services:
reservations:
memory: 8M
cpus: '0.1'
+
payments:
deploy:
placement:
@@ -894,9 +906,82 @@ services:
- traefik.http.routers.${PREFIX_STACK_NAME}_dynamic_scheduler.tls=true
- traefik.http.routers.${PREFIX_STACK_NAME}_dynamic_scheduler.middlewares=ops_gzip@swarm, ops_auth@swarm
+ fallback-service-web:
+ image: nginx:1.25.1
+ configs:
+ - source: {{ SWARM_STACK_NAME }}_web_html
+ target: /usr/share/nginx/html/503.html
+ - source: {{ SWARM_STACK_NAME }}_web_nginx_config
+ target: /etc/nginx/conf.d/default.conf
+ networks:
+ - public
+ - monitored
+ deploy:
+ placement:
+ constraints:
+ - node.labels.simcore==true
+ update_config:
+ order: start-first
+ labels:
+ - io.simcore.zone=${TRAEFIK_SIMCORE_ZONE}
+ - traefik.enable=true
+
+ # webserver
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_html.priority=1
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_html.rule=(Path(`/`) || Path(`/v0`) || Path(`/socket.io/`) || Path(`/static-frontend-data.json`) || PathRegexp(`^/study/(?P\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b)`) || Path(`/view`) || Path(`/#/view`) || Path(`/#/error`) || PathPrefix(`/v0/`))
+ - traefik.http.services.${PREFIX_STACK_NAME}_fallback_html.loadbalancer.server.port=80
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_html.entrypoints=http
+
+ fallback-service-api:
+ image: nginx:1.25.1
+ configs:
+ - source: {{ SWARM_STACK_NAME }}_api_json
+ target: /usr/share/nginx/api/503.json
+ - source: {{ SWARM_STACK_NAME }}_api_nginx_config
+ target: /etc/nginx/conf.d/default.conf
+ networks:
+ - public
+ - monitored
+ deploy:
+ placement:
+ constraints:
+ - node.labels.simcore==true
+ update_config:
+ order: start-first
+ labels:
+ - io.simcore.zone=${TRAEFIK_SIMCORE_ZONE}
+ - traefik.enable=true
+ # api-server
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_api.priority=1
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_api.rule=Path(`/`) || Path(`/v0`) || PathPrefix(`/v0/`) || Path(`/api/v0/openapi.json`)
+ - traefik.http.services.${PREFIX_STACK_NAME}_fallback_api.loadbalancer.server.port=80
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_api.entrypoints=simcore_api
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_api.service=${PREFIX_STACK_NAME}_fallback_api
+ # invitations
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_invitations_api.priority=1
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_invitations_api.rule=(${DEPLOYMENT_FQDNS_CAPTURE_INVITATIONS})
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_invitations_api.entrypoints=http
+ - traefik.http.services.${PREFIX_STACK_NAME}_fallback_invitations_api.loadbalancer.server.port=80
+ - traefik.http.routers.${PREFIX_STACK_NAME}_fallback_invitations_api.service=${PREFIX_STACK_NAME}_fallback_invitations_api
+
+configs:
+ {{ SWARM_STACK_NAME }}_web_html:
+ file: ./configs/fallback-service-nginx/web/503.html
+ name: {{ SWARM_STACK_NAME }}_web_html_{{ "./configs/fallback-service-nginx/web/503.html" | sha256file | substring(0,10) }}
+ {{ SWARM_STACK_NAME }}_api_json:
+ file: ./configs/fallback-service-nginx/api/503.json
+ name: {{ SWARM_STACK_NAME }}_api_json_{{ "./configs/fallback-service-nginx/api/503.json" | sha256file | substring(0,10) }}
+ {{ SWARM_STACK_NAME }}_web_nginx_config:
+ file: ./configs/fallback-service-nginx/web/default.conf
+ name: {{ SWARM_STACK_NAME }}_web_nginx_config_{{ "./configs/fallback-service-nginx/web/default.conf" | sha256file | substring(0,10) }}
+ {{ SWARM_STACK_NAME }}_api_nginx_config:
+ file: ./configs/fallback-service-nginx/api/default.conf
+ name: {{ SWARM_STACK_NAME }}_api_nginx_config_{{ "./configs/fallback-service-nginx/api/default.conf" | sha256file | substring(0,10) }}
+
volumes:
rabbit_data:
name: ${SWARM_STACK_NAME}_rabbit_data
+
networks:
public:
external: true