mirror of
https://github.com/batonogov/learn-devops.git
synced 2025-11-29 00:33:02 +00:00
Add uv example (#30)
Co-authored-by: Fedor Batonogov <f.batonogov@yandex.ru>
This commit is contained in:
committed by
GitHub
parent
a998a1bfdb
commit
ea0d72d879
@@ -19,7 +19,7 @@ repos:
|
|||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
|
|
||||||
- repo: https://github.com/ansible-community/ansible-lint.git
|
- repo: https://github.com/ansible-community/ansible-lint.git
|
||||||
rev: v24.10.0
|
rev: v24.12.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: ansible-lint
|
- id: ansible-lint
|
||||||
exclude: ^talos/
|
exclude: ^talos/
|
||||||
@@ -31,8 +31,16 @@ repos:
|
|||||||
- id: tofu_validate
|
- id: tofu_validate
|
||||||
|
|
||||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||||
rev: v0.42.0
|
rev: v0.43.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: markdownlint
|
- id: markdownlint
|
||||||
args: ["--fix"]
|
args: [--fix]
|
||||||
files: \.md$
|
files: \.md$
|
||||||
|
|
||||||
|
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
||||||
|
rev: v2.14.0
|
||||||
|
hooks:
|
||||||
|
- id: pretty-format-yaml
|
||||||
|
args: [--autofix, --indent, '2', --offset, '2']
|
||||||
|
- id: pretty-format-toml
|
||||||
|
args: [--autofix]
|
||||||
|
|||||||
137
docker/README.md
137
docker/README.md
@@ -1,133 +1,20 @@
|
|||||||
# Docker
|
# Docker
|
||||||
|
|
||||||
## Описание приложения
|
## Blue-green deployment
|
||||||
|
|
||||||
Простой веб сервис написанный на **Go**, возвращающий имя узла.
|
Сине-зеленое развертывание — это стратегия развертывания, при которой вы создаете два отдельных, но идентичные среды.
|
||||||
|
Одна среда (синяя) использует текущую версию приложения и одна среда (зеленая) использует новую версию приложения.
|
||||||
|
Использование синего/зеленого развертывания стратегия повышает доступность приложений
|
||||||
|
и снижает риск развертывания за счет упрощения процесс отката в случае сбоя развертывания.
|
||||||
|
После завершения тестирования на зеленом среда, трафик активных приложений направляется в зеленую среду и синюю среда устарела.
|
||||||
|
|
||||||
Сервис можно запустить несколькими способами.
|
[Blue-green deployment](./blue-green-deployment/) - это программная платформа для быстрой сборки, отладки и развертывания приложений с помощью **контейнеров**.
|
||||||
|
|
||||||
### Локальный запуск
|
## uv
|
||||||
|
|
||||||
Сборка приложения:
|
Чрезвычайно быстрый менеджер пакетов и проектов Python, написанный на Rust.
|
||||||
|
|
||||||
```sh
|
Один инструмент для замены **pip**, **pip-tools**, **pipx**, **poetry**, **pyenv**, **twine**, **virtualenv**, и многое другое.
|
||||||
go build main.go
|
|
||||||
```
|
|
||||||
|
|
||||||
Запуск
|
[uv](./uv/)
|
||||||
|
[Официальный GitHub репозиторий](https://github.com/astral-sh/uv)
|
||||||
```sh
|
|
||||||
./main
|
|
||||||
```
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
```output
|
|
||||||
Сервер запущен на порту 8080...
|
|
||||||
```
|
|
||||||
|
|
||||||
Проверка
|
|
||||||
|
|
||||||
```sh
|
|
||||||
curl localhost:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
```output
|
|
||||||
Имя узла: MacBook-Pro-Fedor.local
|
|
||||||
```
|
|
||||||
|
|
||||||
### Запуск в контейнере
|
|
||||||
|
|
||||||
```sh
|
|
||||||
docker build -t test . && docker run --hostname my_container --publish 8080:8080 test
|
|
||||||
```
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
```output
|
|
||||||
Сервер запущен на порту 8080...
|
|
||||||
```
|
|
||||||
|
|
||||||
Проверка
|
|
||||||
|
|
||||||
```sh
|
|
||||||
curl localhost:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
```output
|
|
||||||
Имя узла: my_container
|
|
||||||
```
|
|
||||||
|
|
||||||
### Запуск при помощи docker compose
|
|
||||||
|
|
||||||
Запуск
|
|
||||||
|
|
||||||
```sh
|
|
||||||
docker compose --profile blue up --wait --remove-orphans --scale web-blue=3
|
|
||||||
```
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
```output
|
|
||||||
✔ Network docker_default Created
|
|
||||||
✔ Container docker-web-blue-1 Healthy
|
|
||||||
✔ Container docker-nginx-proxy-1 Healthy
|
|
||||||
✔ Container docker-web-blue-3 Healthy
|
|
||||||
✔ Container docker-web-blue-2 Healthy
|
|
||||||
```
|
|
||||||
|
|
||||||
Проверка
|
|
||||||
|
|
||||||
Поскольку запущено несколько реплик сервиса, то при повторной проверке мы можем увидеть разное имена узлов
|
|
||||||
|
|
||||||
```sh
|
|
||||||
declare -A responses
|
|
||||||
count=0
|
|
||||||
|
|
||||||
while [ ${#responses[@]} -lt 3 ]; do
|
|
||||||
response=$(curl -s localhost:8080)
|
|
||||||
|
|
||||||
if [[ -z "${responses[$response]}" ]]; then
|
|
||||||
responses["$response"]=1
|
|
||||||
count=$((count + 1))
|
|
||||||
echo "Уникальный ответ $count: $response"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
```output
|
|
||||||
Уникальный ответ 1: Имя узла: eeec60605b3c
|
|
||||||
Уникальный ответ 2: Имя узла: 1a0e8d8f0d64
|
|
||||||
Уникальный ответ 3: Имя узла: d5822762eab6
|
|
||||||
```
|
|
||||||
|
|
||||||
### Сине-зеленое развертывание
|
|
||||||
|
|
||||||
Запуск
|
|
||||||
|
|
||||||
```sh
|
|
||||||
bash ./deploy.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
```output
|
|
||||||
Список контейнеров
|
|
||||||
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
|
||||||
docker-nginx-proxy-1 nginxproxy/nginx-proxy:1.6.2-alpine "/app/docker-entrypo…" nginx-proxy 22 seconds ago Up 22 seconds (healthy) 0.0.0.0:80->80/tcp
|
|
||||||
docker-web-green-1 docker-web-green "./main" web-green 6 seconds ago Up 6 seconds (healthy) 8080/tcp
|
|
||||||
docker-web-green-2 docker-web-green "./main" web-green 6 seconds ago Up 6 seconds (healthy) 8080/tcp
|
|
||||||
docker-web-green-3 docker-web-green "./main" web-green 6 seconds ago Up 6 seconds (healthy) 8080/tcp
|
|
||||||
Журналы запуска web-green
|
|
||||||
web-green-3 | Сервер запущен на порту 8080...
|
|
||||||
web-green-2 | Сервер запущен на порту 8080...
|
|
||||||
web-green-1 | Сервер запущен на порту 8080...
|
|
||||||
```
|
|
||||||
|
|
||||||
[Проверка](README.md#L83)
|
|
||||||
|
|||||||
133
docker/blue-green-deployment/README.md
Normal file
133
docker/blue-green-deployment/README.md
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# Docker
|
||||||
|
|
||||||
|
## Описание приложения
|
||||||
|
|
||||||
|
Простой веб сервис написанный на **Go**, возвращающий имя узла.
|
||||||
|
|
||||||
|
Сервис можно запустить несколькими способами.
|
||||||
|
|
||||||
|
### Локальный запуск
|
||||||
|
|
||||||
|
Сборка приложения:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go build main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
Запуск
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./main
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Сервер запущен на порту 8080...
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверка
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Имя узла: MacBook-Pro-Fedor.local
|
||||||
|
```
|
||||||
|
|
||||||
|
### Запуск в контейнере
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker build -t test . && docker run --hostname my_container --publish 8080:8080 test
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Сервер запущен на порту 8080...
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверка
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Имя узла: my_container
|
||||||
|
```
|
||||||
|
|
||||||
|
### Запуск при помощи docker compose
|
||||||
|
|
||||||
|
Запуск
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose --profile blue up --wait --remove-orphans --scale web-blue=3
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
✔ Network docker_default Created
|
||||||
|
✔ Container docker-web-blue-1 Healthy
|
||||||
|
✔ Container docker-nginx-proxy-1 Healthy
|
||||||
|
✔ Container docker-web-blue-3 Healthy
|
||||||
|
✔ Container docker-web-blue-2 Healthy
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверка
|
||||||
|
|
||||||
|
Поскольку запущено несколько реплик сервиса, то при повторной проверке мы можем увидеть разное имена узлов
|
||||||
|
|
||||||
|
```sh
|
||||||
|
declare -A responses
|
||||||
|
count=0
|
||||||
|
|
||||||
|
while [ ${#responses[@]} -lt 3 ]; do
|
||||||
|
response=$(curl -s localhost:8080)
|
||||||
|
|
||||||
|
if [[ -z "${responses[$response]}" ]]; then
|
||||||
|
responses["$response"]=1
|
||||||
|
count=$((count + 1))
|
||||||
|
echo "Уникальный ответ $count: $response"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Уникальный ответ 1: Имя узла: eeec60605b3c
|
||||||
|
Уникальный ответ 2: Имя узла: 1a0e8d8f0d64
|
||||||
|
Уникальный ответ 3: Имя узла: d5822762eab6
|
||||||
|
```
|
||||||
|
|
||||||
|
### Сине-зеленое развертывание
|
||||||
|
|
||||||
|
Запуск
|
||||||
|
|
||||||
|
```sh
|
||||||
|
bash ./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Список контейнеров
|
||||||
|
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||||
|
docker-nginx-proxy-1 nginxproxy/nginx-proxy:1.6.2-alpine "/app/docker-entrypo…" nginx-proxy 22 seconds ago Up 22 seconds (healthy) 0.0.0.0:80->80/tcp
|
||||||
|
docker-web-green-1 docker-web-green "./main" web-green 6 seconds ago Up 6 seconds (healthy) 8080/tcp
|
||||||
|
docker-web-green-2 docker-web-green "./main" web-green 6 seconds ago Up 6 seconds (healthy) 8080/tcp
|
||||||
|
docker-web-green-3 docker-web-green "./main" web-green 6 seconds ago Up 6 seconds (healthy) 8080/tcp
|
||||||
|
Журналы запуска web-green
|
||||||
|
web-green-3 | Сервер запущен на порту 8080...
|
||||||
|
web-green-2 | Сервер запущен на порту 8080...
|
||||||
|
web-green-1 | Сервер запущен на порту 8080...
|
||||||
|
```
|
||||||
|
|
||||||
|
[Проверка](README.md#L83)
|
||||||
@@ -11,7 +11,7 @@ services:
|
|||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpus: "0.5" # Лимитированный доступ к ресурсам CPU
|
cpus: '0.5' # Лимитированный доступ к ресурсам CPU
|
||||||
memory: 32M # Лимит памяти
|
memory: 32M # Лимит памяти
|
||||||
restart: always # Перезапускать сервис при падении
|
restart: always # Перезапускать сервис при падении
|
||||||
profiles:
|
profiles:
|
||||||
@@ -19,7 +19,8 @@ services:
|
|||||||
|
|
||||||
# Сервис для развертывания приложения с профилем "green"
|
# Сервис для развертывания приложения с профилем "green"
|
||||||
web-green:
|
web-green:
|
||||||
<<: *web # Используем настройки из сервиса web-blue
|
<<: *web
|
||||||
|
# Используем настройки из сервиса web-blue
|
||||||
profiles:
|
profiles:
|
||||||
- green
|
- green
|
||||||
|
|
||||||
183
docker/uv/.dockerignore
Normal file
183
docker/uv/.dockerignore
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/python
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
||||||
|
|
||||||
|
### Python ###
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
### Python Patch ###
|
||||||
|
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
||||||
|
poetry.toml
|
||||||
|
|
||||||
|
# ruff
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# LSP config files
|
||||||
|
pyrightconfig.json
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/python
|
||||||
|
|
||||||
|
# Other
|
||||||
|
.gitignore
|
||||||
|
Dockerfile*
|
||||||
|
Makefile
|
||||||
|
README.md
|
||||||
|
pyproject.toml
|
||||||
176
docker/uv/.gitignore
vendored
Normal file
176
docker/uv/.gitignore
vendored
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/python
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
||||||
|
|
||||||
|
### Python ###
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
### Python Patch ###
|
||||||
|
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
||||||
|
poetry.toml
|
||||||
|
|
||||||
|
# ruff
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# LSP config files
|
||||||
|
pyrightconfig.json
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/python
|
||||||
43
docker/uv/Dockerfile
Normal file
43
docker/uv/Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Базовый образ
|
||||||
|
FROM python:3.13.1-alpine
|
||||||
|
|
||||||
|
# Устанавливаем переменные окружения
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
PYTHONUNBUFFERED=1 \
|
||||||
|
WORKDIR_PATH="/app" \
|
||||||
|
VENV_PATH="/opt/venv"
|
||||||
|
|
||||||
|
# Определяем аргументы для пользователя и группы
|
||||||
|
ARG USERNAME=appuser
|
||||||
|
ARG GROUPNAME=appgroup
|
||||||
|
|
||||||
|
# Создаем пользователя и рабочую директорию
|
||||||
|
RUN addgroup --system ${GROUPNAME} \
|
||||||
|
&& adduser --system --ingroup ${GROUPNAME} ${USERNAME} \
|
||||||
|
&& mkdir -p ${WORKDIR_PATH} ${VENV_PATH} \
|
||||||
|
&& chown -R ${USERNAME}:${GROUPNAME} ${WORKDIR_PATH} ${VENV_PATH}
|
||||||
|
|
||||||
|
# Устанавливаем рабочую директорию
|
||||||
|
WORKDIR ${WORKDIR_PATH}
|
||||||
|
|
||||||
|
# Копируем uv чрезвычайно быстрый менеджер пакетов и проектов Python
|
||||||
|
COPY --from=ghcr.io/astral-sh/uv:0.5.11 /uv /uvx /bin/
|
||||||
|
|
||||||
|
# Создаем виртуальное окружение и настраиваем PATH
|
||||||
|
RUN uv venv ${VENV_PATH}
|
||||||
|
ENV PATH="${VENV_PATH}/bin:$PATH"
|
||||||
|
|
||||||
|
# Копируем requirements, устанавливаем зависимости в venv и устанавливаем права
|
||||||
|
COPY --chown=${USERNAME}:${GROUPNAME} ./requirements.txt ./requirements.txt
|
||||||
|
RUN uv pip install --no-cache --require-hashes --requirements ./requirements.txt \
|
||||||
|
&& chown -R ${USERNAME}:${GROUPNAME} ${VENV_PATH}
|
||||||
|
|
||||||
|
# Копируем остальные файлы приложения
|
||||||
|
COPY --chown=${USERNAME}:${GROUPNAME} ./ ./
|
||||||
|
|
||||||
|
# Запускаем контейнер от имени нового пользователя
|
||||||
|
USER ${USERNAME}:${GROUPNAME}
|
||||||
|
|
||||||
|
# Настраиваем команду запуска
|
||||||
|
ENTRYPOINT ["uvicorn", "main:app"]
|
||||||
|
CMD [ "--host", "0.0.0.0", "--port", "8000" ]
|
||||||
40
docker/uv/Dockerfile.pip
Normal file
40
docker/uv/Dockerfile.pip
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Базовый образ
|
||||||
|
FROM python:3.13.1-alpine
|
||||||
|
|
||||||
|
# Устанавливаем переменные окружения
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
PYTHONUNBUFFERED=1 \
|
||||||
|
WORKDIR_PATH="/app" \
|
||||||
|
VENV_PATH="/opt/venv"
|
||||||
|
|
||||||
|
# Определяем аргументы для пользователя и группы
|
||||||
|
ARG USERNAME=appuser
|
||||||
|
ARG GROUPNAME=appgroup
|
||||||
|
|
||||||
|
# Создаем пользователя и рабочую директорию
|
||||||
|
RUN addgroup --system ${GROUPNAME} \
|
||||||
|
&& adduser --system --ingroup ${GROUPNAME} ${USERNAME} \
|
||||||
|
&& mkdir -p ${WORKDIR_PATH} ${VENV_PATH} \
|
||||||
|
&& chown -R ${USERNAME}:${GROUPNAME} ${WORKDIR_PATH} ${VENV_PATH}
|
||||||
|
|
||||||
|
# Устанавливаем рабочую директорию
|
||||||
|
WORKDIR ${WORKDIR_PATH}
|
||||||
|
|
||||||
|
# Создаем виртуальное окружение и настраиваем PATH
|
||||||
|
RUN python -m venv ${VENV_PATH}
|
||||||
|
ENV PATH="${VENV_PATH}/bin:$PATH"
|
||||||
|
|
||||||
|
# Копируем requirements, устанавливаем зависимости в venv и устанавливаем права
|
||||||
|
COPY --chown=${USERNAME}:${GROUPNAME} ./requirements.txt ./requirements.txt
|
||||||
|
RUN pip install --no-cache --require-hashes -r ./requirements.txt \
|
||||||
|
&& chown -R ${USERNAME}:${GROUPNAME} ${VENV_PATH}
|
||||||
|
|
||||||
|
# Копируем остальные файлы приложения
|
||||||
|
COPY --chown=${USERNAME}:${GROUPNAME} ./ ./
|
||||||
|
|
||||||
|
# Запускаем контейнер от имени нового пользователя
|
||||||
|
USER ${USERNAME}:${GROUPNAME}
|
||||||
|
|
||||||
|
# Настраиваем команду запуска
|
||||||
|
ENTRYPOINT ["uvicorn", "main:app"]
|
||||||
|
CMD [ "--host", "0.0.0.0", "--port", "8000" ]
|
||||||
16
docker/uv/Makefile
Normal file
16
docker/uv/Makefile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
reqs:
|
||||||
|
rm ./requirements.txt || true
|
||||||
|
uv pip compile --generate-hashes pyproject.toml --output-file ./requirements.txt
|
||||||
|
|
||||||
|
venv:
|
||||||
|
uv venv --python 3.13
|
||||||
|
uv pip install --require-hashes --requirements ./requirements.txt
|
||||||
|
. .venv/bin/activate
|
||||||
|
|
||||||
|
build:
|
||||||
|
time docker build --no-cache --file Dockerfile -t uv .
|
||||||
|
docker images
|
||||||
|
|
||||||
|
build-pip:
|
||||||
|
time docker build --no-cache --file Dockerfile.pip -t pip .
|
||||||
|
docker images
|
||||||
37
docker/uv/README.md
Normal file
37
docker/uv/README.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# uv
|
||||||
|
|
||||||
|
Чрезвычайно быстрый менеджер пакетов и проектов Python, написанный на Rust.
|
||||||
|
|
||||||
|
Один инструмент для замены **pip**, **pip-tools**, **pipx**, **poetry**, **pyenv**, **twine**, **virtualenv**, и многое другое.
|
||||||
|
|
||||||
|
[Официальный GitHub репозиторий](https://github.com/astral-sh/uv)
|
||||||
|
|
||||||
|
## Как работаь с **uv**
|
||||||
|
|
||||||
|
[Установка **UV**](https://github.com/astral-sh/uv#installation)
|
||||||
|
|
||||||
|
- Создание окружения
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make venv
|
||||||
|
```
|
||||||
|
|
||||||
|
- Обновление библиотек
|
||||||
|
|
||||||
|
Обноваляем версии зависимостей в **pyproject.toml** и запускаем
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make reqs
|
||||||
|
```
|
||||||
|
|
||||||
|
Сборка образа с **uv** без кэша
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make build
|
||||||
|
```
|
||||||
|
|
||||||
|
Сборка образа с **pip** без кэша
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make build-pip
|
||||||
|
```
|
||||||
16
docker/uv/main.py
Normal file
16
docker/uv/main.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
from fastapi import FastAPI
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
class Item(BaseModel):
|
||||||
|
name: str
|
||||||
|
price: float
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
async def root():
|
||||||
|
return {"message": "Hello World"}
|
||||||
|
|
||||||
|
@app.post("/items/")
|
||||||
|
async def create_item(item: Item):
|
||||||
|
return item
|
||||||
77
docker/uv/pyproject.toml
Normal file
77
docker/uv/pyproject.toml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
[project]
|
||||||
|
authors = [{name = "Fedor Batonogov", email = "f.batonogov@yandex.ru"}]
|
||||||
|
dependencies = [
|
||||||
|
"aioboto3==13.3.0",
|
||||||
|
"aiobotocore==2.16.0",
|
||||||
|
"aiofiles==24.1.0",
|
||||||
|
"aiohappyeyeballs==2.4.4",
|
||||||
|
"aiohttp==3.11.11",
|
||||||
|
"aioitertools==0.12.0",
|
||||||
|
"aiosignal==1.3.2",
|
||||||
|
"annotated-types==0.7.0",
|
||||||
|
"anyio==4.7.0",
|
||||||
|
"asgi-lifespan==2.1.0",
|
||||||
|
"asyncio==3.4.3",
|
||||||
|
"attrs==24.3.0",
|
||||||
|
"autoflake==2.3.1",
|
||||||
|
"black==24.10.0",
|
||||||
|
"boto3==1.35.81",
|
||||||
|
"botocore==1.35.81",
|
||||||
|
"certifi==2024.12.14",
|
||||||
|
"cfgv==3.4.0",
|
||||||
|
"charset-normalizer==3.4.0",
|
||||||
|
"click==8.1.8",
|
||||||
|
"contextvars==2.4",
|
||||||
|
"distlib==0.3.9",
|
||||||
|
"fastapi==0.115.6",
|
||||||
|
"filelock==3.16.1",
|
||||||
|
"flake8==7.1.1",
|
||||||
|
"frozenlist==1.5.0",
|
||||||
|
"h11==0.14.0",
|
||||||
|
"httpcore==1.0.7",
|
||||||
|
"httpx==0.28.1",
|
||||||
|
"identify==2.6.3",
|
||||||
|
"idna==3.10",
|
||||||
|
"immutables==0.21",
|
||||||
|
"iniconfig==2.0.0",
|
||||||
|
"jmespath==1.0.1",
|
||||||
|
"logging==0.4.9.6",
|
||||||
|
"loguru==0.7.3",
|
||||||
|
"mccabe==0.7.0",
|
||||||
|
"multidict==6.1.0",
|
||||||
|
"multipart==1.2.1",
|
||||||
|
"mypy-extensions==1.0.0",
|
||||||
|
"nodeenv==1.9.1",
|
||||||
|
"packaging==24.2",
|
||||||
|
"pathspec==0.12.1",
|
||||||
|
"platformdirs==4.3.6",
|
||||||
|
"pluggy==1.5.0",
|
||||||
|
"pre_commit==4.0.1",
|
||||||
|
"propcache==0.2.1",
|
||||||
|
"pycodestyle==2.12.1",
|
||||||
|
"pydantic==2.10.4",
|
||||||
|
"pydantic-settings==2.7.0",
|
||||||
|
"pydantic-core==2.27.2",
|
||||||
|
"pyflakes==3.2.0",
|
||||||
|
"pytest==8.3.4",
|
||||||
|
"pytest-asyncio==0.25.0",
|
||||||
|
"pytest-mock==3.14.0",
|
||||||
|
"python-dateutil==2.9.0.post0",
|
||||||
|
"python-dotenv==1.0.1",
|
||||||
|
"python-multipart==0.0.20",
|
||||||
|
"PyYAML==6.0.2",
|
||||||
|
"requests==2.32.3",
|
||||||
|
"s3transfer==0.10.4",
|
||||||
|
"six==1.17.0",
|
||||||
|
"sniffio==1.3.1",
|
||||||
|
"starlette==0.41.3",
|
||||||
|
"typing_extensions==4.12.2",
|
||||||
|
"urllib3==2.3.0 ",
|
||||||
|
"uvicorn==0.34.0",
|
||||||
|
"virtualenv==20.28.0",
|
||||||
|
"wrapt==1.17.0",
|
||||||
|
"yarl==1.18.3"
|
||||||
|
]
|
||||||
|
dynamic = ["version"]
|
||||||
|
name = "uv"
|
||||||
|
requires-python = ">=3.13"
|
||||||
1203
docker/uv/requirements.txt
Normal file
1203
docker/uv/requirements.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user