Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
49a11d6
Feat: Add k8s manifests for deploying the full service
amirsadraabdollahi May 17, 2026
bd16f21
Fix: change build_and_push branch to all
amirsadraabdollahi May 17, 2026
d30736f
Feat: Add image pull secret to manifests
amirsadraabdollahi May 18, 2026
e669965
Fix: use dockerhub rabbitmq image
amirsadraabdollahi May 18, 2026
453b660
Fix: Add command to cantaloupe deployment
amirsadraabdollahi May 18, 2026
c766be1
Fix: Decrease pvc storage size for nginx
amirsadraabdollahi May 18, 2026
f9d791e
Feat: Add cantus-k3s.simssa.ca to hosts
amirsadraabdollahi May 18, 2026
f5f422d
Feat: Add imagepullpolicy
amirsadraabdollahi May 18, 2026
4ed34ea
Fix: Tune memory resources of pods
amirsadraabdollahi May 18, 2026
bbbe4f3
Feat: Add django-extensions app
amirsadraabdollahi May 19, 2026
999c98d
Remove init container for migrate in app k8s manifest
amirsadraabdollahi May 19, 2026
90c6351
Fix: Tune resources, turn off the merge slash in nginx and ingress
amirsadraabdollahi May 19, 2026
120b0a8
Fix: replace https:/ with https:// in manifest_proxy view
amirsadraabdollahi May 19, 2026
6a2c131
Remove annotation from ingress
amirsadraabdollahi May 19, 2026
47d0858
Feat: Update dependencies
amirsadraabdollahi May 19, 2026
8c53d2f
Increase memory limit of app deployment
amirsadraabdollahi May 19, 2026
45fe5bb
Fix: force_insert and force_update in model.save() for django 6
amirsadraabdollahi May 20, 2026
0963353
Fix: run black linter
amirsadraabdollahi May 20, 2026
3ecc964
Update black linter
amirsadraabdollahi May 20, 2026
89692ad
Feat: Add staging manifests for k8s
amirsadraabdollahi May 20, 2026
b0cd0f5
Add Migration plan
amirsadraabdollahi May 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/workflows/build_and_push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: build-and-push

on:
push:
branches: ["**"]
tags: ["v*.*.*"]
workflow_dispatch:

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
include:
- name: app
context: .
file: ./app/Dockerfile
image: cantus-app
build_args: DEVELOPMENT=False
- name: nginx
context: .
file: ./nginx/Dockerfile
image: cantus-nginx
- name: solr
context: ./solr
file: ./solr/Dockerfile
image: cantus-solr
- name: cantaloupe
context: ./cantaloupe
file: ./cantaloupe/Dockerfile
image: cantus-cantaloupe

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}
tags: |
type=sha,prefix={{branch}}-
type=raw,value={{branch}}-latest
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
file: ${{ matrix.file }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: ${{ matrix.build_args }}
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ __init__.pyc
.vscode
_local_django_settings.py
.python-version
mypy.ini
mypy.ini
.idea
3 changes: 2 additions & 1 deletion app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ COPY app/production-mei-files/ /code/production-mei-files/
EXPOSE 8001

RUN chmod u+x /code/django-config.sh
COPY app/public /code/public
# Copy environment dependencies, but not poetry, to the django container
COPY --from=dependency-install-container /code/.venv /code/.venv
# Add our python environment binaries and package files to the path
ENV PATH="$PATH:/code/.venv/bin/" \
PYTHONPATH="$PYTHONPATH:/code/.venv/lib/python3.12/site-packages/" \
PYTHONPATH="/code/.venv/lib/python3.12/site-packages/" \
DJANGO_SETTINGS_MODULE="cantusdata.settings"

WORKDIR /code/public
7 changes: 3 additions & 4 deletions app/public/cantusdata/admin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
from django.db.models import Model
from django.db.models.query import QuerySet
from django.http import HttpRequest

from django_celery_results.models import TaskResult # type: ignore[import-untyped]
from django_celery_results.admin import TaskResultAdmin # type: ignore[import-untyped]
from django_celery_results.models import TaskResult # type: ignore[import-untyped]

from cantusdata.models.manuscript import Manuscript
from cantusdata.models.chant import Chant
from cantusdata.models.folio import Folio
from cantusdata.models.plugin import Plugin
from cantusdata.models.manuscript import Manuscript
from cantusdata.models.neume_exemplar import NeumeExemplar
from cantusdata.models.plugin import Plugin
from cantusdata.tasks import chant_import_task


Expand Down
5 changes: 3 additions & 2 deletions app/public/cantusdata/helpers/mei_processing/mei_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
Defines associated types for the data structures used by the parser.
"""

from typing import Tuple, Dict, List, Iterator, Optional
from lxml import etree # pylint: disable=no-name-in-module
from typing import Tuple, Dict, List, Iterator, Optional

from cantusdata.helpers.neume_helpers import NEUME_GROUPS, NeumeName
from .bounding_box_utils import combine_bounding_boxes_single_system
from .mei_parsing_types import (
Zone,
SyllableText,
Expand All @@ -25,7 +27,6 @@
Neume,
Syllable,
)
from .bounding_box_utils import combine_bounding_boxes_single_system

# Mapping from pitch names to integer pitch class where C = 0
PITCH_CLASS = {"c": 0, "d": 2, "e": 4, "f": 5, "g": 7, "a": 9, "b": 11}
Expand Down
9 changes: 6 additions & 3 deletions app/public/cantusdata/helpers/mei_processing/mei_tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,12 @@ def _create_document_from_neume_components(
and the system number of that neume component.
:return: An NgramDocument containing the information from the neume components.
"""
pitch_names, contour, semitone_intervals, intervals = (
self._stringify_neume_component_data(neume_components)
)
(
pitch_names,
contour,
semitone_intervals,
intervals,
) = self._stringify_neume_component_data(neume_components)
zones_with_sys: List[Tuple[Zone, int]] = [
(nc["bounding_box"], nc["system"]) for nc in neume_components
]
Expand Down
4 changes: 3 additions & 1 deletion app/public/cantusdata/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@ class Migration(migrations.Migration):
migrations.AddConstraint(
model_name="manuscript",
constraint=models.CheckConstraint(
check=models.Q(("is_mapped__in", ["UNMAPPED", "PENDING", "MAPPED"])),
condition=models.Q(
("is_mapped__in", ["UNMAPPED", "PENDING", "MAPPED"])
),
name="is_mapped_status",
),
),
Expand Down
7 changes: 5 additions & 2 deletions app/public/cantusdata/models/manuscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class Meta:
ordering = ["name"]
constraints = [
models.CheckConstraint(
check=models.Q(is_mapped__in=IsMapped.values), name="is_mapped_status"
condition=models.Q(is_mapped__in=IsMapped.values),
name="is_mapped_status",
)
]

Expand Down Expand Up @@ -60,7 +61,9 @@ def __init__(self, *args, **kwargs):
self._last_public_value = self.public

def save(self, force_insert=False, force_update=False, *args, **kwargs):
super(Manuscript, self).save(force_insert, force_update, *args, **kwargs)
super(Manuscript, self).save(
force_insert=force_insert, force_update=force_update, *args, **kwargs
)

if (self.public != self._last_public_value) and self.chants_loaded:
# The public property has changed, we need to refresh the Solr chants
Expand Down
32 changes: 22 additions & 10 deletions app/public/cantusdata/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
DEBUG = False

ALLOWED_HOSTS = [
"cantus-k3s.simssa.ca",
"cantus.simssa.ca",
"dev-cantus.simssa.ca",
"cantus.staging.simssa.ca",
"localhost",
"cantus-app-1",
]
] + [h for h in os.environ.get("EXTRA_ALLOWED_HOSTS", "").split(",") if h]

# Application definition

Expand All @@ -41,6 +41,7 @@
"django.contrib.staticfiles",
# Additional apps
"django_celery_results",
"django_extensions",
"rest_framework",
"rest_framework.authtoken",
"cantusdata.CantusdataConfig",
Expand Down Expand Up @@ -89,7 +90,7 @@
"NAME": os.environ.get("POSTGRES_DB"),
"USER": os.environ.get("POSTGRES_USER"),
"PASSWORD": os.environ.get("POSTGRES_PASSWORD"),
"HOST": "postgres",
"HOST": os.environ.get("POSTGRES_HOST", "postgres"),
"PORT": "5432",
}
}
Expand Down Expand Up @@ -121,8 +122,6 @@

USE_I18N = True

USE_L10N = True

USE_TZ = True


Expand Down Expand Up @@ -150,9 +149,14 @@

DATA_UPLOAD_MAX_NUMBER_FIELDS = 10000

SOLR_SERVER = "http://solr:8983/solr/cantus_ultimus_1"
SOLR_ADMIN = "http://solr:8983/solr/admin"
SOLR_TEST_SERVER = "http://solr:8983/solr/cantus-test"
_solr_host = os.environ.get("SOLR_HOST", "solr")
SOLR_SERVER = os.environ.get(
"SOLR_SERVER", f"http://{_solr_host}:8983/solr/cantus_ultimus_1"
)
SOLR_ADMIN = os.environ.get("SOLR_ADMIN", f"http://{_solr_host}:8983/solr/admin")
SOLR_TEST_SERVER = os.environ.get(
"SOLR_TEST_SERVER", f"http://{_solr_host}:8983/solr/cantus-test"
)

LOGGING_CONFIG = None

Expand All @@ -163,13 +167,21 @@

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_TRUSTED_ORIGINS = ["https://cantus.simssa.ca", "https://cantus.staging.simssa.ca"]
CSRF_TRUSTED_ORIGINS = [
"https://cantus-k3s.simssa.ca",
"https://cantus.simssa.ca",
"https://cantus.staging.simssa.ca",
]

SECURE_HSTS_SECONDS = 86400
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True

CELERY_BROKER_URL = f"amqp://{os.environ.get('RABBIT_USER')}:{os.environ.get('RABBIT_PASSWORD')}@cantus-rabbitmq-1:5672/{os.environ.get('RABBIT_VHOST')}"
_rabbit_host = os.environ.get("RABBIT_HOST", "cantus-rabbitmq-1")
CELERY_BROKER_URL = (
f"amqp://{os.environ.get('RABBIT_USER')}:{os.environ.get('RABBIT_PASSWORD')}"
f"@{_rabbit_host}:5672/{os.environ.get('RABBIT_VHOST')}"
)
CELERY_RESULT_BACKEND = "django-db"
CELERY_RESULT_PERSISTENT = False
CELERY_RESULT_EXTENDED = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@


class TestBoundingBoxUtils(TestCase):

def test_combine_bounding_boxes_single_system(self) -> None:
bounding_boxes: List[Zone] = [
{"coordinates": (0, 0, 1, 1), "rotate": 0},
Expand Down
4 changes: 4 additions & 0 deletions app/public/cantusdata/views/manifest_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class ManifestProxyView(APIView):

def get(self, request, *args, **kwargs):
manifest_url = kwargs["manifest_url"]
# Traefik (and some nginx configs) collapse https:// → https:/
manifest_url = manifest_url.replace("https:/", "https://", 1).replace(
"http:/", "http://", 1
)
postprocessing = iiif_fn.get(manifest_url, lambda x: x)
format_ = kwargs.get("format", None)
if format_:
Expand Down
5 changes: 4 additions & 1 deletion compose-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ services:
dockerfile: ./app/Dockerfile
args:
DEVELOPMENT: ${DEVELOPMENT}
image: cantus-app
container_name: cantus-app-1
command: /code/django-config.sh
volumes:
Expand Down Expand Up @@ -49,7 +50,9 @@ services:

nginx:
container_name: cantus-nginx-1
build: ./nginx
build:
context: .
dockerfile: ./nginx/Dockerfile
ports:
- "8000:8000"
depends_on:
Expand Down
5 changes: 4 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ services:
dockerfile: ./app/Dockerfile
args:
DEVELOPMENT: ${DEVELOPMENT}
image: cantus-app
container_name: cantus-app-1
command: /code/django-config.sh
volumes:
Expand Down Expand Up @@ -44,7 +45,9 @@ services:

nginx:
container_name: cantus-nginx-1
build: ./nginx
build:
context: .
dockerfile: ./nginx/Dockerfile
ports:
- "8000:8000"
depends_on:
Expand Down
Loading
Loading