This is an automated email from the ASF dual-hosted git repository.

asorokoumov pushed a commit to branch slim-dockerfile
in repository https://gitbox.apache.org/repos/asf/otava.git

commit 5d51fc659c378e5657277c3a8046deec95dcdcab
Author: Alex Sorokoumov <[email protected]>
AuthorDate: Mon Sep 1 12:22:50 2025 -0700

    Reduce Docker image size
    
    ```
    $ uv run tox -e docker-build
    ```
    
    Without this PR:
    
    ```
    $ docker image ls | grep apache/otava
    apache/otava                    latest              2b43a1b28f21   5 
seconds ago   1.8GB
    ```
    
    With this PR:
    
    ```
    $ docker image ls | grep apache/otava
    apache/otava                    latest              fe6ae40666a2   13 
seconds ago       778MB
    ```
---
 Dockerfile                              | 49 ++++++++++++-----
 docs/CSV.md                             |  2 +-
 examples/csv/docker-compose.yaml        |  3 +-
 examples/csv/otava.yaml                 | 27 ----------
 examples/graphite/docker-compose.yaml   | 11 ++--
 examples/graphite/otava.yaml            | 48 -----------------
 examples/postgresql/docker-compose.yaml |  7 ++-
 examples/postgresql/otava.yaml          | 94 ---------------------------------
 8 files changed, 45 insertions(+), 196 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 4af06ac..c198394 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,30 @@
 # specific language governing permissions and limitations
 # under the License.
 
-FROM python:3.8-slim-bookworm
+# Builder stage - build the wheel
+FROM ghcr.io/astral-sh/uv:debian AS builder
+
+# Install build dependencies
+RUN apt-get update --assume-yes && \
+    apt-get install -o 'Dpkg::Options::=--force-confnew' -y --force-yes -q \
+    gcc \
+    clang \
+    build-essential \
+    make \
+    && rm -rf /var/lib/apt/lists/*
+
+# Set working directory
+WORKDIR /build
+
+# Copy source code
+COPY . /build
+
+# Build the wheel using uv
+RUN uv build --wheel
+
+# Runtime stage - install and run the package
+FROM python:3.10-slim-bookworm AS runtime
+
 # So that STDOUT/STDERR is printed
 ENV PYTHONUNBUFFERED="1"
 ARG UV_VERSION=0.8.3
@@ -29,24 +52,22 @@ RUN groupadd --gid 8192 otava && \
     useradd --uid 8192 --shell /bin/false --create-home --no-log-init --gid 
otava otava && \
     chown otava:otava ${OTAVA_HOME}
 
-# First let's just get things updated.
-# Install System dependencies
+
+# Install build dependencies needed for native extensions
 RUN apt-get update --assume-yes && \
     apt-get install -o 'Dpkg::Options::=--force-confnew' -y --force-yes -q \
-    git \
-    openssh-client \
     gcc \
-    clang \
     build-essential \
-    make \
     && rm -rf /var/lib/apt/lists/*
 
-# Copy the rest of the program over
-COPY --chown=otava:otava . ${OTAVA_HOME}
+# Copy the wheel from builder stage
+COPY --from=builder /build/dist/*.whl /tmp/
+
+# Install the wheel using uv
+RUN pip install /tmp/apache_otava-*.whl && rm /tmp/apache_otava-*.whl
 
-ENV PATH="${OTAVA_HOME}/bin:$PATH"
+# Switch to otava user
+USER otava
 
-RUN --mount=from=ghcr.io/astral-sh/uv,source=/uv,target=/bin/uv 
--mount=type=ssh \
-    uv pip install --system -e ".[dev]" && \
-    mkdir -p bin && \
-    ln -s ../venv/bin/otava ${OTAVA_HOME}/bin
+# The otava command should now be available in PATH via the installed package
+ENTRYPOINT ["otava"]
diff --git a/docs/CSV.md b/docs/CSV.md
index 30305dc..8eb65b7 100644
--- a/docs/CSV.md
+++ b/docs/CSV.md
@@ -40,7 +40,7 @@ tests:
 ## Example
 
 ```bash
-docker-compose -f examples/csv/docker-compose.yaml run --build otava bin/otava 
analyze local.sample
+docker-compose -f examples/csv/docker-compose.yaml run --build otava analyze 
local.sample
 ```
 
 Expected output:
diff --git a/examples/csv/docker-compose.yaml b/examples/csv/docker-compose.yaml
index a1e5f36..f3abcd3 100644
--- a/examples/csv/docker-compose.yaml
+++ b/examples/csv/docker-compose.yaml
@@ -22,6 +22,7 @@ services:
       dockerfile: Dockerfile
     container_name: otava
     environment:
-      OTAVA_CONFIG: examples/csv/otava.yaml
+      OTAVA_CONFIG: /config/otava.yaml
     volumes:
       - ./data:/data
+      - ./config:/config
diff --git a/examples/csv/otava.yaml b/examples/csv/otava.yaml
deleted file mode 100644
index d91f4ea..0000000
--- a/examples/csv/otava.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-tests:
-  local.sample:
-    type: csv
-    file: /data/local_sample.csv
-    time_column: time
-    attributes: [commit]
-    metrics: [metric1, metric2]
-    csv_options:
-      delimiter: ","
-      quotechar: "'"
diff --git a/examples/graphite/docker-compose.yaml 
b/examples/graphite/docker-compose.yaml
index a784ea1..06b0ec7 100644
--- a/examples/graphite/docker-compose.yaml
+++ b/examples/graphite/docker-compose.yaml
@@ -38,7 +38,7 @@ services:
     ports:
       - "3000:3000"
     volumes:
-        - ./grafana:/etc/grafana/provisioning
+      - ./grafana:/etc/grafana/provisioning
     networks:
       - otava-graphite
 
@@ -65,15 +65,12 @@ services:
       GRAFANA_ADDRESS: http://grafana:3000/
       GRAFANA_USER: admin
       GRAFANA_PASSWORD: admin
-      OTAVA_CONFIG: examples/graphite/otava.yaml
+      OTAVA_CONFIG: /config/otava.yaml
     networks:
       - otava-graphite
+    volumes:
+      - ./config:/config
 
 networks:
   otava-graphite:
     driver: bridge
-
-
-# TODO:
-# 3. make sure Otava can connect to graphite and query the data
-# 4. make sure it annotates the dashboard correctly
\ No newline at end of file
diff --git a/examples/graphite/otava.yaml b/examples/graphite/otava.yaml
deleted file mode 100644
index 09e07f9..0000000
--- a/examples/graphite/otava.yaml
+++ /dev/null
@@ -1,48 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# External systems connectors configuration:
-graphite:
-  url: ${GRAPHITE_ADDRESS}
-
-grafana:
-  url: ${GRAFANA_ADDRESS}
-  user: ${GRAFANA_USER}
-  password: ${GRAFANA_PASSWORD}
-
-# Define your tests here:
-tests:
-  my-product.test:
-    type: graphite
-    prefix: performance-tests.daily.my-product
-    tags: [perf-test, daily, my-product]
-    metrics:
-      throughput:
-        suffix: client.throughput
-        direction: 1   # higher is better
-        scale: 1
-      response_time:
-        suffix: client.p50
-        direction: -1  # lower is better
-        scale: 1
-      cpu_usage:
-        suffix: server.cpu
-        direction: -1  # lower is better
-        scale: 1
-
-
-
diff --git a/examples/postgresql/docker-compose.yaml 
b/examples/postgresql/docker-compose.yaml
index f4829da..151879e 100644
--- a/examples/postgresql/docker-compose.yaml
+++ b/examples/postgresql/docker-compose.yaml
@@ -14,9 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-
-version: "3.8"
-
 services:
   postgres:
     image: postgres:latest
@@ -45,10 +42,12 @@ services:
       POSTGRES_USERNAME: exampleuser
       POSTGRES_PASSWORD: examplepassword
       POSTGRES_DATABASE: benchmark_results
-      OTAVA_CONFIG: examples/postgresql/otava.yaml
+      OTAVA_CONFIG: /config/otava.yaml
       BRANCH: trunk
     networks:
       - otava-postgres
+    volumes:
+      - ./config:/config
 
 networks:
   otava-postgres:
diff --git a/examples/postgresql/otava.yaml b/examples/postgresql/otava.yaml
deleted file mode 100644
index bb52c15..0000000
--- a/examples/postgresql/otava.yaml
+++ /dev/null
@@ -1,94 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# External systems connectors configuration:
-postgres:
-  hostname: ${POSTGRES_HOSTNAME}
-  port: ${POSTGRES_PORT}
-  username: ${POSTGRES_USERNAME}
-  password: ${POSTGRES_PASSWORD}
-  database: ${POSTGRES_DATABASE}
-
-# Templates define common bits shared between test definitions:
-templates:
-  common:
-    type: postgres
-    time_column: commit_ts
-    attributes: [experiment_id, commit, config_id]
-    # required for --update-postgres to work
-    update_statement: |
-      UPDATE results 
-        SET {metric}_rel_forward_change=%s, 
-            {metric}_rel_backward_change=%s, 
-            {metric}_p_value=%s
-      WHERE experiment_id = '{experiment_id}' AND config_id = {config_id}
-    metrics:
-      process_cumulative_rate_mean:
-        direction: 1
-        scale: 1
-      process_cumulative_rate_stderr:
-        direction: -1
-        scale: 1
-      process_cumulative_rate_diff:
-        direction: -1
-        scale: 1
-
-# Define your tests here:
-tests:
-  aggregate_mem:
-    inherit: [ common ] # avoids repeating metrics definitions and 
postgres-related config
-    query: |
-      SELECT e.commit, 
-             e.commit_ts, 
-             r.process_cumulative_rate_mean, 
-             r.process_cumulative_rate_stderr, 
-             r.process_cumulative_rate_diff, 
-             r.experiment_id,
-             r.config_id
-      FROM results r
-      INNER JOIN configs c ON r.config_id = c.id
-      INNER JOIN experiments e ON r.experiment_id = e.id
-      WHERE e.exclude_from_analysis = false AND
-            e.branch = '${BRANCH}' AND
-            e.username = 'ci' AND
-            c.store = 'MEM' AND
-            c.cache = true AND
-            c.benchmark = 'aggregate' AND
-            c.instance_type = 'ec2i3.large'
-      ORDER BY e.commit_ts ASC;
-
-  aggregate_time_rocks:
-    inherit: [ common ]
-    query: |
-      SELECT e.commit, 
-             e.commit_ts, 
-             r.process_cumulative_rate_mean, 
-             r.process_cumulative_rate_stderr, 
-             r.process_cumulative_rate_diff,  
-             r.experiment_id,
-             r.config_id
-      FROM results r
-      INNER JOIN configs c ON r.config_id = c.id
-      INNER JOIN experiments e ON r.experiment_id = e.id
-      WHERE e.exclude_from_analysis = false AND
-            e.branch = '${BRANCH}' AND
-            e.username = 'ci' AND
-            c.store = 'TIME_ROCKS' AND
-            c.cache = true AND
-            c.benchmark = 'aggregate' AND
-            c.instance_type = 'ec2i3.large'
-      ORDER BY e.commit_ts ASC;
\ No newline at end of file

Reply via email to