FROM node:20-alpine AS frontend-build WORKDIR /frontend COPY frontend/package.json frontend/package-lock.json* ./ RUN npm install COPY frontend/ ./ RUN npm run build FROM postgres:16-bookworm AS runtime ARG GEOINTEL_INSTALL_AI=false ARG GEOINTEL_TORCH_INDEX_URL=https://download.pytorch.org/whl/cpu ARG GEOINTEL_TORCH_VERSION=2.13.0 ARG GEOINTEL_TORCHVISION_VERSION=0.28.0 ENV GEOINTEL_ENV=production \ GEOINTEL_API_PREFIX=/api/v1 \ GEOINTEL_STORAGE_ROOT=/app/storage \ STORAGE_ROOT=/app/storage \ GEOINTEL_ALL_IN_ONE=1 \ PATH="/opt/geointel/venv/bin:${PATH}" RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ curl \ gdal-bin \ libgl1 \ libglib2.0-0 \ libgdal-dev \ libgeos-dev \ libpq-dev \ libproj-dev \ libsm6 \ libx11-6 \ libxcb1 \ libxext6 \ libxrender1 \ nginx \ postgresql-16-postgis-3 \ postgresql-16-postgis-3-scripts \ proj-bin \ python3-dev \ python3-venv \ && ln -sf /usr/bin/python3.11 /usr/local/bin/python3 \ && ln -sf /usr/bin/python3.11 /usr/bin/python3 \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY backend/pyproject.toml /app/ COPY backend/app/__init__.py /app/app/__init__.py RUN printf '# GeoIntel backend package metadata\n' > /app/README.md \ && /usr/bin/python3.11 -m venv /opt/geointel/venv \ && pip install --no-cache-dir --upgrade pip setuptools \ && if [ "$GEOINTEL_INSTALL_AI" = "true" ]; then \ pip install --no-cache-dir \ --index-url "$GEOINTEL_TORCH_INDEX_URL" \ "torch==$GEOINTEL_TORCH_VERSION" \ "torchvision==$GEOINTEL_TORCHVISION_VERSION"; \ fi \ && extras=".[gis]" \ && if [ "$GEOINTEL_INSTALL_AI" = "true" ]; then extras=".[gis,ai]"; fi \ && pip install --no-cache-dir "$extras" COPY backend/ /app/ COPY fixtures/ /app/fixtures/ RUN python scripts/gis_import_smoke.py \ && python scripts/yolo_preflight.py --json >/tmp/geointel-yolo-preflight.json \ && rm -f /etc/nginx/sites-enabled/default \ && mkdir -p /app/storage /run/nginx /var/log/nginx COPY scripts/prepare_operator_real_data_samples.py /app/scripts/prepare_operator_real_data_samples.py COPY scripts/provision_mol_municipality_workspace.py /app/scripts/provision_mol_municipality_workspace.py COPY scripts/provision_mol_context_layers.py /app/scripts/provision_mol_context_layers.py COPY scripts/provision_mol_dhmv.py /app/scripts/provision_mol_dhmv.py COPY scripts/provision_regional_dhmv.py /app/scripts/provision_regional_dhmv.py COPY scripts/provision_mol_flood_hazards.py /app/scripts/provision_mol_flood_hazards.py COPY scripts/provision_regional_flood_hazards.py /app/scripts/provision_regional_flood_hazards.py COPY scripts/provision_thematic_rasters.py /app/scripts/provision_thematic_rasters.py COPY scripts/provision_mol_soil_map.py /app/scripts/provision_mol_soil_map.py COPY scripts/provision_regional_soil_map.py /app/scripts/provision_regional_soil_map.py COPY scripts/provision_mol_population_history.py /app/scripts/provision_mol_population_history.py COPY scripts/statbel_population_preflight.py /app/scripts/statbel_population_preflight.py COPY scripts/manage_statbel_population_release.py /app/scripts/manage_statbel_population_release.py COPY scripts/provision_mol_historical_landuse.py /app/scripts/provision_mol_historical_landuse.py COPY scripts/provision_regional_historical_landuse.py /app/scripts/provision_regional_historical_landuse.py COPY scripts/provision_official_landuse_timeseries.py /app/scripts/provision_official_landuse_timeseries.py COPY scripts/provision_waterinfo_station_history.py /app/scripts/provision_waterinfo_station_history.py COPY scripts/provision_mol_bwk_natura2000.py /app/scripts/provision_mol_bwk_natura2000.py COPY scripts/provision_regional_bwk_natura2000.py /app/scripts/provision_regional_bwk_natura2000.py COPY scripts/provision_agricultural_parcel_history.py /app/scripts/provision_agricultural_parcel_history.py COPY scripts/manage_alz_agriculture_release.py /app/scripts/manage_alz_agriculture_release.py COPY scripts/provision_buildings_addresses_register.py /app/scripts/provision_buildings_addresses_register.py COPY scripts/provision_regional_timeseries.py /app/scripts/provision_regional_timeseries.py COPY scripts/geographic_scopes.py /app/scripts/geographic_scopes.py COPY scripts/provision_geographic_scope.py /app/scripts/provision_geographic_scope.py COPY scripts/provision_regional_grb_buildings.py /app/scripts/provision_regional_grb_buildings.py COPY scripts/provision_regional_grb_context.py /app/scripts/provision_regional_grb_context.py COPY scripts/audit_source_freshness.py /app/scripts/audit_source_freshness.py COPY scripts/manage_grb_refresh.py /app/scripts/manage_grb_refresh.py COPY scripts/export_operator_yolo_tile_dataset.py /app/scripts/export_operator_yolo_tile_dataset.py COPY scripts/audit_operator_yolo_dataset_quality.py /app/scripts/audit_operator_yolo_dataset_quality.py COPY scripts/render_operator_yolo_label_qa_contact_sheets.py /app/scripts/render_operator_yolo_label_qa_contact_sheets.py COPY scripts/train_operator_yolo_detector.sh /app/scripts/train_operator_yolo_detector.sh COPY scripts/verify_real_data_detection_qa_workflow.sh /app/scripts/verify_real_data_detection_qa_workflow.sh COPY scripts/run_detection_quality_matrix.sh /app/scripts/run_detection_quality_matrix.sh COPY scripts/run_multi_sample_detection_quality_matrix.sh /app/scripts/run_multi_sample_detection_quality_matrix.sh COPY scripts/run_mol_operational_validation.sh /app/scripts/run_mol_operational_validation.sh COPY scripts/export_detection_calibration_evidence.sh /app/scripts/export_detection_calibration_evidence.sh COPY scripts/assemble_detection_calibration_evidence_portfolio.sh /app/scripts/assemble_detection_calibration_evidence_portfolio.sh COPY scripts/build_fixed_threshold_evidence_portfolio_inputs.py /app/scripts/build_fixed_threshold_evidence_portfolio_inputs.py COPY scripts/audit_detection_false_negative_evidence.py /app/scripts/audit_detection_false_negative_evidence.py COPY scripts/audit_detection_false_positive_evidence.py /app/scripts/audit_detection_false_positive_evidence.py COPY scripts/render_detection_false_positive_review_contact_sheets.py /app/scripts/render_detection_false_positive_review_contact_sheets.py COPY scripts/render_detection_false_negative_review_contact_sheets.py /app/scripts/render_detection_false_negative_review_contact_sheets.py COPY scripts/validate_detection_false_positive_review_decisions.py /app/scripts/validate_detection_false_positive_review_decisions.py COPY scripts/validate_detection_false_negative_review_decisions.py /app/scripts/validate_detection_false_negative_review_decisions.py COPY scripts/run_operator_hard_negative_detection_matrix.sh /app/scripts/run_operator_hard_negative_detection_matrix.sh COPY scripts/run_background_corpus_split_matrix.sh /app/scripts/run_background_corpus_split_matrix.sh COPY scripts/build_background_corpus_split_report.py /app/scripts/build_background_corpus_split_report.py COPY scripts/build_detection_model_promotion_report.py /app/scripts/build_detection_model_promotion_report.py COPY scripts/build_mol_operational_benchmark_report.py /app/scripts/build_mol_operational_benchmark_report.py COPY scripts/run_split_background_promotion_workflow.sh /app/scripts/run_split_background_promotion_workflow.sh COPY scripts/activate_promoted_yolo_candidate.py /app/scripts/activate_promoted_yolo_candidate.py COPY deploy/unraid/nginx-all-in-one.conf /etc/nginx/conf.d/default.conf COPY deploy/unraid/all-in-one-start.sh /usr/local/bin/geointel-all-in-one-start COPY --from=frontend-build /frontend/dist/ /usr/share/nginx/html/ RUN chmod +x /usr/local/bin/geointel-all-in-one-start \ && chmod +x \ /app/scripts/train_operator_yolo_detector.sh \ /app/scripts/verify_real_data_detection_qa_workflow.sh \ /app/scripts/run_detection_quality_matrix.sh \ /app/scripts/run_multi_sample_detection_quality_matrix.sh \ /app/scripts/run_mol_operational_validation.sh \ /app/scripts/export_detection_calibration_evidence.sh \ /app/scripts/assemble_detection_calibration_evidence_portfolio.sh \ /app/scripts/run_operator_hard_negative_detection_matrix.sh \ /app/scripts/run_background_corpus_split_matrix.sh \ /app/scripts/run_split_background_promotion_workflow.sh VOLUME ["/var/lib/postgresql/data", "/app/storage"] EXPOSE 80 HEALTHCHECK --interval=30s --timeout=5s --retries=10 --start-period=60s \ CMD curl -fsS http://127.0.0.1/health >/dev/null || exit 1 CMD ["/usr/local/bin/geointel-all-in-one-start"]