Skip to content

Commit 129eae1

Browse files
authored
Merge pull request #125 from openzim/rework-components-add-shuttle
Rework backend to isolate the mill and the shuttle
2 parents 505e403 + 0f6d919 commit 129eae1

39 files changed

+391
-190
lines changed

.github/workflows/Publish.yml

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,60 @@ jobs:
4242
- name: Retrieve source code
4343
uses: actions/checkout@v5
4444

45-
- name: Build and publish Docker Image
45+
- name: Build and publish Docker Image for backend mill
46+
uses: openzim/docker-publish-action@v10
47+
with:
48+
image-name: openzim/cms-mill
49+
on-master: latest
50+
restrict-to: openzim/cms
51+
context: backend
52+
dockerfile: Dockerfile-mill
53+
registries: ghcr.io
54+
credentials:
55+
GHCRIO_USERNAME=${{ secrets.GHCR_USERNAME }}
56+
GHCRIO_TOKEN=${{ secrets.GHCR_TOKEN }}
57+
58+
- name: Build and publish Docker Image for backend shuttle
59+
uses: openzim/docker-publish-action@v10
60+
with:
61+
image-name: openzim/cms-shuttle
62+
on-master: latest
63+
restrict-to: openzim/cms
64+
context: backend
65+
dockerfile: Dockerfile-shuttle
66+
registries: ghcr.io
67+
credentials:
68+
GHCRIO_USERNAME=${{ secrets.GHCR_USERNAME }}
69+
GHCRIO_TOKEN=${{ secrets.GHCR_TOKEN }}
70+
71+
- name: Build and publish Docker Image for backend API
4672
uses: openzim/docker-publish-action@v10
4773
with:
4874
image-name: openzim/cms-api
4975
on-master: latest
5076
restrict-to: openzim/cms
5177
context: backend
78+
dockerfile: Dockerfile-api
5279
registries: ghcr.io
5380
credentials:
5481
GHCRIO_USERNAME=${{ secrets.GHCR_USERNAME }}
5582
GHCRIO_TOKEN=${{ secrets.GHCR_TOKEN }}
5683

84+
# mill should be first since it deploys the alembic migration
85+
- name: Deploy CMS Mill changes to cms.openzim.org
86+
uses: actions-hub/kubectl@master
87+
env:
88+
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
89+
with:
90+
args: rollout restart deployments mill-deployment -n cms
91+
92+
- name: Deploy CMS Shuttle changes to cms.openzim.org
93+
uses: actions-hub/kubectl@master
94+
env:
95+
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
96+
with:
97+
args: rollout restart deployments shuttle-deployment -n cms
98+
5799
- name: Deploy CMS API changes to cms.openzim.org
58100
uses: actions-hub/kubectl@master
59101
env:

.github/workflows/backend-Tests.yml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,32 @@ jobs:
5555
psql -c 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";'
5656
"host=localhost port=5432 dbname=cmstest user=cms password=cmspass"
5757
58-
- name: Build backend Docker image
58+
- name: Build backend mill Docker image
5959
working-directory: backend
60-
run: docker build -t cms-backend:test .
60+
run: docker build -t cms-backend-mill:test -f Dockerfile-mill .
6161

62-
- name: Run backend container
62+
- name: Build backend shuttle Docker image
63+
working-directory: backend
64+
run: docker build -t cms-backend-shuttle:test -f Dockerfile-shuttle .
65+
66+
- name: Build backend API Docker image
67+
working-directory: backend
68+
run: docker build -t cms-backend-api:test -f Dockerfile-api .
69+
70+
- name: Run backend api container
6371
run: |
6472
docker run -d --name cms-backend-test \
6573
-e POSTGRES_URI=$POSTGRES_URI \
6674
-e JWT_SECRET=DH8kSxcflUVfNRdkEiJJCn2dOOKI3qfw \
6775
-p 8000:80 \
68-
cms-backend:test
76+
cms-backend-api:test
6977
# wait for container to be ready
7078
for i in {1..10}; do
7179
if curl -s http://localhost:8000/v2/healthcheck > /dev/null; then
72-
echo "Backend is up!"
80+
echo "Backend API is up!"
7381
break
7482
fi
75-
echo "Waiting for backend..."
83+
echo "Waiting for backend API..."
7684
sleep 3
7785
done
7886
@@ -81,6 +89,7 @@ jobs:
8189
env:
8290
DATABASE_URL: postgresql+psycopg://cms:cmspass@localhost:5432/cmstest
8391
JWT_SECRET: DH8kSxcflUVfNRdkEiJJCn2dOOKI3qfw
92+
ALEMBIC_UPGRADE_HEAD_ON_START: false
8493
run: inv coverage --args "-vvv"
8594

8695
- name: Upload coverage report to codecov

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ You are welcome to use it, report bugs and request features!
1010

1111
As an internal tool, we don't provide releases nor changelogs for the CMS. Please check the respective source-code for the two components of the CMS:
1212

13-
- `backend`: the python backend API available via `ghcr.io/openzim/cms-api` docker image.
13+
- `backend`: the python backend, with 3 sub-components:
14+
- the `api`, responsible to provide an API (sic), available via `ghcr.io/openzim/cms-api` docker image
15+
- the `mill`, responsible to process background tasks, available via `ghcr.io/openzim/cms-mill` docker image
16+
- the `shuttle`, responsible to move files around, available via `ghcr.io/openzim/cms-shuttle` docker image
1417
- `frontend`: the Vue.js Web UI available via `ghcr.io/openzim/cms-ui` docker image.
1518

1619
```sh

backend/Dockerfile

Lines changed: 0 additions & 38 deletions
This file was deleted.

backend/Dockerfile-api

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FROM python:3.13-slim-bookworm
2+
LABEL org.opencontainers.image.source https://github.com/openzim/cms
3+
4+
ENV ALEMBIC_UPGRADE_HEAD_ON_START=false
5+
6+
# curl needed for healthcheck
7+
RUN apt-get update && apt-get install -y curl && \
8+
rm -rf /var/lib/apt/lists/*
9+
10+
# install Python dependencies first (since they change more rarely than src code)
11+
COPY pyproject.toml README.md /app/
12+
COPY src/cms_backend/__about__.py /app/src/cms_backend/__about__.py
13+
RUN pip install --no-cache-dir '/app[api]'
14+
15+
COPY src /app/src
16+
17+
RUN pip install --no-cache-dir '/app[api]' \
18+
&& rm -rf /app/src \
19+
&& rm /app/pyproject.toml \
20+
&& rm /app/README.md
21+
22+
EXPOSE 80
23+
24+
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
25+
CMD curl -f http://localhost/v1/healthcheck || exit 1
26+
27+
CMD ["uvicorn", "cms_backend.api.main:app", "--host", "0.0.0.0", "--port", "80"]

backend/Dockerfile-mill

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM python:3.13-slim-bookworm
2+
LABEL org.opencontainers.image.source https://github.com/openzim/cms
3+
4+
ENV ALEMBIC_UPGRADE_HEAD_ON_START=true
5+
6+
# Install dependencies
7+
RUN apt-get update && apt-get install -y curl && \
8+
rm -rf /var/lib/apt/lists/*
9+
10+
# Install Python dependencies first (since they change more rarely than src code)
11+
COPY pyproject.toml README.md /app/
12+
COPY src/cms_backend/__about__.py /app/src/cms_backend/__about__.py
13+
RUN pip install --no-cache-dir /app
14+
15+
COPY src /app/src
16+
17+
RUN pip install --no-cache-dir /app \
18+
&& rm -rf /app/src \
19+
&& rm /app/pyproject.toml \
20+
&& rm /app/README.md
21+
22+
WORKDIR /app
23+
24+
CMD ["python", "-m", "cms_backend.mill.main"]

backend/Dockerfile-shuttle

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM python:3.13-slim-bookworm
2+
LABEL org.opencontainers.image.source https://github.com/openzim/cms
3+
4+
ENV ALEMBIC_UPGRADE_HEAD_ON_START=false
5+
6+
# Install dependencies
7+
RUN apt-get update && apt-get install -y curl && \
8+
rm -rf /var/lib/apt/lists/*
9+
10+
# Install Python dependencies first (since they change more rarely than src code)
11+
COPY pyproject.toml README.md /app/
12+
COPY src/cms_backend/__about__.py /app/src/cms_backend/__about__.py
13+
RUN pip install --no-cache-dir /app
14+
15+
COPY src /app/src
16+
17+
RUN pip install --no-cache-dir /app \
18+
&& rm -rf /app/src \
19+
&& rm /app/pyproject.toml \
20+
&& rm /app/README.md
21+
22+
WORKDIR /app
23+
24+
CMD ["python", "-m", "cms_backend.shuttle.main"]

backend/pyproject.toml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@ classifiers = [
1818
]
1919
dependencies = [
2020
"alembic == 1.15.2",
21-
"fastapi[all] == 0.115.2",
2221
"pydantic == 2.11.4", # this is also a sub-dep of fastapi but we rely a lot on it
2322
"SQLAlchemy == 2.0.41",
2423
"pymongo == 4.13.0",
2524
"psycopg[binary,pool] == 3.2.11",
26-
"regex == 2025.10.23"
25+
"regex == 2025.10.23",
26+
"humanfriendly == 10.0",
2727
]
2828
dynamic = ["version"]
2929

3030
[project.optional-dependencies]
31+
api = [
32+
"fastapi[all] == 0.115.2",
33+
]
3134
scripts = [
3235
"invoke == 2.2.0",
3336
]
@@ -37,6 +40,7 @@ lint = [
3740
]
3841
check = [
3942
"pyright == 1.1.400",
43+
"types-humanfriendly == 10.0.0"
4044
]
4145
test = [
4246
"coverage == 7.8.0",
@@ -46,10 +50,12 @@ test = [
4650
"pytest-env == 1.1.5",
4751
"Faker==37.3.0",
4852
"python-dateutil==2.9.0.post0",
53+
"cms_backend[api]",
4954
]
5055
dev = [
5156
"pre-commit == 4.2.0",
5257
"ipykernel == 6.29.5",
58+
"cms_backend[api]",
5359
"cms_backend[scripts]",
5460
"cms_backend[lint]",
5561
"cms_backend[test]",
@@ -61,6 +67,9 @@ Homepage = "https://github.com/openzim/cms/backend"
6167
Donate = "https://www.kiwix.org/en/support-us/"
6268

6369
[project.scripts]
70+
cms-api = "cms_backend.api.main:app"
71+
cms-mill = "cms_backend.mill.main:main"
72+
cms-shuttle = "cms_backend.shuttle.main:main"
6473
create-initial-user = "cms_backend.utils.database:create_initial_user"
6574
check-db-schema = "cms_backend.utils.database:check_if_schema_is_up_to_date"
6675

File renamed without changes.
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
from fastapi.responses import JSONResponse
1010
from pydantic import ValidationError
1111

12+
from cms_backend.api.routes.books import router as books_router
13+
from cms_backend.api.routes.healthcheck import router as healthcheck_router
14+
from cms_backend.api.routes.http_errors import BadRequestError
15+
from cms_backend.api.routes.titles import router as titles_router
16+
from cms_backend.api.routes.warehouse_paths import router as warehouse_paths_router
17+
from cms_backend.api.routes.zimfarm_notifications import (
18+
router as zimfarm_notification_router,
19+
)
1220
from cms_backend.db.exceptions import (
1321
RecordAlreadyExistsError,
1422
RecordDisabledError,
1523
RecordDoesNotExistError,
1624
)
17-
from cms_backend.routes.books import router as books_router
18-
from cms_backend.routes.healthcheck import router as healthcheck_router
19-
from cms_backend.routes.http_errors import BadRequestError
20-
from cms_backend.routes.titles import router as titles_router
21-
from cms_backend.routes.warehouse_paths import router as warehouse_paths_router
22-
from cms_backend.routes.zimfarm_notifications import (
23-
router as zimfarm_notification_router,
24-
)
2525
from cms_backend.utils.database import (
2626
upgrade_db_schema,
2727
)

0 commit comments

Comments
 (0)