diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..73bb1a2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,78 @@ +# Git +.git +.gitignore +.gitattributes + +# Python +__pycache__ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +.pytest_cache/ +.coverage +.coverage.* +htmlcov/ + +# Virtual Environments +venv/ +ENV/ +env/ +.venv +.env +.env.local +.env.*.local + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store +.ropeproject + +# Project specific +.cache/ +.ruff_cache/ +*.db +.pytest_cache/ + +# Docker +.docker +.dockerignore +Dockerfile + +# Build artifacts +.flatpak-builder/ +build-dir/ + +# Node (если используется) +node_modules/ +npm-debug.log +yarn-error.log + +# OS +.DS_Store +Thumbs.db + +# app +tests/ diff --git a/.env.example b/.env.example index a8c5792..92beda3 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,10 @@ # Урлы -STREAM_URL=адрес видеопотока -WEBSOCKET_URL=адрес вебсокета клиента -WEBSOCKET_URL_ROBOT=адрес вебсокета робота +STREAM_URL=http://адрес видеопотока +WEBSOCKET_URL=ws://адрес вебсокета клиента +WEBSOCKET_URL_ROBOT=ws://адрес вебсокета робота +HOST_APP=ip или доменное имя для app +PORT_APP=порт для app +IS_RELOAD=True для разработки, False для обычного использования # Команды для робота FORWARD=вперёд diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..94b3845 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,53 @@ +name: Build and backup docker conteiner + +on: + # Сработает при создании pull request в master ветку + pull_request: + branches: + - master + +jobs: + # Сборка контейнера + build: + name: Run build conteiner + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + run: | + make docker-build + env: + PORT_APP: ${{ secrets.PORT_APP }} + # Отправка образа в dockerhub + push_dockerhub: + name: Push image to docker hub + runs-on: ubuntu-latest + needs: build # ждёт успешной сборки + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/web-robot-control-app:latest + build-args: | + PORT_APP=${{ secrets.PORT_APP }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b5df75f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.12.0-slim + +WORKDIR /app + +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 + +COPY . /app + +RUN pip install poetry + +RUN poetry config virtualenvs.create false && \ + poetry install --no-interaction --no-ansi \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..96a8f1e --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +help: + @echo "Доступные команды:" + @echo " make docker-build - Собрать Docker образ" + @echo " make docker-rebuild - Пересобрать Docker образ (с очисткой кеша)" + @echo " make start-app-debug - Поднять контейнер с приложением (в режиме debug)" + @echo " make start-app - Поднять контейнер с приложением" + @echo " make stop-app - Остановить контейнер с приложением" + @echo " make docker-pull - Скачать образ web-robot-control-app c Docker Hub" + +docker-build: + docker compose build + +docker-rebuild: + docker compose build --no-cache + +start-app-debug: + docker compose up + +start-app: + docker compose up -d + +stop-app: + docker stop web_robot_control + +docker-pull: + docker pull arduinum628/web-robot-control-app \ No newline at end of file diff --git a/README.md b/README.md index 9748f01..960624e 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,61 @@ **Web-robot-control** - open source веб-приложение для управлением роботом и трансляции видео с веб-камеры. -## Запуск приложения +## Запуск приложения (Linux / Mac OS) -**Запуск для локальной разработки**: `poetry run start_app` +**Способ 1 (локальная разработка)** -**Todo:** создать Python-функцию для запуска веб-приложения и добавить её в скрипты Poetry +- **Клонировать репозиторий**: `git clone git@github.com:Arduinum/web-robot-control.git` +- **Перейти в папку проекта**: `cd web-robot-control` +- **Установить библиотеки проекта**: `poetry install` +- **Создать `.env` в корне проекта используя `.env.example` в качестве шаблона** +- **Запуск приложения**: `poetry run start_app` + +### Способ 2 (с использованим `docker-compose.yml`) + +- **Клонировать репозиторий**: `git clone git@github.com:Arduinum/web-robot-control.git` +- **Перейти в папку проекта**: `cd web-robot-control` +- **Создать `.env` в корне проекта используя `.env.example` в качестве шаблона** +- **Скачать образ**: `make docker-pull` +- **Создать volume**: `docker volume create app` +- **Запуск приложения**: `make start-app` + +### Способ 3 (с использованием docker) + +- **Создать `.env` в любом удоном месте используя `.env.example` в качестве шаблона** +- **Скачать образ**: `docker pull arduinum628/web-robot-control-app` +- **Создать volume**: `docker volume create app` +- **Создать `.env` в корне проекта используя `.env.example` в качестве шаблона** +- **Экспорт `.env` переменных**: `export $(grep -v '^#' .env | xargs)` +- **Запуск приложения**: `docker run -d --name web_robot_control -p ${PORT_APP}:${PORT_APP} -v app:/app --env-file .env arduinum628/web-robot-control-app:latest poetry run start_app` + +## Запуск приложения (Windows) + +**Способ 1 (локальная разработка)** + +- **Клонировать репозиторий**: `git clone git@github.com:Arduinum/web-robot-control.git` +- **Перейти в папку проекта**: `cd web-robot-control` +- **Установить библиотеки проекта**: `poetry install` +- **Создать `.env` в корне проекта используя `.env.example` в качестве шаблона** +- **Запуск приложения**: `poetry run start_app` + +### Способ 2 (с использованим `docker-compose.yml`) + +- **Клонировать репозиторий**: `git clone git@github.com:Arduinum/web-robot-control.git` +- **Перейти в папку проекта**: `cd web-robot-control` +- **Создать `.env` в корне проекта используя `.env.example` в качестве шаблона** +- **Скачать образ**: `docker compose pull` +- **Создать volume**: `docker volume create app` +- **Запуск приложения**: `docker compose up -d` + +### Способ 3 (с использованием docker) + +- **Создать `.env` в любом удоном месте используя `.env.example` в качестве шаблона** +- **Скачать образ**: `docker pull arduinum628/web-robot-control-app` +- **Создать volume**: `docker volume create app` +- **Создать `.env` в корне проекта используя `.env.example` в качестве шаблона** +- **Экспорт `.env` переменных**: `export $(grep -v '^#' .env | xargs)` +- **Запуск приложения**: `docker run -d --name web_robot_control -p $env:PORT_APP:$env:PORT_APP -v app:/app --env-file .env arduinum628/web-robot-control-app:latest poetry run start_app`
diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..680cad4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + app: + build: . + image: arduinum628/web-robot-control-app:latest + container_name: web_robot_control + command: poetry run start_app + env_file: + - .env + ports: + - "${PORT_APP}:${PORT_APP}" + volumes: + - app:/app + +volumes: + app: \ No newline at end of file diff --git a/src/web_robot_control/settings.py b/src/web_robot_control/settings.py index 3d79add..8a53ef6 100644 --- a/src/web_robot_control/settings.py +++ b/src/web_robot_control/settings.py @@ -31,6 +31,9 @@ class Settings(ModelConfig): stream_url: str websocket_url_robot: str + port_app: int + host_app: str + is_reload: bool commands_robot: CommandsRobot = CommandsRobot() diff --git a/src/web_robot_control/start.py b/src/web_robot_control/start.py index 20a44a2..3f32ed3 100644 --- a/src/web_robot_control/start.py +++ b/src/web_robot_control/start.py @@ -1,12 +1,14 @@ import uvicorn +from web_robot_control.settings import settings + def start_app(): """Функция запуска приложения""" uvicorn.run( 'web_robot_control.main:app', - host='127.0.0.1', - port=8000, - reload=True + host=settings.host_app, + port=settings.port_app, + reload=settings.is_reload )