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