Skip to content

Commit 659f787

Browse files
authored
feat(docker): reduce image size (#363)
1 parent 07ac4e3 commit 659f787

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

.dockerignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Ignore git related files
2+
.github/
3+
.gitignore
4+
5+
# Ignore folders not necessary for the docker image
6+
docs/
7+
tests/
8+
9+
# Ignore venv if any
10+
venv/
11+
12+
# Ignore files not necessary for the docker image
13+
CONTRIBUTING.md
14+
*.png
15+
*.json
16+
LICENSE
17+
Makefile

Dockerfile

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,51 @@
11
ARG PY_VERSION=3.12
2+
3+
#---------------------------------------------------------------------------------------
4+
# Stage 1 → Builder image
5+
#---------------------------------------------------------------------------------------
26
FROM python:$PY_VERSION-slim AS build-env
37

48
ARG VERSION
5-
69
WORKDIR /app
710

811
# Install python deps
9-
RUN python -m pip install --upgrade poetry wheel twine
12+
RUN apt-get update && apt-get install -y --no-install-recommends build-essential \
13+
&& rm -rf /var/lib/apt/lists/*
14+
RUN python -m pip install --no-cache-dir --upgrade poetry wheel twine
1015

1116
# Install project deps
12-
COPY pyproject.toml .
13-
RUN poetry install --with dev
17+
COPY pyproject.toml poetry.lock ./
18+
RUN poetry install --with dev --no-root
1419

1520
# Copy code *after* installing deps to avoid unnecessarily invalidating cache
1621
COPY . .
1722

23+
# Build the project
1824
RUN poetry build
19-
RUN PROJECT_VERSION=$(poetry version -s) && cp /app/dist/boaviztapi-$PROJECT_VERSION.tar.gz ./boaviztapi-$VERSION.tar.gz
20-
RUN pip install boaviztapi-$VERSION.tar.gz && cp $(which uvicorn) /app
25+
RUN PROJECT_VERSION=$(poetry version -s) && \
26+
cp /app/dist/boaviztapi-$PROJECT_VERSION.tar.gz ./boaviztapi-$VERSION.tar.gz
2127

28+
#---------------------------------------------------------------------------------------
29+
# Stage 2 → Runtime image
30+
#---------------------------------------------------------------------------------------
2231
FROM python:$PY_VERSION-slim AS run-env
2332
# Python 3 surrogate unicode handling
2433
# @see https://click.palletsprojects.com/en/7.x/python3/
25-
ENV LC_ALL=C.UTF-8
26-
ENV LANG=C.UTF-8
27-
28-
COPY --from=build-env /app /app
29-
COPY --from=build-env /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
30-
ENV PYTHONPATH=/usr/local/lib/python3.12/site-packages
34+
ENV LC_ALL=C.UTF-8 \
35+
LANG=C.UTF-8
3136

37+
ARG VERSION
3238
WORKDIR /app
3339

40+
# Copy executable and dependencies
41+
COPY --from=build-env /app/boaviztapi-$VERSION.tar.gz /app/
42+
RUN pip install --no-cache-dir /app/boaviztapi-$VERSION.tar.gz
43+
44+
# Required in main.py
45+
COPY --from=build-env /app/pyproject.toml /usr/local/lib/python3.12/site-packages/boaviztapi/
46+
47+
# Copy uvicorn executable
48+
RUN pip install --no-cache-dir uvicorn
49+
3450
EXPOSE 5000
35-
CMD ["./uvicorn", "boaviztapi.main:app", "--host", "0.0.0.0", "--port", "5000"]
51+
CMD ["uvicorn", "boaviztapi.main:app", "--host", "0.0.0.0", "--port", "5000"]

boaviztapi/main.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,27 @@
2727

2828
from fastapi.responses import HTMLResponse
2929

30+
def get_version_from_pyproject():
31+
# List of potential locations for the pyproject.toml file
32+
potential_paths = [
33+
os.path.join(os.path.dirname(__file__), '../pyproject.toml'),
34+
os.path.join(os.path.dirname(__file__), 'pyproject.toml'),
35+
]
36+
37+
for path in potential_paths:
38+
if os.path.exists(path):
39+
with open(path, 'r') as f:
40+
return toml.loads(f.read())['tool']['poetry']['version']
41+
42+
# Raise an error if the file is not found in any of the locations
43+
raise FileNotFoundError("pyproject.toml not found in expected locations")
44+
3045
# Serverless frameworks adds a 'stage' prefix to the route used to serve applications
3146
# We have to manage it to expose openapi doc on aws and generate proper links.
3247
stage = os.environ.get('STAGE', None)
3348
openapi_prefix = f"/{stage}" if stage else "/"
3449
app = FastAPI(root_path=openapi_prefix) # Here is the magic
35-
version = toml.loads(open(os.path.join(os.path.dirname(__file__), '../pyproject.toml'), 'r').read())['tool']['poetry'][
36-
'version']
50+
version = get_version_from_pyproject()
3751
_logger = logging.getLogger(__name__)
3852

3953
origins = json.loads(os.getenv("ALLOWED_ORIGINS", '["*"]'))

0 commit comments

Comments
 (0)