diff --git a/.devcontainer/.env b/.devcontainer/.env index 0083f06..d9abf75 100644 --- a/.devcontainer/.env +++ b/.devcontainer/.env @@ -1,4 +1,5 @@ PYTHON_BASE=3.13 +DEVCONTAINER_IMAGE_REV=0.1 DEVCONTAINER_IMAGE_PULL_REPO=docker.masara.eu/python DEVCONTAINER_IMAGE_PUSH_REPO=repo.masara.eu/python -DEVCONTAINER_IMAGE_REV=0.1 + diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a186588..2a173f2 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,29 +1,29 @@ -# Používame oficiálny Python image, ale env bude podobné ako v base:ubuntu -ARG PYTHON_VERSION=3.13 -FROM python:${PYTHON_VERSION}-slim - -ENV PYTHONUNBUFFERED=1 \ - PIP_NO_CACHE_DIR=1 \ - PIP_DISABLE_PIP_VERSION_CHECK=1 - -# Základ + Docker repo + docker-ce-cli + compose plugin + git -RUN set -eux; \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - ca-certificates curl gnupg && \ - install -m 0755 -d /etc/apt/keyrings && \ - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ - chmod a+r /etc/apt/keyrings/docker.gpg && \ - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ - https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" \ - > /etc/apt/sources.list.d/docker.list && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - build-essential pkg-config \ - git \ - docker-ce-cli docker-compose-plugin docker-buildx-plugin \ - libatomic1 libstdc++6 libgcc-s1 \ - procps \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /workspace +# Používame oficiálny Python image, ale env bude podobné ako v base:ubuntu +ARG PYTHON_VERSION=3.13 +FROM python:${PYTHON_VERSION}-slim + +ENV PYTHONUNBUFFERED=1 \ + PIP_NO_CACHE_DIR=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + +# Základ + Docker repo + docker-ce-cli + compose plugin + git +RUN set -eux; \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates curl gnupg && \ + install -m 0755 -d /etc/apt/keyrings && \ + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ + chmod a+r /etc/apt/keyrings/docker.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ + https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" \ + > /etc/apt/sources.list.d/docker.list && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + build-essential pkg-config \ + git \ + docker-ce-cli docker-compose-plugin docker-buildx-plugin \ + libatomic1 libstdc++6 libgcc-s1 \ + procps \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0b494b1..9218046 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,49 +1,53 @@ -{ - "name": "Python Dev", - "dockerComposeFile": "docker-compose.yml", - "service": "dev", - "containerEnv": { - "PIP_INDEX_URL": "https://dv.masara.eu/repository/pypi-group/simple", - "PIP_ROOT_USER_ACTION": "ignore" - }, - "remoteEnv": { - "DOCKER_BUILDKIT": "1" - }, - "workspaceFolder": "/workspace", - "remoteUser": "root", - "customizations": { - "vscode": { - "extensions": [ - "ms-python.python", - "ms-python.vscode-pylance", - "ms-toolsai.jupyter", - "ms-python.black-formatter", - "ms-python.isort", - "ms-azuretools.vscode-docker" - ], - "settings": { - "python.formatting.provider": "black", - "python.analysis.extraPaths": [ - "${workspaceFolder}/app" - ], - "editor.formatOnSave": true, - "python.terminal.activateEnvironment": true, - "python.defaultInterpreterPath": ".venv/bin/python", - "remote.restoreForwardedPorts": false, - "remote.autoForwardPortsSource": "output", - "debug.javascript.autoAttachFilter": "disabled" - } - } - }, - "mounts": [ - "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" - ], - "postCreateCommand": "bash .devcontainer/post_create.sh", - "forwardPorts": [ - ], - "portsAttributes": { - "*": { - "onAutoForward": "ignore" - } - } -} +{ + "name": "Python Dev", + "containerEnv": { + "PIP_INDEX_URL": "https://dv.masara.eu/repository/pypi-group/simple", + "PIP_ROOT_USER_ACTION": "ignore" + }, + "remoteEnv": { + "DOCKER_BUILDKIT": "1", + "VIRTUAL_ENV": "/workspace/.venv", + "PATH": "/workspace/.venv/bin:${containerEnv:PATH}" + }, + "workspaceFolder": "/workspace", + "remoteUser": "root", + "overrideCommand": true, + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-toolsai.jupyter", + "ms-python.black-formatter", + "ms-python.isort", + "ms-azuretools.vscode-docker", + "openai.chatgpt" + ], + "settings": { + "python.formatting.provider": "black", + "python.analysis.extraPaths": [ + "${workspaceFolder}/app" + ], + "editor.formatOnSave": true, + "python.terminal.activateEnvironment": true, + "python.defaultInterpreterPath": ".venv/bin/python", + "remote.restoreForwardedPorts": false, + "remote.autoForwardPortsSource": "output", + "debug.javascript.autoAttachFilter": "disabled" + } + } + }, + "mounts": [ + "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock", + "type=bind,source=${localEnv:USERPROFILE}/.codex,target=/root/.codex" + ], + "postCreateCommand": "bash .devcontainer/post_create.sh", + "forwardPorts": [], + "portsAttributes": { + "*": { + "onAutoForward": "ignore" + } + }, + "image": "docker.masara.eu/python:3.13-0.1-devcontainer", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached" +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index d359b99..50e46ec 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -1,9 +1,11 @@ -services: +services: dev: image: ${DEVCONTAINER_IMAGE_PULL_REPO}:${PYTHON_BASE}-${DEVCONTAINER_IMAGE_REV}-devcontainer pull_policy: always init: true + command: sleep infinity + tty: true volumes: - ..:/workspace:cached environment: - PYTHON_BASE: ${PYTHON_BASE} + PYTHON_BASE: ${PYTHON_BASE} diff --git a/.devcontainer/post_create.sh b/.devcontainer/post_create.sh index de96a24..ffa6d69 100644 --- a/.devcontainer/post_create.sh +++ b/.devcontainer/post_create.sh @@ -7,24 +7,29 @@ VENV_PATH="/workspace/.venv" if [ ! -d "$VENV_PATH" ]; then echo "Virtuálne prostredie neexistuje – vytváram..." python -m venv "$VENV_PATH" - - echo "Aktivujem virtuálne prostredie..." - # shellcheck disable=SC1090 - source "$VENV_PATH/bin/activate" - - echo "Aktualizujem pip a základné nástroje..." - pip install --upgrade pip setuptools wheel else echo "Používam existujúce virtuálne prostredie..." - # shellcheck disable=SC1090 - # source "$VENV_PATH/bin/activate" fi +echo "Aktivujem virtuálne prostredie..." +# shellcheck disable=SC1090 +source "$VENV_PATH/bin/activate" + +echo "Aktualizujem pip a základné nástroje..." +python -m pip install --upgrade pip setuptools wheel + # Inštalácia závislostí, ak existuje requirements.txt if [ -f "/workspace/requirements.txt" ]; then echo "Inštalujem závislosti z requirements.txt..." - pip install -r /workspace/requirements.txt + python -m pip install -r /workspace/requirements.txt else echo "requirements.txt nenájdený – preskakujem inštaláciu závislostí." fi +# Ak sa terminál otvorí skôr, než Python extension stihne auto-aktiváciu, +# zabezpečíme aktiváciu aj cez shell init. +BASHRC="/root/.bashrc" +ACTIVATE_LINE='[ -f /workspace/.venv/bin/activate ] && source /workspace/.venv/bin/activate' +if ! grep -Fq "$ACTIVATE_LINE" "$BASHRC"; then + echo "$ACTIVATE_LINE" >> "$BASHRC" +fi diff --git a/.dockerignore b/.dockerignore index 0ce478c..3de2c41 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,16 +1,16 @@ - -__pycache__ -*.pyc -*.pyo -*.pyd -*.db -*.sqlite3 -.env -*.log -.git -.gitignore -.vscode -.venv -venv -rest -docker + +__pycache__ +*.pyc +*.pyo +*.pyd +*.db +*.sqlite3 +.env +*.log +.git +.gitignore +.vscode +.venv +venv +rest +docker diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 5773c64..9889460 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -27,4 +27,4 @@ "problemMatcher": [] } ] -} +} diff --git a/Dockerfile b/Dockerfile index 16e791f..344e20d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,32 @@ -# syntax=docker/dockerfile:1.6 - -ARG PYTHON_BASE=3.13 -FROM python:${PYTHON_BASE}-slim - -ENV PYTHONDONTWRITEBYTECODE=1 \ - PYTHONUNBUFFERED=1 \ - PIP_NO_CACHE_DIR=1 \ - PIP_DISABLE_PIP_VERSION_CHECK=1 \ - PIP_INDEX_URL=https://dv.masara.eu/repository/pypi-group/simple \ - PIP_NO_INPUT=1 - -WORKDIR /app - -# Inštalácia závislostí -COPY requirements.txt . -RUN --mount=type=cache,target=/root/.cache/pip \ - pip install -r requirements.txt - -# Kopírovanie zdrojov -COPY app/ /app/ - -# Vytvorenie ne-root usera -ARG APP_USER_ID=1000 -RUN useradd -u ${APP_USER_ID} -m appuser && \ - chown -R appuser:appuser /app - -USER appuser - -# Príklad spustenia -# EXPOSE 8080 -# CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"] +# syntax=docker/dockerfile:1.6 + +ARG PYTHON_BASE=3.13 +FROM python:${PYTHON_BASE}-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PIP_NO_CACHE_DIR=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 \ + PIP_INDEX_URL=https://dv.masara.eu/repository/pypi-group/simple \ + PIP_NO_INPUT=1 + +WORKDIR /app + +# Inštalácia závislostí +COPY requirements.txt . +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install -r requirements.txt + +# Kopírovanie zdrojov +COPY app/ /app/ + +# Vytvorenie ne-root usera +ARG APP_USER_ID=1000 +RUN useradd -u ${APP_USER_ID} -m appuser && \ + chown -R appuser:appuser /app + +USER appuser + +# Príklad spustenia +# EXPOSE 8080 +# CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"] diff --git a/app/main.py b/app/main.py index 7ccb890..5122182 100644 --- a/app/main.py +++ b/app/main.py @@ -1,2 +1,2 @@ -# hello_world.py +# hello_world.py print("Hello, world!") \ No newline at end of file diff --git a/scripts/publish-devcontainer-image.ps1 b/scripts/publish-devcontainer-image.ps1 index 96d5540..f14b14a 100644 --- a/scripts/publish-devcontainer-image.ps1 +++ b/scripts/publish-devcontainer-image.ps1 @@ -71,4 +71,4 @@ if ($LASTEXITCODE -ne 0) { if ($Push) { Invoke-DockerPushWithLoginFallback -Tag $versionTag -Registry $registry Invoke-DockerPushWithLoginFallback -Tag $channelTag -Registry $registry -} +}