services: # ── Orchestration workflow engine ───────────────────────────────────────── orchestrator: build: context: ../lf_orchestration dockerfile_inline: | FROM python:3.12-slim WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 RUN apt-get update && apt-get install -y --no-install-recommends curl \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 1717 CMD ["uvicorn", "orchestrator.main:app", "--host", "0.0.0.0", "--port", "1717"] image: lf-orchestrator:${ORCHESTRATOR_VERSION:-dev} container_name: lf-orchestrator ports: - "${ORCHESTRATOR_PORT:-1717}:1717" environment: MODE: ${ORCHESTRATOR_MODE:-plug} SPECTROMETER_URL: http://spectrometer:8000 RECONSTRUCTOR_URL: http://reconstructor:8000 SEQ_INTERP_URL: http://seq-interp:7475 depends_on: seq-interp: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1717/health"] interval: 10s timeout: 5s retries: 5 start_period: 15s # ── MRI sequence interpreter ─────────────────────────────────────────────── seq-interp: build: context: ../lf_mri/MRI-testing dockerfile: seq_interp/Dockerfile image: lf-seq-interp:${SEQ_INTERP_VERSION:-dev} container_name: lf-seq-interp ports: - "${SEQ_INTERP_PORT:-7475}:7475" volumes: - seq_interp_input:/app/seq_interp/data/input - seq_interp_output:/app/seq_interp/data/output - seq_interp_logs:/app/seq_interp/log restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:7475/health"] interval: 10s timeout: 5s retries: 5 start_period: 15s # ── Spectroscopy signal processor ───────────────────────────────────────── spectroscopy: build: context: ../lf_mri/fast-api-spectroscopy image: lf-spectroscopy:${SPECTROSCOPY_VERSION:-dev} container_name: lf-spectroscopy ports: - "${SPECTROSCOPY_PORT:-8002}:8002" environment: SERVICE_PORT: "8002" restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8002/health"] interval: 10s timeout: 5s retries: 5 start_period: 15s # ── MRI image reconstructor ──────────────────────────────────────────────── reconstructor: build: context: ../fast-api-reconstruction/serv dockerfile_inline: | FROM python:3.12-slim WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PYTHONPATH=/app MPLBACKEND=Agg RUN apt-get update && apt-get install -y --no-install-recommends curl libgomp1 \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000"] image: lf-reconstructor:${RECONSTRUCTOR_VERSION:-dev} container_name: lf-reconstructor ports: - "${RECONSTRUCTOR_PORT:-8081}:8000" volumes: - reconstructor_sessions:/app/sessions restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 10s timeout: 5s retries: 5 start_period: 20s # ── Spectrometer hardware controller (DRF) ──────────────────────────────── spectrometer: build: context: ../lowfield_mri_programs/spectrometer_service/mserv00 dockerfile_inline: | FROM python:3.12-slim WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 \ DJANGO_SETTINGS_MODULE=mserv00.settings \ DJANGO_ALLOWED_HOSTS=* RUN apt-get update && apt-get install -y --no-install-recommends curl \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . RUN sed -i "s/ALLOWED_HOSTS = \[.*/ALLOWED_HOSTS = ['*']/" mserv00/settings.py \ && python manage.py migrate --noinput EXPOSE 8000 CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] image: lf-spectrometer:${SPECTROMETER_VERSION:-dev} container_name: lf-spectrometer ports: - "${SPECTROMETER_PORT:-8000}:8000" volumes: - spectrometer_db:/app/db restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/api/"] interval: 15s timeout: 5s retries: 5 start_period: 30s volumes: seq_interp_input: seq_interp_output: seq_interp_logs: reconstructor_sessions: spectrometer_db: