Skip to content

Commit

Permalink
WIP docker swarm
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik van Velzen committed Aug 21, 2024
1 parent 150ec7f commit 306375d
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ indent_size = 4

[*.{yml,yaml}]
indent_style = space
indent_size = 2
indent_size = 4

[*.md]
trim_trailing_whitespace = false
Expand Down
41 changes: 39 additions & 2 deletions .github/workflows/build-push-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- main
- production
- acceptance
- swarm
workflow_dispatch:

permissions:
Expand Down Expand Up @@ -74,7 +75,7 @@ jobs:
--push
## This job takes pretty long and can be split up to parallelize the deploy.
deploy-wagtail:
deploy-wagtail-azure:
needs:
- build-and-push-images
- variables
Expand Down Expand Up @@ -142,7 +143,7 @@ jobs:
--hostname ${{ fromJson(needs.variables.outputs.result).WAGTAIL_HOSTNAME }}
deploy-next:
deploy-next-azure:
needs:
- build-and-push-images
- variables
Expand Down Expand Up @@ -195,3 +196,39 @@ jobs:
--environment holon-env
--name next-${{ github.ref_name }}
--hostname www.holontool.nl
deploy-swarm:
runs-on: ubuntu-latest
needs:
- build-and-push-images
- variables
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
sparse-checkout: docker
- name: Deploy to Docker Swarm
uses: sagebind/docker-swarm-deploy-action@v2
env:
AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }}
MEDIA_LOCATION: ${{ fromJson(needs.variables.outputs.result).MEDIA_LOCATION }}
STATIC_LOCATION: ${{ fromJson(needs.variables.outputs.result).STATIC_LOCATION }}
DB_HOST: ${{ secrets.DB_HOST }}
DB_USER: ${{ fromJson(needs.variables.outputs.result).DB_USER }}
DB_NAME: ${{ fromJson(needs.variables.outputs.result).DB_NAME }}
DB_PASSWORD: ${{ secrets[fromJson(needs.variables.outputs.result).DB_PASSWORD_KEY] }}
RETURN_SCENARIO: ${{ fromJson(needs.variables.outputs.result).RETURN_SCENARIO }}
SECRET_KEY: "${{ secrets.SECRET_KEY }}"
SENTRY_ENVIRONMENT: ${{ fromJson(needs.variables.outputs.result).SENTRY_ENVIRONMENT }}
DOMAIN_HOST: ${{ fromJson(needs.variables.outputs.result).DOMAIN_HOST }}
N_WORKERS: ${{ fromJson(needs.variables.outputs.result).wagtail.N_WORKERS }}
EMAIL_HOST_PASSWORD: ${{ secrets.EMAIL_HOST_PASSWORD }}
WAGTAIL_HOSTNAME: https://${{ fromJson(needs.variables.outputs.result).WAGTAIL_HOSTNAME }}
# NextJS
NEXT_HOSTNAME: ${{ fromJson(needs.variables.outputs.result).NEXT_HOSTNAME }}
NEXT_PUBLIC_TINY_URL_API_KEY: ${{ secrets.TINY_URL_API_KEY }}
with:
remote_host: ssh://[email protected]
ssh_private_key: ${{ secrets.SWARM_SSH_PRIVATE_KEY }}
ssh_public_key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ1E4LUG22qgzc8U7oNYGWCn0cyA31+iyX2pck9wcPMS
args: stack deploy --compose-file ./docker/compose-prod.yaml holon-${{ github.ref_name }}
12 changes: 12 additions & 0 deletions .github/workflows/get-variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ const configPerBranch = {
N_WORKERS: '4',
}
},
swarm: {
DB_NAME: 'holon-test',
DB_USER: 'holon-test',
DB_PASSWORD_KEY: 'POSTGRES_PASSWORD',
RETURN_SCENARIO: 'True',
SENTRY_ENVIRONMENT: 'swarm-test',
NEXT_HOSTNAME: 'swarm.holontool.nl',
DOMAIN_HOST: 'https://swarm.holontool.nl',
WAGTAIL_HOSTNAME: 'cms-swarm.holontool.nl',
MEDIA_LOCATION: 'media-test',
STATIC_LOCATION: 'static-test',
},
}

module.exports = (branchName) => {
Expand Down
61 changes: 61 additions & 0 deletions docker/compose-prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Compose file for Docker Swarm environments
version: "3.8"

services:
wagtail:
image: ghcr.io/zenmo/holon-wagtail:${TAG}
environment:
ALLOWED_HOSTS: "*"
AZURE_ACCOUNT_NAME: holonstorage
AZURE_STORAGE_KEY: ${AZURE_STORAGE_KEY}
MEDIA_LOCATION: ${MEDIA_LOCATION}
STATIC_LOCATION: ${STATIC_LOCATION}
DB_HOST: ${DB_HOST}
DB_USER: ${DB_USER}
DB_NAME: ${DB_NAME}
DB_PASSWORD: ${DB_PASSWORD}
RETURN_SCENARIO: ${RETURN_SCENARIO}
SECRET_KEY: ${SECRET_KEY}
SENTRY_DSN: "https://764e9f2b886741bcbcfd2acd74a7f7b0@o4505045746384896.ingest.sentry.io/4505045759361024"
SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT}
DOMAIN_HOST: ${DOMAIN_HOST}
N_WORKERS: ${N_WORKERS}
EMAIL_HOST_PASSWORD: ${EMAIL_HOST_PASSWORD}
WAGTAILADMIN_BASE_URL: https://${WAGTAIL_HOSTNAME}
labels:
caddy: ${WAGTAIL_HOSTNAME}
caddy.reverse_proxy: "{{upstreams 8000}}"
networks:
- caddy_default
- postgres_default
- default
deploy:
resources:
limits:
cpus: "8"
memory: 8G

nextjs:
image: ghcr.io/zenmo/holon-nextjs:${TAG}
environment:
WAGTAIL_API_URL: http://wagtail:8000/wt/api/nextjs
NEXT_PUBLIC_WAGTAIL_API_URL: https://${WAGTAIL_HOSTNAME}/wt/api/nextjs
NEXT_PUBLIC_TINY_URL_API_KEY: ${NEXT_PUBLIC_TINY_URL_API_KEY}
labels:
caddy: ${NEXT_HOSTNAME}, www.${NEXT_HOSTNAME}
caddy.reverse_proxy: "{{upstreams 3000}}"
networks:
- caddy_default
- default
deploy:
resources:
limits:
cpus: "4"
memory: 4G

networks:
caddy_default:
external: true
postgres_default:
external: true
default:
1 change: 1 addition & 0 deletions docker/config/python.example.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# For development
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_BUCKET_NAME=
Expand Down
42 changes: 31 additions & 11 deletions src/holon/views/holon.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from django.apps import apps
from django.shortcuts import render
from etm_service.etm_session.session import ETMConnectionError
from rest_framework import generics, status
from rest_framework.request import Request
from rest_framework.response import Response
Expand All @@ -15,9 +14,10 @@
from holon.models.config import QueryCovertModuleType
from holon.models.scenario_rule import ModelType, DatamodelQueryRule
from holon.models.util import all_subclasses, is_exclude_field
from holon.serializers import HolonRequestSerializer, ScenarioSerializer
from holon.serializers import HolonRequestSerializer
from holon.services import CostTables, ETMConnect
from holon.services.cloudclient import CloudClient
from holon.services.cloudclient.input import inputs_to_debug_values
from holon.services.cloudclient.output import AnyLogicOutput
from holon.services.data import Results
from holon.utils.logging import HolonLogger
Expand Down Expand Up @@ -58,6 +58,13 @@ def post(self, request: Request):
use_caching = use_result_cache(request)
scenario: Scenario | None = None
anylogic_output: AnyLogicOutput | None = None
debug_values = {
"scenario": {},
"anylogic": {
"input": {},
"output": {},
},
}

try:
if not serializer.is_valid():
Expand All @@ -84,15 +91,29 @@ def post(self, request: Request):
HolonV2Service.logger.log_print("Applying interactive elements to scenario")

scenario = Scenario.queryset_with_relations().get(id=scenario_id)
debug_values["scenario"] = {
"id": scenario.id,
"name": scenario.name,
}

scenario_aggregate = ScenarioAggregate(scenario)
scenario_aggregate = rule_mapping.apply_rules(scenario_aggregate, interactive_elements)

cc_payload = scenario_aggregate.serialize_to_json()

# RUN ANYLOGIC
HolonV2Service.logger.log_print("Running Anylogic model")
anylogic_output = CloudClient(payload=cc_payload, scenario=scenario).run()
anylogic_client = CloudClient(payload=scenario_aggregate, scenario=scenario)
debug_values["anylogic"]["input"] = {
# TODO: this is quite computationally expensive, see if we can do it only when needed
"debug": inputs_to_debug_values(anylogic_client.create_inputs())
}
anylogic_output = anylogic_client.run()
# Disabled because it makes the response too big for common tooling
# debug_values["anylogic"]["output"] = {
# # TODO: this is quite computationally expensive, see if we can do it only when needed
# "debug": anylogic_output.get_debug_output(),
# # It would be useful to include the interpreted values but the response is getting too big
# # "decoded": anylogic_output.decoded,
# }

# ETM Module
# We want to be resilient in the face of errors.
Expand All @@ -113,7 +134,7 @@ def post(self, request: Request):
)

results = Results(
cc_payload=cc_payload,
debug_values=debug_values,
request=request,
anylogic_outcomes=anylogic_output,
cost_benefit_overview=cost_benefit_tables.main_table(),
Expand Down Expand Up @@ -141,11 +162,10 @@ def post(self, request: Request):
traceback.print_exc()
capture_exception(e)

response_body = {"error_msg": f"something went wrong: {e}"}
if scenario:
response_body["scenario"] = ScenarioSerializer(scenario).data
if anylogic_output:
response_body["anylogic_outcomes"] = anylogic_output.decoded
response_body = {
"error_msg": f"something went wrong: {e}",
"debug_values": debug_values,
}

return Response(
response_body,
Expand Down
2 changes: 1 addition & 1 deletion src/requirements/local.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-r test.txt

# Add local extra requirements here (django-debug etc)
pydevd-pycharm~=241.17011.79
pydevd-pycharm~=242.21829.44
black
django-debug-toolbar
isort
Expand Down

0 comments on commit 306375d

Please sign in to comment.