Skip to content

Commit

Permalink
fix: docker dev build corrections (#195)
Browse files Browse the repository at this point in the history
Corrects additional Docker build issues introduced during the move to `uv`.

To run the full docker stack in devolpment:

`docker compose up --build --force-recreate`

To run build and run the image for production, use:

`docker compose -f docker-compose.yml up --build --force-recreate`
  • Loading branch information
cofin authored Jan 17, 2025
1 parent e9c9f79 commit 795592a
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 114 deletions.
4 changes: 1 addition & 3 deletions .env.docker.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
SECRET_KEY='secret-key'
LITESTAR_DEBUG=true
LITESTAR_HOST=0.0.0.0
LITESTAR_PORT=8080
LITESTAR_PORT=8000
APP_URL=http://localhost:${LITESTAR_PORT}

LOG_LEVEL=20
Expand All @@ -25,6 +25,4 @@ SAQ_CONCURRENCY=1

VITE_HOST=localhost
VITE_PORT=3006
VITE_HOT_RELOAD=True
VITE_DEV_MODE=False
ALLOWED_CORS_ORIGINS=["localhost:3006","localhost:8080","localhost:8000"]
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repos:
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.9.1
rev: v0.9.2
hooks:
- id: ruff
args:
Expand Down
77 changes: 38 additions & 39 deletions deploy/docker/dev/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,72 +25,71 @@ RUN apt-get update \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false\
&& mkdir -p /workspace/app \
&& pip install --quiet -U pip wheel setuptools virtualenv

# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
## ---------------------------------------------------------------------------------- ##
## ------------------------- Python build base -------------------------------------- ##
## ------------------------- Python Dev Image --------------------------------------- ##
## ---------------------------------------------------------------------------------- ##
FROM python-base AS build-base
FROM python-base AS dev-image
ARG UV_INSTALL_ARGS="--all-groups"
ENV UV_INSTALL_ARGS="${UV_INSTALL_ARGS}" \
GRPC_PYTHON_BUILD_WITH_CYTHON=1 \
PATH="/workspace/app/.venv/bin:/usr/local/bin:$PATH"
## -------------------------- add build packages ----------------------------------- ##
RUN apt-get install -y --no-install-recommends build-essential curl \
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /root/.cache \
&& rm -rf /var/apt/lists/* \
&& rm -rf /var/cache/apt/* \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false

## -------------------------- install application ----------------------------------- ##
WORKDIR /workspace/app
COPY pyproject.toml uv.lock README.md .pre-commit-config.yaml LICENSE Makefile \
package.json package-lock.json vite.config.ts tsconfig.json \
tailwind.config.cjs postcss.config.cjs components.json \
./
COPY tools ./tools/
COPY public ./public/
COPY resources ./resources/
RUN python -m venv --copies /workspace/app/.venv \
&& uv sync ${UV_INSTALL_ARGS} \
&& uvx nodeenv .venv --force --quiet \
&& NODE_OPTIONS="--no-deprecation --disable-warning=ExperimentalWarning" npm install --ignore-scripts --no-fund

COPY src ./src/

## ---------------------------------------------------------------------------------- ##
## -------------------------------- development build ------------------------------- ##
## ---------------------------------------------------------------------------------- ##
## ------------------------- use builder base --------------------------------------- ##
FROM build-base AS dev-image
ARG ENV_SECRETS="runtime-secrets"
ARG LITESTAR_APP="app.asgi:create_app"
ARG VITE_USE_SERVER_LIFESPAN="false"
ARG VITE_USE_SERVER_LIFESPAN="true"
ARG VITE_DEV_MODE="true"
ARG VITE_HOT_RELOAD="true"
ARG SAQ_USE_SERVER_LIFESPAN="false"
## --------------------------- standardize execution env ----------------------------- ##
ENV PATH="/workspace/app/.venv/bin:$PATH" \
ENV PATH="/workspace/app/.venv/bin:/usr/local/bin:/opt/nodeenv/bin:$PATH" \
VIRTUAL_ENV="/workspace/app/.venv" \
ENV_SECRETS="${ENV_SECRETS}" \
VITE_USE_SERVER_LIFESPAN="${VITE_USE_SERVER_LIFESPAN}" \
VITE_DEV_MODE="${VITE_DEV_MODE}" \
VITE_HOT_RELOAD="${VITE_HOT_RELOAD}" \
SAQ_USE_SERVER_LIFESPAN="${SAQ_USE_SERVER_LIFESPAN}" \
PIP_DEFAULT_TIMEOUT=100 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_NO_CACHE_DIR=1 \
UV_LINK_MODE=copy \
UV_NO_CACHE=1 \
UV_COMPILE_BYTECODE=1 \
UV_INSTALL_ARGS="${UV_INSTALL_ARGS}" \
UV_SYSTEM_PYTHON=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONFAULTHANDLER=1 \
PYTHONHASHSEED=random \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
LITESTAR_APP="${LITESTAR_APP}"
## -------------------------- add build packages ----------------------------------- ##
RUN apt-get install -y --no-install-recommends git build-essential curl \
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /root/.cache \
&& rm -rf /var/apt/lists/* \
&& rm -rf /var/cache/apt/* \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false

## -------------------------- install application ----------------------------------- ##
WORKDIR /workspace/app
COPY pyproject.toml uv.lock README.md .pre-commit-config.yaml LICENSE Makefile \
package.json package-lock.json vite.config.ts tsconfig.json \
tailwind.config.cjs postcss.config.cjs components.json \
./
COPY tools ./tools/
RUN uvx nodeenv --quiet /opt/nodeenv/
RUN NODE_OPTIONS="--no-deprecation --disable-warning=ExperimentalWarning" npm install --ignore-scripts --no-fund
RUN uv sync ${UV_INSTALL_ARGS} --no-install-project

COPY public ./public/
COPY resources ./resources/
COPY docs/ docs/
COPY tests/ tests/
COPY src src/
RUN uv sync $UV_INSTALL_ARGS

STOPSIGNAL SIGINT
EXPOSE 8000
ENTRYPOINT ["tini","--" ]
CMD [ "litestar","run","--host","0.0.0.0"]
CMD [ "litestar","run","--host","0.0.0.0","--port","8000"]
VOLUME /workspace/app
4 changes: 2 additions & 2 deletions deploy/docker/run/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ RUN uv pip ${UV_INSTALL_ARGS} install --quiet --disable-pip-version-check /tmp/*
&& chown -R nonroot:nonroot /workspace/app
USER nonroot
STOPSIGNAL SIGINT
EXPOSE 8080
EXPOSE 8000
ENTRYPOINT ["tini","--" ]
CMD [ "app", "run", "--port","8080", "--host", "0.0.0.0"]
CMD [ "app", "run", "--port","8000", "--host", "0.0.0.0"]
VOLUME /workspace/app
2 changes: 1 addition & 1 deletion deploy/docker/run/Dockerfile.distroless
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,5 @@ COPY --from=run-base --chown=65532:65532 /workspace/app/.venv /workspace/app/.ve
STOPSIGNAL SIGINT
EXPOSE 8000
ENTRYPOINT ["tini","--" ]
CMD [ "litestar","run","--host","0.0.0.0"]
CMD [ "litestar","run","--host","0.0.0.0","--port","8000"]
VOLUME /workspace/app
4 changes: 3 additions & 1 deletion docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ services:
context: .
dockerfile: deploy/docker/dev/Dockerfile
ports:
- "8080:8080"
- "8000:8000"
- "3006:3006"
tty: true
environment:
VITE_USE_SERVER_LIFESPAN: "true" # true in dev or run
VITE_DEV_MODE: "true"
VITE_HOT_RELOAD: "true"
SAQ_USE_SERVER_LIFESPAN: "false"
command: litestar run --reload --host 0.0.0.0 --port 8000
restart: always
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ services:
cache:
condition: service_healthy
ports:
- "8080:8080"
- "8000:8000"
environment:
VITE_USE_SERVER_LIFESPAN: "false" # true if ssr or separate service
SAQ_USE_SERVER_LIFESPAN: "false"
Expand Down
38 changes: 19 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/app/domain/accounts/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ async def to_model(self, data: ModelDictT[m.Role], operation: str | None = None)

async def _populate_slug(self, data: ModelDictT[m.Role], operation: str | None) -> ModelDictT[m.Role]:
if operation == "create" and is_schema_with_field(data, "slug") and data.slug is None: # type: ignore[union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[attr-defined,union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[union-attr]
if operation == "create" and is_dict_without_field(data, "slug"):
data["slug"] = await self.repository.get_available_slug(data["name"]) # type: ignore[attr-defined ]
data["slug"] = await self.repository.get_available_slug(data["name"])
if operation == "update" and is_schema_with_field(data, "slug") and data.slug is None: # type: ignore[union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[attr-defined,union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[ union-attr]
if operation == "update" and is_dict_without_field(data, "slug") and is_dict_with_field(data, "name"):
data["slug"] = await self.repository.get_available_slug(data["name"]) # type: ignore[attr-defined ]
data["slug"] = await self.repository.get_available_slug(data["name"])
return data


Expand Down
8 changes: 4 additions & 4 deletions src/app/domain/teams/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ async def to_model(self, data: ModelDictT[m.Team], operation: str | None = None)

async def _populate_slug(self, data: ModelDictT[m.Team], operation: str | None) -> ModelDictT[m.Team]:
if operation == "create" and is_schema_with_field(data, "slug") and data.slug is None: # type: ignore[union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[attr-defined,union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[union-attr]
if operation == "create" and is_dict_without_field(data, "slug"):
data["slug"] = await self.repository.get_available_slug(data["name"]) # type: ignore[attr-defined ]
data["slug"] = await self.repository.get_available_slug(data["name"])
if operation == "update" and is_schema_with_field(data, "slug") and data.slug is None: # type: ignore[union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[attr-defined,union-attr]
data.slug = await self.repository.get_available_slug(data.name) # type: ignore[union-attr]
if operation == "update" and is_dict_without_field(data, "slug") and is_dict_with_field(data, "name"):
data["slug"] = await self.repository.get_available_slug(data["name"]) # type: ignore[attr-defined ]
data["slug"] = await self.repository.get_available_slug(data["name"])
return data

async def _populate_with_owner_and_tags(
Expand Down
Loading

0 comments on commit 795592a

Please sign in to comment.