diff --git a/.dockerignore b/.dockerignore index 64bf0abe..7436a9fd 100644 --- a/.dockerignore +++ b/.dockerignore @@ -64,12 +64,9 @@ setup_req.txt ### Docker # .dockerignore .dockerignore -dev.Dockerfile docker-compose.yml Dockerfile -hub.alpine.Dockerfile -hub.ubuntu.Dockerfile -ubuntu.Dockerfile +hub.Dockerfile ####################################### ### pyTMbot # app dir diff --git a/.github/workflows/docker_build_on_push.yml b/.github/workflows/docker_build_on_push.yml index 6f1a7d75..f0617b05 100644 --- a/.github/workflows/docker_build_on_push.yml +++ b/.github/workflows/docker_build_on_push.yml @@ -15,4 +15,4 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build the Docker image - run: docker build . --file hub.alpine.Dockerfile --tag orenlab/pytmbot:$(date +%s) + run: docker build . --target prod --tag orenlab/pytmbot:$(date +%s) diff --git a/.github/workflows/docker_dev_alpine.yml b/.github/workflows/docker_dev_alpine.yml index 367e7cb5..2e124cee 100644 --- a/.github/workflows/docker_dev_alpine.yml +++ b/.github/workflows/docker_dev_alpine.yml @@ -21,6 +21,7 @@ jobs: - name: Build and push uses: docker/build-push-action@v5 with: - file: hub.alpine.Dockerfile + build-args: --target prod + file: hub.Dockerfile push: true tags: orenlab/pytmbot:alpine-dev diff --git a/.github/workflows/docker_dev_ubuntu.yml b/.github/workflows/docker_dev_ubuntu.yml deleted file mode 100644 index 9d6aa523..00000000 --- a/.github/workflows/docker_dev_ubuntu.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Push Ubuntu Dev Image - -on: - push: - branches: - - 'development' - -jobs: - docker: - runs-on: ubuntu-latest - steps: - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build and push - uses: docker/build-push-action@v5 - with: - file: hub.ubuntu.Dockerfile - push: true - tags: orenlab/pytmbot:ubuntu-dev diff --git a/.github/workflows/docker_image_release_cicd.yml b/.github/workflows/docker_image_release_cicd.yml index 336f3f4c..352a33bf 100644 --- a/.github/workflows/docker_image_release_cicd.yml +++ b/.github/workflows/docker_image_release_cicd.yml @@ -26,14 +26,15 @@ jobs: id: meta uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 with: - images: orenlab/pytmbot + images: ${{ github.repository }} - name: Build and push Docker image id: push uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 with: context: . - file: hub.alpine.Dockerfile + file: Dockerfile + build-args: --target prod push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.run/Dockerfile.run.xml b/.run/Dockerfile.run.xml index de294819..716a16fc 100644 --- a/.run/Dockerfile.run.xml +++ b/.run/Dockerfile.run.xml @@ -1,21 +1,41 @@ - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/Dockerfile_dev.run.xml b/.run/Dockerfile_dev.run.xml deleted file mode 100644 index de294819..00000000 --- a/.run/Dockerfile_dev.run.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 4ea65bba..0d60d0d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,30 @@ -####################################### -# pyTMbot Dockerfile (based on Alpine) -# image size: ~ 90Mb +############################################################# +## pyTMbot Dockerfile # https://github.com/orenlab/pytmbot -####################################### +# +# To launch with a production token. Default way: +# docker --target prod build -t orenlab/pytmbot:latest . +# +# To launch with a development token. Only for development: +# docker --target dev build -t orenlab/pytmbot:latest . +############################################################# -# Set Alpine tag version for first and second stage -ARG IMAGE_VERSION_FIRST=3.12.3-alpine3.19 -ARG IMAGE_VERSION_SECOND=3.19.1 +# Set base images tag +ARG PYTHON_IMAGE=3.12.3-alpine3.19 +ARG ALPINE_IMAGE=3.19.1 -# First stage -FROM python:$IMAGE_VERSION_FIRST AS builder -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 +######################################################################################################################## +######################### BUILD ALPINE BASED IMAGE ##################################################################### +######################################################################################################################## -COPY requirements.txt . +# Zero Alpine stage - setup base image +FROM alpine:${ALPINE_IMAGE} AS alpine_base -# Update base os components and install all deps (need to build psutil) +# Update base os components RUN apk --no-cache update && \ apk --no-cache upgrade && \ - apk --no-cache add gcc python3-dev musl-dev linux-headers - -# Install dependencies to the venv path -RUN python$PYTHON_VERSION -m venv --without-pip venv -RUN pip install --no-cache --target="/venv/lib/python$PYTHON_VERSION/site-packages" -r requirements.txt - -RUN python -m pip uninstall pip setuptools python3-wheel python3-dev -y - -# Second unnamed stage -FROM alpine:$IMAGE_VERSION_SECOND -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 - # Add Timezone support in Alpine image -RUN apk --no-cache add tzdata + apk --no-cache add tzdata # App workdir WORKDIR /opt/pytmbot/ @@ -43,42 +35,69 @@ ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONPATH=/opt/pytmbot ENV PATH=/venv/bin:$PATH +# Copy lisence +COPY LICENSE /opt/pytmbot/ + +# Copy bot files +COPY ./app ./app/ +COPY ./logs /opt/logs/ + +# First Alpine stage - build Python deps +FROM python:${PYTHON_IMAGE} AS builder + +# Python version (minimal - 3.12) +ARG PYTHON_VERSION=3.12 + +COPY requirements.txt . + +# Install all deps (need to build psutil) +RUN apk --no-cache add gcc python3-dev musl-dev linux-headers + +# Install dependencies to the venv path +RUN python${PYTHON_VERSION} -m venv --without-pip venv +RUN pip install --no-cache-dir --no-deps --target="/venv/lib/python${PYTHON_VERSION}/site-packages" -r requirements.txt + +RUN python${PYTHON_VERSION} -m pip uninstall pip setuptools python3-wheel python3-dev musl-dev -y + +# Second Alpine stage - based on the base stage. Setup bot +FROM alpine_base AS reliase_base + +# Python version (minimal - 3.12) +ARG PYTHON_VERSION=3.12 + # Сopy only the necessary python files and directories from first stage COPY --from=builder /usr/local/bin/python3 /usr/local/bin/python3 -COPY --from=builder /usr/local/bin/python$PYTHON_VERSION /usr/local/bin/python$PYTHON_VERSION -COPY --from=builder /usr/local/lib/python$PYTHON_VERSION /usr/local/lib/python$PYTHON_VERSION -COPY --from=builder /usr/local/lib/libpython$PYTHON_VERSION.so.1.0 /usr/local/lib/libpython$PYTHON_VERSION.so.1.0 +COPY --from=builder /usr/local/bin/python${PYTHON_VERSION} /usr/local/bin/python${PYTHON_VERSION} +COPY --from=builder /usr/local/lib/python${PYTHON_VERSION} /usr/local/lib/python${PYTHON_VERSION} +COPY --from=builder /usr/local/lib/libpython${PYTHON_VERSION}.so.1.0 /usr/local/lib/libpython${PYTHON_VERSION}.so.1.0 COPY --from=builder /usr/local/lib/libpython3.so /usr/local/lib/libpython3.so # Copy only the dependencies installation from the first stage image COPY --from=builder /venv /venv -# Copy .pytmbotenv file with token (prod, dev) -COPY .pytmbotenv /opt/pytmbot +# activate venv +RUN source /venv/bin/activate && \ +# forward logs to Docker's log collector + ln -sf /dev/stdout /opt/logs/pytmbot.log -# Copy lisence -COPY LICENSE /opt/pytmbot -# Copy bot files -COPY ./app ./app/ -COPY ./logs /opt/logs/ +# Target for CI/CD image, --mode = prod +FROM reliase_base AS prod +CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=prod" ] -# Update base os components -RUN apk --no-cache update && \ - apk --no-cache upgrade && \ -# activate venv - source /venv/bin/activate && \ -# forward logs to Docker's log collector - ln -sf /dev/stdout /opt/logs/pytmbot.log +# Target for self biuld image, --mode = prod +FROM reliase_base AS selfbuild_prod + +# Copy .pytmbotenv file with token (prod, dev) +COPY .pytmbotenv /opt/pytmbot/ -# Run app -# !!! needed set log level: -# - DEBUG -# - INFO (default) -# - ERROR -# - CRITICAL -# !!! needed set pyTMBot mode: -# - dev -# - prod (default) CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=prod" ] + +# Target for self biuld image, --mode = dev +FROM reliase_base AS selfbuild_dev + +# Copy .pytmbotenv file with token (prod, dev) +COPY .pytmbotenv /opt/pytmbot/ + +CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=dev" ] \ No newline at end of file diff --git a/README.md b/README.md index 4d63dbb5..82d11eb6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ The bot operates synchronously. It does not use webhooks. [![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=orenlab_pytmbot&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=orenlab_pytmbot) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/abe0314bb5c24cfda8db9c0a293d17c0)](https://app.codacy.com/gh/orenlab/pytmbot/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![Docker Image Build CI/CD](https://github.com/orenlab/pytmbot/actions/workflows/docker_build_on_push.yml/badge.svg)](https://github.com/orenlab/pytmbot/actions/workflows/docker_build_on_push.yml) +![Docker Pulls](https://img.shields.io/docker/pulls/orenlab/pytmbot?link=https%3A%2F%2Fhub.docker.com%2Fr%2Forenlab%2Fpytmbot) The bot was written using the [pyTelegramBotAPI](https://github.com/eternnoir/pyTelegramBotAPI). Use [psutil](https://github.com/giampaolo/psutil) and [docker-py](https://github.com/docker/docker-py) libraries for @@ -88,8 +89,7 @@ All failed attempts to authorize are logged with an `ERROR` flag. │ │ │ ├── handler.py - Base handler class (abc) │ │ │ ├── handlers_aggregator.py - Main handlers aggregator │ │ │ └── inline_handlers -│ │ │ ├── __init__.py - Import all inline handlers -│ │ │ ├── inline_query_handler.py - Deprecated in next release +│ │ │ ├── __init__.py │ │ │ └── swap_handler.py - Swap inline handler │ │ ├── jinja2 │ │ │ ├── __init__.py @@ -124,15 +124,13 @@ All failed attempts to authorize are logged with an `ERROR` flag. │ ├── cfg_templates │ │ └── env.py - Template for initial setup │ └── fs.py - Filesystem utility -├── dev.Dockerfile - Dockerfile with mode=dev ├── docker-compose.yml - Docker Compose file (used main Dockerfile) ├── docs │ ├── docker.md - README for hub.docker.com │ ├── installation.md - Installation guide │ ├── roadmap.md - Roadmap guide │ └── screenshots.md - Bots screenshot -├── hub.alpine.Dockerfile - Dockerfile for Docker CI/CD based on Alpine -├── hub.ubuntu.Dockerfile - Dockerfile for Docker CI/CD based on Ubuntu +├── hub.Dockerfile - Dockerfile for Docker CI/CD based on Alpine ├── logs │ └── pytmbot.log - Main logs file ├── poetry.lock - Poetry file @@ -142,7 +140,6 @@ All failed attempts to authorize are logged with an `ERROR` flag. ├── setup_req.txt - Setup requirements ├── tests │ └── bot_tests.py - Bots tests -└── ubuntu.Dockerfile - Dockerfile, based on Ubuntu image ``` ## 📈 Roadmap diff --git a/SECURITY.md b/SECURITY.md index 99431703..d3228eef 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,8 +4,8 @@ | Version | Supported | |---------|--------------------| -| 0.0.5 | :white_check_mark: | -| < 0.0.5 | :x: | +| 0.0.6 | :white_check_mark: | +| < 0.0.6 | :x: | ## Reporting a Vulnerability diff --git a/app/__init__.py b/app/__init__.py index da36b1c5..e6c47200 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -5,21 +5,21 @@ the status of your local servers """ +import argparse import logging import sys import telebot from telebot import ExceptionHandler -import argparse -from app.core.settings.bot_settings import BotSettings from app.core import exceptions +from app.core.settings.bot_settings import BotSettings # Main config config = BotSettings() # Set global name -__version__ = '0.0.5' +__version__ = '0.0.6' __author__ = 'Denis Rozhnovskiy ' __license__ = 'MIT' __repository__ = 'https://github.com/orenlab/pytmbot' @@ -29,7 +29,11 @@ class CustomExceptionHandler(ExceptionHandler): """Custom exception handler that handles exceptions raised during the execution""" def handle(self, exception): - bot_logger.error(exception, exc_info=False) + if bot_logger.level == 20: + if "Bad getaway" in str(exception): + bot_logger.error('Connection error to Telegram API. Bad getaway. Error code: 502') + else: + bot_logger.error(exception, exc_info=False) return True diff --git a/app/core/adapters/docker_adapter.py b/app/core/adapters/docker_adapter.py index 479f2d30..b665f974 100644 --- a/app/core/adapters/docker_adapter.py +++ b/app/core/adapters/docker_adapter.py @@ -94,7 +94,7 @@ def check_image_details(self): ).time().strftime("%H:%M:%S") details.append( { - 'name': container_details.attrs['Name'].title(), + 'name': container_details.attrs['Name'].title().replace('/', ''), 'image': container_details.attrs['Config']['Image'], 'created': f'{created_day}, {created_time}', 'mem_usage': naturalsize(usage_stats['memory_stats']['usage']), diff --git a/app/core/handlers/default_handlers/containers_handler.py b/app/core/handlers/default_handlers/containers_handler.py index e1116f50..67514bdb 100644 --- a/app/core/handlers/default_handlers/containers_handler.py +++ b/app/core/handlers/default_handlers/containers_handler.py @@ -51,9 +51,7 @@ def _compile_message(self) -> str: def handle(self): @self.bot.message_handler(regexp="Containers") def get_containers(message: Message) -> None: - """ - Get docker containers info - """ + """Get docker containers info""" try: self.bot.send_chat_action(message.chat.id, 'typing') bot_logger.info(self.bot_msg_tpl.HANDLER_START_TEMPLATE.format( diff --git a/app/core/handlers/default_handlers/fs_handler.py b/app/core/handlers/default_handlers/fs_handler.py index 4b440361..c37b8ed2 100644 --- a/app/core/handlers/default_handlers/fs_handler.py +++ b/app/core/handlers/default_handlers/fs_handler.py @@ -38,9 +38,7 @@ def _compile_message(self) -> str: def handle(self): @self.bot.message_handler(regexp="File system") def get_fs(message: Message) -> None: - """ - Get file system info - """ + """Get file system info""" try: self.bot.send_chat_action(message.chat.id, 'typing') bot_logger.info(self.bot_msg_tpl.HANDLER_START_TEMPLATE.format( diff --git a/app/core/handlers/default_handlers/process_handler.py b/app/core/handlers/default_handlers/process_handler.py index e3780a12..c55039fc 100644 --- a/app/core/handlers/default_handlers/process_handler.py +++ b/app/core/handlers/default_handlers/process_handler.py @@ -49,9 +49,7 @@ def _get_answer(self) -> str: def handle(self): @self.bot.message_handler(regexp="Process") def get_process(message: Message) -> None: - """ - Get process count - """ + """Get process count""" try: self.bot.send_chat_action(message.chat.id, 'typing') bot_logger.info(self.bot_msg_tpl.HANDLER_START_TEMPLATE.format( diff --git a/app/core/handlers/default_handlers/start_handler.py b/app/core/handlers/default_handlers/start_handler.py index b2c5252b..ae83d8b0 100644 --- a/app/core/handlers/default_handlers/start_handler.py +++ b/app/core/handlers/default_handlers/start_handler.py @@ -18,9 +18,7 @@ def __init__(self, bot): def handle(self): @self.bot.message_handler(commands=['help', 'start']) def start(message: Message) -> None: - """ - The entry point for starting a dialogue with the bot - """ + """The entry point for starting a dialogue with the bot""" try: self.bot.send_chat_action(message.chat.id, 'typing') bot_logger.info(self.bot_msg_tpl.HANDLER_START_TEMPLATE.format( diff --git a/app/core/handlers/handlers_aggregator.py b/app/core/handlers/handlers_aggregator.py index 8ef29828..959df4cf 100644 --- a/app/core/handlers/handlers_aggregator.py +++ b/app/core/handlers/handlers_aggregator.py @@ -15,7 +15,6 @@ FileSystemHandler, ContainersHandler ) -from app.core.handlers.inline_handlers import InlineQueryHandler from app.core.handlers.inline_handlers.swap_handler import InlineSwapHandler @@ -30,7 +29,6 @@ def __init__(self, bot): self.uptime_handler = UptimeHandler(self.bot) self.fs_handler = FileSystemHandler(self.bot) self.containers_handler = ContainersHandler(self.bot) - self.inline_query_handler = InlineQueryHandler(self.bot) self.inline_swap_handler = InlineSwapHandler(self.bot) def run_handlers(self): @@ -42,7 +40,6 @@ def run_handlers(self): self.process_handler.handle() self.uptime_handler.handle() self.fs_handler.handle() - self.inline_query_handler.handle() self.inline_swap_handler.handle() # check if Docker sock available try: diff --git a/app/core/handlers/inline_handlers/__init__.py b/app/core/handlers/inline_handlers/__init__.py index c0e0a3c2..e69de29b 100644 --- a/app/core/handlers/inline_handlers/__init__.py +++ b/app/core/handlers/inline_handlers/__init__.py @@ -1,8 +0,0 @@ -#!/usr/bin/python3 -""" -(c) Copyright 2024, Denis Rozhnovskiy -pyTeleMonBot - A simple Telegram bot designed to gather basic information about -the status of your local servers -""" - -from .inline_query_handler import InlineQueryHandler diff --git a/app/core/handlers/inline_handlers/inline_query_handler.py b/app/core/handlers/inline_handlers/inline_query_handler.py deleted file mode 100644 index 2662630e..00000000 --- a/app/core/handlers/inline_handlers/inline_query_handler.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/venv/bin/python3 -""" -(c) Copyright 2024, Denis Rozhnovskiy -PyTMBot - A simple Telegram bot designed to gather basic information about -the status of your local servers -""" -from telebot import types - -from app import bot_logger -from app.core.adapters.psutil_adapter import PsutilAdapter -from app.core.handlers.handler import Handler - - -class InlineQueryHandler(Handler): - def __init__(self, bot): - super().__init__(bot) - self.psutil_adapter = PsutilAdapter() - - def handle(self): - - @self.bot.callback_query_handler(func=lambda call: call.data == 'docker_image_update') - def docker_image_update(call: types.CallbackQuery): - """ - Get callback query - docker image update check - """ - try: - bot_logger.info( - self.bot_msg_tpl.HANDLER_START_TEMPLATE.format("callback_query_handler['docker_image_update']")) - self.bot.edit_message_text( - chat_id=call.message.chat.id, - message_id=call.message.message_id, - text="Test callback_query_handler['docker_image_update']" - ) - - except ValueError: - raise self.exceptions.PyTeleMonBotHandlerError(self.bot_msg_tpl.VALUE_ERR_TEMPLATE) - except self.TemplateError: - raise self.exceptions.PyTeleMonBotTemplateError(self.bot_msg_tpl.TPL_ERR_TEMPLATE) diff --git a/app/core/middleware/auth.py b/app/core/middleware/auth.py index 01efe647..372989ac 100644 --- a/app/core/middleware/auth.py +++ b/app/core/middleware/auth.py @@ -26,9 +26,9 @@ def __init__(self) -> None: """Initialize the middleware""" super().__init__() self.bot_msg_tpl = MessageTpl() - self.update_types = ['message'] # Needed for correctly work middleware + self.update_types = ['message', 'inline_query'] # Needed for correctly work middleware - def pre_process(self, message: Message, data): + def pre_process(self, message: Message, data) -> CancelUpdate: """Check allowed users""" if message.from_user.id in config.allowed_user_ids: bot_logger.info( @@ -53,5 +53,5 @@ def pre_process(self, message: Message, data): ) return CancelUpdate() - def post_process(self, message: Message, data, exception): # Not needed in this case, but needed for method + def post_process(self, message: Message, data, exception) -> None: # Not needed in this case, but needed for method """Method need to correctly work middleware""" diff --git a/app/core/settings/loggers.py b/app/core/settings/loggers.py index ba086512..d72b56c3 100644 --- a/app/core/settings/loggers.py +++ b/app/core/settings/loggers.py @@ -8,11 +8,9 @@ class MessageTpl: """Template for logs""" - ACCESS_SUCCESS = "Request from: {0}, user_id {1}. Accepted." - ERROR_ACCESS_LOG_TEMPLATE = ("Request from: {0} user_id {1}. Ignored. " - "Reason: user_id not allowed (see BotSettings class in app/settings/bot_settings.py)") - ERROR_USER_BLOCKED_TEMPLATE = "Sorry, you don't have the rights to access this bot...(" - INFO_USER_SESSION_START_TEMPLATE = "user: {0} user_id: {1} handler: {2}" - VALUE_ERR_TEMPLATE = "Invalid message format" - TPL_ERR_TEMPLATE = "Error parsing template" - HANDLER_START_TEMPLATE = "Start handling session. User: {0}, user_id: {1}, lang: {2}, is_bot: {3}" + ACCESS_SUCCESS: str = "Request from: {0}, user_id {1}. Accepted." + ERROR_ACCESS_LOG_TEMPLATE: str = "Request from: {0} user_id {1}. Ignored. Reason: user_id not allowed." + ERROR_USER_BLOCKED_TEMPLATE: str = "You do not have permission to access this service. I apologize." + VALUE_ERR_TEMPLATE: str = "Invalid message format" + TPL_ERR_TEMPLATE: str = "Error parsing template" + HANDLER_START_TEMPLATE: str = "Start handling session. User: {0}, user_id: {1}, lang: {2}, is_bot: {3}" diff --git a/app/main.py b/app/main.py index e61d1349..e903aef3 100644 --- a/app/main.py +++ b/app/main.py @@ -42,7 +42,7 @@ def _start_polling(self): timeout=60, long_polling_timeout=60, skip_pending=True, - logger_level=None + logger_level=bot_logger.level ) except (ReadTimeout, HTTPError, ConnectionError, BaseHTTPError) as e: self.bot.stop_polling() @@ -52,8 +52,7 @@ def _start_polling(self): continue except telebot.apihelper.ApiTelegramException as e: self.bot.stop_polling() - bot_logger.debug(f'{e}. Retry after {self.sleep_time} seconds.') - bot_logger.error(f'Telegram API error. Retry after {self.sleep_time} seconds.') + bot_logger.error(f'{e}. Retry after {self.sleep_time} seconds.') sleep(self.sleep_time) continue except Exception as e: diff --git a/dev.Dockerfile b/dev.Dockerfile deleted file mode 100644 index 569737e3..00000000 --- a/dev.Dockerfile +++ /dev/null @@ -1,84 +0,0 @@ -####################################### -# pyTMbot Dockerfile (based on Alpine) -# image size: ~ 90Mb -# https://github.com/orenlab/pytmbot -####################################### - -# Set Alpine tag version for first and second stage -ARG IMAGE_VERSION_FIRST=3.12.3-alpine3.19 -ARG IMAGE_VERSION_SECOND=3.19.1 - -# First stage -FROM python:$IMAGE_VERSION_FIRST AS builder -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 - -COPY requirements.txt . - -# Update base os components and install all deps (need to build psutil) -RUN apk --no-cache update && \ - apk --no-cache upgrade && \ - apk --no-cache add gcc python3-dev musl-dev linux-headers - -# Install dependencies to the venv path -RUN python$PYTHON_VERSION -m venv --without-pip venv -RUN pip install --no-cache --target="/venv/lib/python$PYTHON_VERSION/site-packages" -r requirements.txt - -RUN python -m pip uninstall pip setuptools python3-wheel python3-dev -y - -# Second unnamed stage -FROM alpine:$IMAGE_VERSION_SECOND -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 - -# Add Timezone support in Alpine image -RUN apk --no-cache add tzdata - -# App workdir -WORKDIR /opt/pytmbot/ - -# Setup env var -ENV PYTHONUNBUFFERED=1 -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONPATH=/opt/pytmbot -ENV PATH=/venv/bin:$PATH - -# Сopy only the necessary python files and directories from first stage -COPY --from=builder /usr/local/bin/python3 /usr/local/bin/python3 -COPY --from=builder /usr/local/bin/python$PYTHON_VERSION /usr/local/bin/python$PYTHON_VERSION -COPY --from=builder /usr/local/lib/python$PYTHON_VERSION /usr/local/lib/python$PYTHON_VERSION -COPY --from=builder /usr/local/lib/libpython$PYTHON_VERSION.so.1.0 /usr/local/lib/libpython$PYTHON_VERSION.so.1.0 -COPY --from=builder /usr/local/lib/libpython3.so /usr/local/lib/libpython3.so - -# Copy only the dependencies installation from the first stage image -COPY --from=builder /venv /venv - -# Copy .pytmbotenv file with token (prod, dev) -COPY .pytmbotenv /opt/pytmbot/ - -# Copy lisence -COPY LICENSE /opt/pytmbot/ - -# Copy bot files -COPY ./app ./app/ -COPY ./logs /opt/logs/ - - -# Update base os components -RUN apk --no-cache update && \ - apk --no-cache upgrade && \ -# activate venv - source /venv/bin/activate && \ -# forward logs to Docker's log collector - ln -sf /dev/stdout /opt/logs/pytmbot.log - -# Run app -# !!! needed set log level: -# - DEBUG -# - INFO (default) -# - ERROR -# - CRITICAL -# !!! needed set pyTMBot mode: -# - dev -# - prod (default) -CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=dev" ] diff --git a/docker-compose.yml b/docker-compose.yml index 051f4e7d..cd5e2ffb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,9 @@ version: "3.9" services: pytmbot: - image: "orenlab/pytmbot:latest" container_name: "pytmbot" build: + target: prod dockerfile: Dockerfile restart: always pid: 'host' diff --git a/docs/docker.md b/docs/docker.md index 9f7d93f9..d2e94ff4 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -39,29 +39,13 @@ Video demo see in YouTube Shorts [here](https://youtube.com/shorts/81RE_PNjxLQ?f - Let's create the necessary files: -For stable tag `0.0.5`, `latest`: - -```bash -sudo -i -cd /root/ -touch .env -``` - -For over tag (`ubuntu-dev`, `alpine-dev`): - ```bash sudo -i cd /root/ touch .pytmbotenv ``` -Then, for stable tag `0.0.5`, `latest`: - -```bash -nano .env -``` - -or for over tag (`ubuntu-dev`, `alpine-dev`):: +Then, ```bash nano .pytmbotenv @@ -70,41 +54,18 @@ nano .pytmbotenv And we insert the following content, first replacing ``: ```bash -# Prod bot token +# Prod bot token: BOT_TOKEN= -# Add your telegram IDs. And your bot too! +# Add your telegram IDs: ALLOWED_USER_IDS=[00000000000, 00000000000] # Set Docker Socket o TCP param. Usually: unix:///var/run/docker.sock: DOCKER_HOST='' -# Set Podman Socket o TCP param. Usually: unix:///run/user/1000/podman/podman.sock -PODMAN_HOST='' ``` ## 🔌 Run bot To launch a Docker container: -For stable tag `0.0.5`, `latest`: - -```bash -sudo docker run -d -m 100M \ --v /var/run/docker.sock:/var/run/docker.sock:ro \ --v /root/.env:/opt/pytmbot/.env:ro \ ---env TZ="Asia/Yekaterinburg" \ ---restart=always \ ---name=pytmbot \ ---pid=host \ ---security-opt=no-new-privileges \ -orenlab/pytmbot:latest -``` - -##### **Note** - -_Please don't forget to specify your time zone! You can find a list of available time zones, for -example, [here](https://manpages.ubuntu.com/manpages/trusty/man3/DateTime::TimeZone::Catalog.3pm.html)_ - -For over tag version (`ubuntu-dev`, `alpine-dev`). Please remember to check and change the tag as necessary: - ```bash sudo docker run -d -m 100M \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ @@ -114,18 +75,17 @@ sudo docker run -d -m 100M \ --name=pytmbot \ --pid=host \ --security-opt=no-new-privileges \ -orenlab/pytmbot:alpine-dev +orenlab/pytmbot:latest ``` -##### **Note** +##### **Note:** _Please don't forget to specify your time zone! You can find a list of available time zones, for example, [here](https://manpages.ubuntu.com/manpages/trusty/man3/DateTime::TimeZone::Catalog.3pm.html)_ ##### **Note:** -_This difference in the naming convention for environment files will be removed with the release of version 0.0.6, which -is expected in early June 2024._ +_Please don't forget to specify Tag version!_ ## 🚀 Bot logs diff --git a/docs/installation.md b/docs/installation.md index 6865fcab..b71bf69a 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -43,31 +43,19 @@ This wizard will generate the necessary configuration file for you: You can leave the steps with the default settings by simply pressing "Enter". -If needed, set log level and operational mode in `Dockerfile`: - -```dockerfile -# run app -# !!! needed set log level: -# - DEBUG -# - INFO (default) -# - ERROR -# - CRITICAL -# !!! needed set pyTMBot mode: -# - dev -# - prod (default) -CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=prod" ] -``` - ## 💰 Run bot To build a Docker image: ```bash cd ~/pytmbot -docker build -t orenlab/pytmbot:latest . -``` -*Also, available in the root of the project is a Dockerfile based on the Ubuntu image: ubuntu.Dockerfile* +# To launch with a production token. Default way: +docker --target selfbuild_prod build -t orenlab/pytmbot:latest . + +# To launch with a development token. Only for development: +docker --target selfbuild_dev build -t orenlab/pytmbot:latest . +``` To launch a Docker container: @@ -87,7 +75,7 @@ orenlab/pytmbot:latest _Please don't forget to specify your time zone! You can find a list of available time zones, for example, [here](https://manpages.ubuntu.com/manpages/trusty/man3/DateTime::TimeZone::Catalog.3pm.html)_ -Docker image size ~90,5 Мб. +Docker image size ~79 Мб. ## 🛠 Logs diff --git a/hub.Dockerfile b/hub.Dockerfile new file mode 100644 index 00000000..879d7d62 --- /dev/null +++ b/hub.Dockerfile @@ -0,0 +1,84 @@ +############################################################# +## pyTMbot Dockerfile +# https://github.com/orenlab/pytmbot +# +# To launch with a production token. Default way: +# docker --target prod build -t orenlab/pytmbot:latest . +############################################################# + +# Set base images tag +ARG PYTHON_IMAGE=3.12.3-alpine3.19 +ARG ALPINE_IMAGE=3.19.1 + +######################################################################################################################## +######################### BUILD ALPINE BASED IMAGE ##################################################################### +######################################################################################################################## + +# Zero Alpine stage - setup base image +FROM alpine:${ALPINE_IMAGE} AS alpine_base + +# Update base os components +RUN apk --no-cache update && \ + apk --no-cache upgrade && \ +# Add Timezone support in Alpine image + apk --no-cache add tzdata + +# App workdir +WORKDIR /opt/pytmbot/ + +# Setup env var +ENV PYTHONUNBUFFERED=1 +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONPATH=/opt/pytmbot +ENV PATH=/venv/bin:$PATH + +# Copy lisence +COPY LICENSE /opt/pytmbot/ + +# Copy bot files +COPY ./app ./app/ +COPY ./logs /opt/logs/ + +# First Alpine stage - build Python deps +FROM python:${PYTHON_IMAGE} AS builder + +# Python version (minimal - 3.12) +ARG PYTHON_VERSION=3.12 + +COPY requirements.txt . + +# Install all deps (need to build psutil) +RUN apk --no-cache add gcc python3-dev musl-dev linux-headers + +# Install dependencies to the venv path +RUN python${PYTHON_VERSION} -m venv --without-pip venv +RUN pip install --no-cache-dir --no-deps --target="/venv/lib/python${PYTHON_VERSION}/site-packages" -r requirements.txt + +RUN python${PYTHON_VERSION} -m pip uninstall pip setuptools python3-wheel python3-dev musl-dev -y + +# Second Alpine stage - based on the base stage. Setup bot +FROM alpine_base AS reliase_base + +# Python version (minimal - 3.12) +ARG PYTHON_VERSION=3.12 + +# Сopy only the necessary python files and directories from first stage +COPY --from=builder /usr/local/bin/python3 /usr/local/bin/python3 +COPY --from=builder /usr/local/bin/python${PYTHON_VERSION} /usr/local/bin/python${PYTHON_VERSION} +COPY --from=builder /usr/local/lib/python${PYTHON_VERSION} /usr/local/lib/python${PYTHON_VERSION} +COPY --from=builder /usr/local/lib/libpython${PYTHON_VERSION}.so.1.0 /usr/local/lib/libpython${PYTHON_VERSION}.so.1.0 +COPY --from=builder /usr/local/lib/libpython3.so /usr/local/lib/libpython3.so + +# Copy only the dependencies installation from the first stage image +COPY --from=builder /venv /venv + +# activate venv +RUN source /venv/bin/activate && \ +# forward logs to Docker's log collector + ln -sf /dev/stdout /opt/logs/pytmbot.log + + +# Target for CI/CD image, --mode = prod +FROM reliase_base AS prod + +CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=prod" ] diff --git a/hub.alpine.Dockerfile b/hub.alpine.Dockerfile deleted file mode 100644 index d3b71e1e..00000000 --- a/hub.alpine.Dockerfile +++ /dev/null @@ -1,85 +0,0 @@ -####################################### -# pyTMbot Dockerfile (based on Alpine) -# image size: ~ 90Mb -# https://github.com/orenlab/pytmbot -####################################### - -# Set Alpine tag version for first and second stage -ARG IMAGE_VERSION_FIRST=3.12.3-alpine3.19 -ARG IMAGE_VERSION_SECOND=3.19.1 - -# First stage -FROM python:$IMAGE_VERSION_FIRST AS builder -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 - -COPY requirements.txt . - -# Update base os components and install all deps (need to build psutil) -RUN apk --no-cache update && \ - apk --no-cache upgrade && \ - apk --no-cache add gcc python3-dev musl-dev linux-headers - -# Install dependencies to the venv path -RUN python$PYTHON_VERSION -m venv --without-pip venv -RUN pip install --no-cache --target="/venv/lib/python$PYTHON_VERSION/site-packages" -r requirements.txt - -RUN python -m pip uninstall pip setuptools python3-wheel python3-dev -y - -# Second unnamed stage -FROM alpine:$IMAGE_VERSION_SECOND -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 - -# Add Timezone support in Alpine image -RUN apk --no-cache add tzdata - -# App workdir -WORKDIR /opt/pytmbot/ - -# Setup env var -ENV PYTHONUNBUFFERED=1 -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONPATH=/opt/pytmbot -ENV PATH=/venv/bin:$PATH - -# Сopy only the necessary python files and directories from first stage -COPY --from=builder /usr/local/bin/python3 /usr/local/bin/python3 -COPY --from=builder /usr/local/bin/python$PYTHON_VERSION /usr/local/bin/python$PYTHON_VERSION -COPY --from=builder /usr/local/lib/python$PYTHON_VERSION /usr/local/lib/python$PYTHON_VERSION -COPY --from=builder /usr/local/lib/libpython$PYTHON_VERSION.so.1.0 /usr/local/lib/libpython$PYTHON_VERSION.so.1.0 -COPY --from=builder /usr/local/lib/libpython3.so /usr/local/lib/libpython3.so - -# Copy only the dependencies installation from the first stage image -COPY --from=builder /venv /venv - -# Copy lisence -COPY LICENSE /opt/pytmbot - -# Copy bot files -COPY ./app ./app/ -COPY ./logs /opt/logs/ - -# Update base os components -RUN apk --no-cache update && \ - apk --no-cache upgrade && \ -# activate venv - source /venv/bin/activate && \ -# forward logs to Docker's log collector - ln -sf /dev/stdout /opt/logs/pytmbot.log - -# Label docker image -LABEL version="alpine-dev" -LABEL maintaner="Orenlab " -LABEL github-repo="https://github.com/orenlab/pytmbot/" - -# Run app -# !!! needed set log level: -# - DEBUG -# - INFO (default) -# - ERROR -# - CRITICAL -# !!! needed set pyTMBot mode: -# - dev -# - prod (default) -CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=prod" ] diff --git a/hub.ubuntu.Dockerfile b/hub.ubuntu.Dockerfile deleted file mode 100644 index 0a3fd78c..00000000 --- a/hub.ubuntu.Dockerfile +++ /dev/null @@ -1,88 +0,0 @@ -####################################### -# pyTMbot Dockerfile (based on Ubuntu) -# image size: ~ 180Mb -# https://github.com/orenlab/pytmbot -####################################### - -# Set Ubuntu tag version -ARG IMAGE_VERSION=24.04 - -# First stage -FROM ubuntu:${IMAGE_VERSION} AS builder -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 -ARG DEBIAN_FRONTEND=noninteractive - -# Update base os components and install all deps (need to build psutil) -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - python3 \ - python3-venv \ - python3-pip \ - python3-wheel \ - python3-dev \ - build-essential \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && apt-get autoclean -y - -# Copy app deps -COPY requirements.txt . - -# Install dependencies to the venv path -RUN python${PYTHON_VERSION} -m venv --without-pip venv -RUN python${PYTHON_VERSION} -m pip install --target="/venv/lib/python${PYTHON_VERSION}/site-packages" \ - -r requirements.txt - -RUN apt-get remove -y python3-pip python3-wheel python3-dev build-essential - -# Second unnamed stage -FROM ubuntu:$IMAGE_VERSION -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 -ARG DEBIAN_FRONTEND=noninteractive - -# Update base os components and install minimal deps -RUN apt-get update && apt-get upgrade -y && apt-get clean && \ - apt-get install -y --no-install-recommends \ - python3 \ - && apt-get clean \ - && rm -rf /var/cache/apt/archives /var/lib/apt/lists/* - -# App workdir -WORKDIR /opt/pytmbot/ - -# Setup env var -ENV PYTHONUNBUFFERED=1 -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONPATH=/opt/pytmbot -ENV PATH=/venv/bin:$PATH - -# Copy only the dependencies installation from the first stage image -COPY --from=builder /venv /venv - -# Copy lisence -COPY LICENSE /opt/pytmbot - -# Copy bot files -COPY ./app ./app/ -COPY ./logs /opt/logs/ - -# forward logs to Docker's log collector -RUN ln -sf /dev/stdout /opt/logs/pytmbot.log - -# Label docker image -LABEL version="ubuntu-dev" -LABEL maintaner="Orenlab " -LABEL github-repo="https://github.com/orenlab/pytmbot/" - -# Run app -# !!! needed set log level: -# - DEBUG -# - INFO (default) -# - ERROR -# - CRITICAL -# !!! needed set pyTMBot mode: -# - dev -# - prod (default) -CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=prod" ] diff --git a/poetry.lock b/poetry.lock index d8a88d5a..d878a0ce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "annotated-types" -version = "0.6.0" +version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" files = [ - {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, - {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] [[package]] @@ -148,38 +148,42 @@ files = [ [[package]] name = "docker" -version = "7.0.0" +version = "7.1.0" description = "A Python library for the Docker Engine API." optional = false python-versions = ">=3.8" files = [ - {file = "docker-7.0.0-py3-none-any.whl", hash = "sha256:12ba681f2777a0ad28ffbcc846a69c31b4dfd9752b47eb425a274ee269c5e14b"}, - {file = "docker-7.0.0.tar.gz", hash = "sha256:323736fb92cd9418fc5e7133bc953e11a9da04f4483f828b527db553f1e7e5a3"}, + {file = "docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"}, + {file = "docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c"}, ] [package.dependencies] -packaging = ">=14.0" pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} requests = ">=2.26.0" urllib3 = ">=1.26.0" [package.extras] +dev = ["coverage (==7.2.7)", "pytest (==7.4.2)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.1.0)", "ruff (==0.1.8)"] +docs = ["myst-parser (==0.18.0)", "sphinx (==5.1.1)"] ssh = ["paramiko (>=2.4.3)"] websockets = ["websocket-client (>=1.3.0)"] [[package]] name = "emoji" -version = "2.11.1" +version = "2.12.1" description = "Emoji for Python" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = ">=3.7" files = [ - {file = "emoji-2.11.1-py2.py3-none-any.whl", hash = "sha256:b7ba25299bbf520cc8727848ae66b986da32aee27dc2887eaea2bff07226ce49"}, - {file = "emoji-2.11.1.tar.gz", hash = "sha256:062ff0b3154b6219143f8b9f4b3e5c64c35bc2b146e6e2349ab5f29e218ce1ee"}, + {file = "emoji-2.12.1-py3-none-any.whl", hash = "sha256:a00d62173bdadc2510967a381810101624a2f0986145b8da0cffa42e29430235"}, + {file = "emoji-2.12.1.tar.gz", hash = "sha256:4aa0488817691aa58d83764b6c209f8a27c0b3ab3f89d1b8dceca1a62e4973eb"}, ] +[package.dependencies] +typing-extensions = ">=4.7.0" + [package.extras] -dev = ["coverage", "coveralls", "pytest"] +dev = ["coverage", "pytest (>=7.4.4)"] [[package]] name = "humanize" @@ -292,17 +296,6 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] -[[package]] -name = "packaging" -version = "24.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, -] - [[package]] name = "podman" version = "5.0.0" @@ -615,13 +608,13 @@ files = [ [[package]] name = "requests" -version = "2.31.0" +version = "2.32.2" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.2-py3-none-any.whl", hash = "sha256:fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c"}, + {file = "requests-2.32.2.tar.gz", hash = "sha256:dd951ff5ecf3e3b3aa26b40703ba77495dab41da839ae72ef3c8e5d8e2433289"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 71c64d95..364929eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyTMBot" -version = "0.0.5" +version = "0.0.6-dev" description = "A simple Telegram bot designed to gather basic information about the status of your local computers and/or servers from Glances" authors = ["Denis Rozhnovskiy "] readme = "README.md" diff --git a/requirements.txt b/requirements.txt index 96e0020f..d5c373f9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,22 +1,19 @@ -annotated-types==0.6.0 +annotated-types==0.7.0 certifi==2024.2.2 charset-normalizer==3.3.2 -docker==7.0.0 -emoji==2.11.1 +docker==7.1.0 +emoji==2.12.1 humanize==4.9.0 idna==3.7 Jinja2==3.1.4 MarkupSafe==2.1.5 -packaging==24.0 -podman==5.0.0 psutil==5.9.8 pydantic==2.7.1 pydantic-settings==2.2.1 pydantic_core==2.18.2 pyTelegramBotAPI==4.18.1 python-dotenv==1.0.1 -pyxdg==0.28 -requests==2.31.0 +requests==2.32.2 telebot==0.0.5 typing_extensions==4.11.0 urllib3==2.2.1 diff --git a/ubuntu.Dockerfile b/ubuntu.Dockerfile deleted file mode 100644 index 0a98794a..00000000 --- a/ubuntu.Dockerfile +++ /dev/null @@ -1,88 +0,0 @@ -####################################### -# pyTMbot Dockerfile (based on Ubuntu) -# image size: ~ 180Mb -# https://github.com/orenlab/pytmbot -####################################### - -# Set Ubuntu tag version -ARG IMAGE_VERSION=24.04 - -# First stage -FROM ubuntu:${IMAGE_VERSION} AS builder -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 -ARG DEBIAN_FRONTEND=noninteractive - -# Update base os components and install all deps (need to build psutil) -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - python3 \ - python3-venv \ - python3-pip \ - python3-wheel \ - python3-dev \ - build-essential \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && apt-get autoclean -y - -# Copy app deps -COPY requirements.txt . - -# Install dependencies to the venv path -RUN python${PYTHON_VERSION} -m venv --without-pip venv -RUN python${PYTHON_VERSION} -m pip install --target="/venv/lib/python${PYTHON_VERSION}/site-packages" \ - -r requirements.txt - -RUN apt-get remove -y python3-pip python3-wheel python3-dev build-essential - -# Second unnamed stage -FROM ubuntu:$IMAGE_VERSION -# Python version (minimal - 3.12) -ARG PYTHON_VERSION=3.12 -ARG DEBIAN_FRONTEND=noninteractive - -# Update base os components and install minimal deps -RUN apt-get update && apt-get upgrade -y && apt-get clean && \ - apt-get install -y --no-install-recommends \ - python3 \ - && apt-get clean \ - && rm -rf /var/cache/apt/archives /var/lib/apt/lists/* - -# App workdir -WORKDIR /opt/pytmbot/ - -# Setup env var -ENV PYTHONUNBUFFERED=1 -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONPATH=/opt/pytmbot -ENV PATH=/venv/bin:$PATH -# Setup time zone (can ovveride on docker run args) -ENV TZ="Asia/Yekaterinburg" - -# Copy only the dependencies installation from the first stage image -COPY --from=builder /venv /venv - -# Copy .pytmbotenv file with token (prod, dev) -COPY .pytmbotenv /opt/pytmbot - -# Copy lisence -COPY LICENSE /opt/pytmbot - -# Copy bot files -COPY ./app ./app/ -COPY ./logs /opt/logs/ - -# forward logs to Docker's log collector -RUN ln -sf /dev/stdout /opt/logs/pytmbot.log - -# Run app -# !!! needed set log level: -# - DEBUG -# - INFO (default) -# - ERROR -# - CRITICAL -# !!! needed set pyTMBot mode: -# - dev -# - prod (default) -CMD [ "/venv/bin/python3", "app/main.py", "--log-level=INFO", "--mode=prod" ]