159 lines
4.8 KiB
Bash
159 lines
4.8 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
echo "manage through mise-en-place"
|
|
exit 1
|
|
|
|
# # 1. Install `uv`
|
|
# a development environment setup tool.
|
|
sudo apt update -qq && sudo apt install -y curl
|
|
|
|
# sudo install -dm 755 /etc/apt/keyrings
|
|
DEST=${1:-/etc/skel}
|
|
URI="https://debian.griffo.io"
|
|
KEY_DIR="/usr/share/keyrings"
|
|
KEY="${KEY_DIR}/debian.griffo.io-archive-keyring.gpg"
|
|
UV_HOME="${DEST}/.config/uv"
|
|
UV_CONFIG_DIR="${UV_HOME}/conf.d"
|
|
|
|
# Add the GPG key
|
|
curl -fsS ${URI}/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o ${KEY} 1>/dev/null
|
|
|
|
# Add the repository
|
|
# echo "deb https://debian.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/debian.griffo.io.list
|
|
conf_print_uv_sources() {
|
|
cat <<EOF
|
|
Types: deb
|
|
URIs: ${URI}/deb/
|
|
Suites: stable
|
|
Components: main
|
|
Signed-By: ${KEY}
|
|
EOF
|
|
}
|
|
conf_print_uv_sources | sudo tee /etc/apt/sources.list-available/debian.griffo.io_uv.sources
|
|
sudo ln -sf /etc/apt/sources.list-available/debian.griffo.io_uv.sources /etc/apt/sources.list.d/debian.griffo.io_uv.sources
|
|
|
|
sudo apt update
|
|
sudo apt install uv
|
|
|
|
## 1. The `uv.toml` (Project Level)
|
|
# This file tells `uv` how to behave. For Docker, the most important settings are disabling automatic Python downloads (to use the image's Python) and using `copy` mode for links (since hardlinks often fail across Docker layers).
|
|
conf_print_uv_toml() {
|
|
cat <<EOF
|
|
# uv.toml
|
|
|
|
# Use 'copy' instead of 'hardlink' to avoid issues with Docker layer filesystems
|
|
link-mode = "copy"
|
|
|
|
# In Docker/CI, we want to fail if the lockfile is out of sync
|
|
frozen = true
|
|
|
|
# Optimization: Compile Python files to bytecode immediately
|
|
compile-bytecode = true
|
|
|
|
[pip]
|
|
# Ensures we always use the same index
|
|
index-url = "https://pypi.org/simple"
|
|
EOF
|
|
}
|
|
conf_print_uv_toml | sudo tee "${UV_HOME}/uv.toml"
|
|
|
|
#---
|
|
|
|
# To integrate **uv**, **mise**, and **Docker**
|
|
|
|
# Below is a setup that uses
|
|
# * `uv.toml` (and
|
|
# * `pyproject.toml`) to manage Python,
|
|
# * `mise.toml` to manage the environment,
|
|
# and a multi-stage `Dockerfile` optimized for build speed.
|
|
|
|
# ---
|
|
|
|
## 2. The `mise.toml` (Local Development)
|
|
|
|
# Mise can automatically manage your `uv` installation and
|
|
# point `uv` to the correct Python version managed by mise.
|
|
#
|
|
# # mise.toml
|
|
# [tools]
|
|
# python = "3.12" # Mise manages the Python version
|
|
# uv = "latest" # Mise ensures uv is installed
|
|
#
|
|
# [env]
|
|
# # Tell uv to use the Python executable managed by mise
|
|
# UV_PYTHON = "{{ tools.python.path }}"
|
|
#
|
|
# # Automatically create/sync the virtualenv when you enter the directory
|
|
# _.python.venv = { path = ".venv", create = true }
|
|
#
|
|
#
|
|
# ---
|
|
|
|
## 3. The `Dockerfile` (Optimized)
|
|
|
|
# This `Dockerfile` uses a **multi-stage build**. It uses `uv` to build a virtual environment in the `builder` stage, then copies only the environment to the `final` stage. This keeps your production image tiny and secure.
|
|
#
|
|
# ```dockerfile
|
|
# # --- Stage 1: Builder ---
|
|
# FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
|
|
#
|
|
# # Enable bytecode compilation for faster startup
|
|
# ENV UV_COMPILE_BYTECODE=1
|
|
# # Use copy mode for layers
|
|
# ENV UV_LINK_MODE=copy
|
|
#
|
|
# WORKDIR /app
|
|
#
|
|
# # 1. Install dependencies only (Cache Layer)
|
|
# # We bind the lockfile and pyproject to avoid unnecessary copies
|
|
# RUN --mount=type=cache,target=/root/.cache/uv \
|
|
# --mount=type=bind,source=uv.lock,target=uv.lock \
|
|
# --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
|
# uv sync --frozen --no-install-project --no-dev
|
|
#
|
|
# # 2. Copy source code and install the project
|
|
# ADD . /app
|
|
# RUN --mount=type=cache,target=/root/.cache/uv \
|
|
# uv sync --frozen --no-dev
|
|
#
|
|
#
|
|
# # --- Stage 2: Final Runtime ---
|
|
# FROM python:3.12-slim-bookworm
|
|
#
|
|
# WORKDIR /app
|
|
#
|
|
# # Copy the virtual environment from the builder
|
|
# COPY --from=builder /app/.venv /app/.venv
|
|
#
|
|
# # Put the venv at the front of the PATH
|
|
# ENV PATH="/app/.venv/bin:$PATH"
|
|
#
|
|
# # Copy only necessary application files
|
|
# COPY ./src ./src
|
|
#
|
|
# # Run as non-root user for security
|
|
# RUN useradd -m appuser
|
|
# USER appuser
|
|
#
|
|
# CMD ["python", "src/main.py"]
|
|
#
|
|
# ```
|
|
|
|
#---
|
|
#
|
|
# ### Why this works:
|
|
#
|
|
# * **Mise Integration:** Local development is seamless. When you `cd` into the
|
|
# folder, mise ensures Python and `uv` are ready. The `UV_PYTHON` env var ensures
|
|
# `uv` doesn't try to download its own Python version, preventing "version drift."
|
|
# * **Docker Layer Caching:** By using `--mount=type=bind` for `uv.lock`, the
|
|
# heavy dependency installation only re-runs if your requirements change, not when
|
|
# your code changes.
|
|
# * **Performance:** `UV_COMPILE_BYTECODE=1` makes your container start up faster
|
|
# by pre-compiling `.pyc` files.
|
|
# * **Size:** The final image doesn't contain `uv`, `gcc`, or any build tools—just
|
|
# your code and the pre-installed packages in the `.venv`.
|
|
#
|
|
# **Would you like me to generate a `.dockerignore` file to ensure your local
|
|
# `.venv` or `.mise` folders don't bloat your build context?**
|