diff --git a/docker-compose.yml b/docker-compose.yml index 548c221cdc..8dbb4419ba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,16 +1,17 @@ -services: +version: "3.9" +services: db: - image: "postgres:16" + image: postgres:16 container_name: ops-db security_opt: - - no-new-privileges:true # Resolve semgrep https://sg.run/0n8q + - no-new-privileges:true environment: - POSTGRES_PASSWORD=local_password - read_only: true # Resolve semgrep https://sg.run/e4JE + read_only: true tmpfs: /var/run/postgresql/ volumes: - - ./backend/data_tools/ops_db_sql_init:/docker-entrypoint-initdb.d + - ./backend/data_tools/ops_db_sql_init:/docker-entrypoint-initdb.d:ro ports: - "5432:5432" healthcheck: @@ -18,6 +19,7 @@ services: interval: 5s timeout: 5s retries: 5 + restart: on-failure data-import: build: @@ -29,13 +31,11 @@ services: - SQLALCHEMY_DATABASE_URI=postgresql://ops:ops@db:5432/postgres command: /bin/sh -c "./data_tools/scripts/import_test_data.sh" volumes: - # See below for an explanation of this volume. The same reasoning applies, - # but in this case it's so we can run new migrations immediately without - # having to rebuild the migration container. - ./backend/ops_api:/home/app/ops_api depends_on: db: condition: service_healthy + restart: "no" disable-users: build: @@ -51,6 +51,7 @@ services: condition: service_healthy data-import: condition: service_completed_successfully + restart: "no" backend: build: @@ -72,10 +73,11 @@ services: data-import: condition: service_completed_successfully healthcheck: - test: [ "CMD", "curl", "-f", "http://localhost:8080" ] + test: ["CMD", "curl", "-f", "http://localhost:8080"] interval: 10s timeout: 10s retries: 10 + restart: on-failure frontend: build: @@ -91,3 +93,4 @@ services: - backend volumes: - ./frontend/src:/home/app/src + restart: on-failure diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 6d11539451..f3bbd8e37f 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,19 +1,17 @@ -FROM oven/bun@sha256:5ba9a68692e9fd7aa435a79b2597f8211fbef2c6b0bed0ce9c9293c98fef5848 +# Use the official Bun image (using a tag version for consistency) +FROM oven/bun:1 AS base +WORKDIR /usr/src/app -# hadolint ignore=DL3008 -RUN apt-get update && apt-get -y --no-install-recommends install unzip && apt-get clean && rm -rf /var/lib/apt/lists/* -RUN useradd -ms /bin/bash app -USER app -WORKDIR /home/app - -COPY --chown=app:app ./package.json ./bun.lockb /home/app/ - -RUN bun install --production --frozen-lockfile - -COPY --chown=app:app index.html /home/app/ -COPY --chown=app:app src /home/app/src -COPY --chown=app:app public /home/app/public -COPY --chown=app:app vite.config.mjs /home/app/ -COPY --chown=app:app eslint.config.js /home/app/ +# Stage to install only production dependencies +FROM base AS prod-deps +RUN mkdir -p /temp/prod +COPY package.json bun.lockb /temp/prod/ +WORKDIR /temp/prod +RUN bun install --frozen-lockfile --production +# Production image – copy only production dependencies and source code (assumes your code is prebuilt) +FROM base AS release +COPY --from=prod-deps /temp/prod/node_modules ./node_modules +COPY . . +# If you have a build step that does not rely on devDependencies, run it here CMD ["bun", "start"] diff --git a/frontend/package.json b/frontend/package.json index 942729e932..6765e8672f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -82,9 +82,9 @@ "vitest": "2.1.9" }, "scripts": { - "start": "vite", - "start:debug": "vite --inspect=0.0.0.0:9229", - "build": "vite build", + "start": "bunx --bun vite", + "start:debug": "bunx --bun vite --inspect=0.0.0.0:9229", + "build": "bunx --bun vite build", "test": "vitest", "test:coverage": "vitest --coverage", "test:ui": "vitest --ui --coverage.enabled=true",