diff --git a/.github/workflows/pr-check.yaml b/.github/workflows/pr-check.yaml index e742487..474315f 100644 --- a/.github/workflows/pr-check.yaml +++ b/.github/workflows/pr-check.yaml @@ -10,6 +10,7 @@ on: - '.dockerignore' - '.github/workflows/**' - 'pyproject.toml' + - 'Dockerfile' permissions: contents: read diff --git a/Dockerfile b/Dockerfile index 89d5e92..c7faed0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,22 @@ -FROM ubuntu:latest - -RUN apt-get update && apt-get install -y --no-install-recommends git curl ca-certificates r-base build-essential libxml2 libxml2-dev libfontconfig1-dev libtiff-dev libcurl4-openssl-dev libsodium-dev python3.12 python3.12-venv python3-pip +FROM ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + git \ + curl \ + ca-certificates \ + r-base \ + build-essential \ + libxml2-dev \ + libfontconfig1-dev \ + libtiff-dev \ + libcurl4-openssl-dev \ + libsodium-dev \ + python3 \ + python3-venv \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* WORKDIR /server @@ -11,6 +27,7 @@ ENV PATH="/root/.local/bin/:$PATH" # Install R dependencies RUN R -e "install.packages('renv', repos = c(CRAN = 'https://cloud.r-project.org'))" + COPY renv.lock renv.lock RUN mkdir -p renv COPY .Rprofile .Rprofile @@ -18,20 +35,17 @@ COPY renv/activate.R renv/activate.R COPY renv/settings.json renv/settings.json RUN R -e "renv::restore()" -# Install python dependencies +# Python deps COPY pyproject.toml uv.lock ./ RUN uv venv .venv RUN uv sync --frozen --no-install-project -# Copy project files +# Copy project COPY . . -# Install the app +# Install app RUN uv pip install -e . -# Expose port EXPOSE 80 -# Start the server -CMD uv run hydroshift/add_analytics.py && uv run streamlit run hydroshift/streamlit_app.py \ - --server.port=80 --server.address=0.0.0.0 --server.headless=true +CMD ["bash", "-c", "uv run hydroshift/add_analytics.py && uv run streamlit run hydroshift/streamlit_app.py --server.port=80 --server.address=0.0.0.0 --server.headless=true"] diff --git a/hydroshift/app_logging.py b/hydroshift/app_logging.py index 1d53665..c420275 100644 --- a/hydroshift/app_logging.py +++ b/hydroshift/app_logging.py @@ -4,6 +4,16 @@ import sys from pathlib import Path +NOISY_LOGGERS = { + "watchdog": logging.WARNING, + "PIL": logging.INFO, + "urllib3": logging.INFO, + "matplotlib": logging.WARNING, + "fiona": logging.WARNING, + "rasterio": logging.WARNING, +} +for logger_name, level in NOISY_LOGGERS.items(): + logging.getLogger(logger_name).setLevel(level) def handle_uncaught(exc_type, exc_value, exc_traceback): if issubclass(exc_type, KeyboardInterrupt): @@ -12,7 +22,7 @@ def handle_uncaught(exc_type, exc_value, exc_traceback): logging.getLogger().critical("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) -def setup_logging(log_dir: str = "logs", log_level: int = logging.INFO, log_file: str = "app.log") -> None: +def setup_logging(log_dir: str = "logs", console_level: int = logging.INFO, file_level: int = logging.DEBUG, log_file: str = "app.log") -> None: # Make dir Path(log_dir).mkdir(parents=True, exist_ok=True) log_path = Path(log_dir) / log_file @@ -23,17 +33,19 @@ def setup_logging(log_dir: str = "logs", log_level: int = logging.INFO, log_file # Establish global settings root_logger = logging.getLogger() - root_logger.setLevel(log_level) + root_logger.setLevel(logging.DEBUG) if root_logger.hasHandlers(): root_logger.handlers.clear() # Console handler console_handler = logging.StreamHandler() + console_handler.setLevel(console_level) console_handler.setFormatter(formatter) root_logger.addHandler(console_handler) # Rotating file handler file_handler = logging.handlers.RotatingFileHandler(log_path, maxBytes=int(1e7), backupCount=5, encoding="utf-8") + file_handler.setLevel(file_level) file_handler.setFormatter(formatter) root_logger.addHandler(file_handler)