├── .dockerignore ├── .gitignore ├── Dockerfile ├── Dockerfile.nats ├── README.md └── docker-compose.yml /.dockerignore: -------------------------------------------------------------------------------- 1 | # Игнорируем каталоги с зависимостями и кэшем Python 2 | __pycache__/ 3 | *.pyc 4 | *.pyo 5 | venv/ 6 | 7 | # Игнорируем файлы и каталоги Git 8 | .git/ 9 | 10 | # Игнорируем каталог с логами 11 | logs/ 12 | 13 | # Игнорируем временные директории и файлы 14 | tmp/ 15 | 16 | # Осторожно с исключением файлов конфигурации и секретов. 17 | # Если эти файлы необходимы для запуска вашего приложения, их исключение может привести к сбоям. 18 | # *.config 19 | # *.env 20 | # *.secret 21 | 22 | # Игнорируем директории и файлы, созданные IDE или текстовыми редакторами 23 | .vscode/ 24 | .idea/ 25 | 26 | # Добавьте другие папки и файлы, которые не должны быть включены в ваш Docker-образ 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Игнорируем каталоги с зависимостями и кэшем Python 2 | __pycache__/ 3 | *.pyc 4 | *.pyo 5 | venv/ 6 | 7 | # Игнорируем локальные конфигурационные файлы и секреты 8 | *.config 9 | *.env 10 | *.secret 11 | 12 | # Игнорируем каталог с логами 13 | logs/ 14 | 15 | # Игнорируем каталог с бинарными файлами и дистрибутивами 16 | dist/ 17 | *.egg-info/ 18 | 19 | # Игнорируем IDE-специфичные файлы (например, для PyCharm) 20 | .idea/ 21 | .vscode/ 22 | 23 | 24 | # Если есть тестовые данные, которые не должны попадать в репозиторий 25 | # test_data/ 26 | 27 | # Добавьте другие папки и файлы, которые не должны быть включены в ваш Git-репозитарий 28 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Используем официальный образ Python 2 | FROM python:3.11.5 3 | 4 | # Устанавливаем рабочую директорию в контейнере 5 | WORKDIR /app 6 | 7 | # Копируем зависимости и устанавливаем их 8 | COPY requirements.txt . 9 | RUN pip install --upgrade pip setuptools 10 | RUN pip install -r requirements.txt 11 | RUN chmod 755 . 12 | 13 | # Копируем исходный код в контейнер 14 | COPY . . 15 | 16 | # Указываем команду для запуска приложения 17 | CMD ["python", "app.py"] # Указываем название вашего главного файла 18 | -------------------------------------------------------------------------------- /Dockerfile.nats: -------------------------------------------------------------------------------- 1 | # Используем базовый образ Debian 2 | FROM debian:bullseye-slim 3 | 4 | # Устанавливаем необходимые пакеты (wget и tar) - для загрузки и распаковки наших образов 5 | RUN apt-get update && \ 6 | apt-get install -y wget tar 7 | 8 | # Загружаем и устанавливаем nats-server 9 | RUN wget https://github.com/nats-io/nats-server/releases/download/v2.9.15/nats-server-v2.9.15-linux-amd64.tar.gz && \ 10 | tar -zxf nats-server-*.tar.gz && \ 11 | cp nats-server-*-linux-amd64/nats-server /usr/bin/ && \ 12 | rm -rf nats-server-*-linux-amd64 nats-server-*.tar.gz 13 | 14 | # Загружаем и устанавливаем natscli 15 | RUN wget https://github.com/nats-io/natscli/releases/download/v0.0.35/nats-0.0.35-amd64.deb && \ 16 | dpkg -i nats-0.0.35-amd64.deb && \ 17 | rm nats-0.0.35-amd64.deb 18 | 19 | # Команда для запуска NATS сервера с JetStream и другими параметрами 20 | CMD ["nats-server", "-js", "--store_dir", "/app/data", "--net", "nats_server", "--addr", "0.0.0.0", "--port", "4222", "--http_port", "8222", "--debug", "--trace"] 21 | # Как можете видеть, я запускаю сервер с параметром --net nats_server, так как так у меня называется служба в docker-compose.yml 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Настраиваем сервер Linux (Ubuntu/Debian) под ТГ-бота вебхук (FastAPI + Uvicorn). 2 | **Стэк для бота:** Postgres, Redis, Nats и др.. 3 | **Стэк на сервере:** Git, Docker (docker-compose), Nginx, Certbot, Pyenv, Cron 4 | Cron и Pyenv были мной добавлены отдельно, а не в докере, так как не разобрался с корректным запуском крона в докере, при котором можно смотреть логи крона. Если вы знаете, как корректно запускать крон в докере, буду признателен за комментарии. (https://t.me/EVGENIY_JEM) 5 | 6 | Я понимаю, что в эпоху GPT многие инструкции становятся не нужны, но чтобы сэкономить время, в первую очередь самому себе, я набросал мануал, который выполнил на последнем проекте. 7 | ВАЖНОЕ ЗАМЕЧАНИЕ! Я не считаю себя профессионалом и не считаю, что мой способ самый лучший и корректный. Данный мануал - это лишь личный опыт, а я не претендую на истину в последней инстанции. 8 | 9 | 10 | ## 1. Обновляем системные пакеты: 11 | sudo apt update 12 | sudo apt dist-upgrade 13 | sudo apt upgrade 14 | 15 | 16 | ## 2. Устанавливаем Git, Docker, и Nginx, и другие: 17 | sudo apt install git docker.io nginx docker-compose 18 | sudo apt install -y build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-openssl 19 | sudo systemctl enable docker 20 | 21 | 22 | ## 3. Настраиваем брандмауэр: 23 | Для того, чтобы серевер Telegram API мог достучаться до нашего бота, необходимо, чтобы были открыты входящие соединения. 24 | 25 | sudo ufw allow 'Nginx Full' 26 | Данная команда открывает входящий трафик по протоколу http и https. 27 | 28 | 29 | ## 4. Запускаем Nginx: 30 | nginx - это веб-сервер, который мы будем использовать для проксирования запросов от Telegram API к вашему вебхуку. 31 | 32 | sudo systemctl enable nginx 33 | sudo systemctl start nginx 34 | systemctl status nginx 35 | В выводе команды вы должны увидеть что-то вроде Active: active (running) 36 | 37 | 38 | ## 5. Настройка Nginx: 39 | ### a. Создайте файл конфигурации для вашего сайта в /etc/nginx/sites-available/: 40 | sudo nano /etc/nginx/sites-available/example.com 41 | ### b. Добавьте следующее содержимое в файл конфигурации: 42 | # Директивы для HTTP (80й порт) 43 | server { 44 | listen 80; # Слушать порт 80 (стандартный HTTP порт). 45 | server_name example.com; # Имя сервера (домен), для которого эта конфигурация применима. 46 | } 47 | 48 | # Директивы для HTTPS (443й порт) 49 | server { 50 | listen 443 ssl; # Слушать порт 443 (стандартный HTTPS порт) с SSL. 51 | server_name example.com; # Имя сервера (домен), для которого эта конфигурация применима. 52 | 53 | # Пути к файлам сертификата и ключа. 54 | # Данный блок должен заполниться автоматически после настройки SSL из пункта 7 55 | ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; 56 | ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; 57 | 58 | # Директивы для проксирования 59 | location / { # "location /" - Определяет, как обрабатывать запросы к корневому URL (/) 60 | proxy_pass http://localhost:YOUR_BOT_PORT; # proxy_pass - Куда перенаправлять входящие запросы. Порт, на котором работает ваш Telegram бот 61 | # Параметры ниже необязательны 62 | proxy_set_header Host $host; 63 | proxy_set_header X-Real-IP $remote_addr; 64 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 65 | } 66 | } 67 | 68 | Где example.com - это имя вашего домена, которое вам дал ваш хостинг. 69 | Замените YOUR_BOT_PORT на порт, на котором работает ваш Telegram бот (который вы пробросили из Docker-контейнера на хост-машину). 70 | 71 | ### c. Создайте символическую ссылку на этот файл в директории sites-enabled 72 | sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ 73 | ### d. Переименовать дефолтные настройки, во избежание конфликта. Либо закомментировать все строки в файле default: 74 | sudo mv /etc/nginx/sites-enabled/default /etc/nginx/sites-enabled/default.backup 75 | ### e. Проверьте конфигурацию Nginx: 76 | sudo nginx -t 77 | Если все в порядке, вы должны увидеть сообщение: `syntax is okay, test is successful` 78 | ### f. Перезапустите Nginx: 79 | sudo systemctl restart nginx 80 | 81 | 82 | ## 6. Устанавливаем Certbot для работы с SSL: 83 | sudo apt install certbot python3-certbot-nginx 84 | 85 | 86 | ## 7. Настройка SSL для Nginx: 87 | ### a. Запускаем Certbot для настройки SSL: 88 | sudo certbot --nginx -d example.com -d www.example.com 89 | Если не сработал вариант выше, то пробуем командой, но уже внутри certbot прописываем ваш домен: 90 | 91 | sudo certbot -–nginx 92 | ### b. Следуем инструкциям, чтобы настроить SSL для вашего домена. Там не сложно. 93 | Небольшое замечание! Сертификат выдается не на всю жизнь, либо настройте автоматическое получение нового через cron, либо не забудьте получить новый в конце срока жизни старого. 94 | 95 | 96 | ## 8. Установка вебхука для Telegram-бота: 97 | ### a. Обычно это делается внутри кода, в файле запуска бота. Задача дать понять Телеграму, что все обновления нужно слать вам на адрес вебхука. Но если вы не делали это в коде, то можно прямо с консоли отправить: 98 | curl -F "url=https://YOUR_DOMAIN/YOUR_WEBHOOK_PATH" https://api.telegram.org/botYOUR_BOT_TOKEN/setWebhook 99 | ### b. Проверить: 100 | curl https://api.telegram.org/botYOUR_BOT_TOKEN/getWebhookInfo 101 | В ответ должны быть показаны данные вашего вебхука 102 | 103 | 104 | ## 9. Для настройки докер контейнера делаем в корневой папке проекта файл Dockerfile: 105 | # Используем официальный образ Python 106 | FROM python:3.11.5 107 | 108 | # Устанавливаем рабочую директорию в контейнере 109 | WORKDIR /app 110 | 111 | # Копируем зависимости и устанавливаем их 112 | COPY requirements.txt . 113 | RUN pip install --upgrade pip setuptools 114 | RUN pip install -r requirements.txt 115 | RUN chmod 755 . 116 | 117 | # Копируем исходный код в контейнер 118 | COPY . . 119 | 120 | # Указываем команду для запуска приложения 121 | CMD ["python", "app.py"] # Указываем название вашего главного файла 122 | 123 | ## 10. Также там-же делаем файл .dockerignore со следующим содержанием: 124 | 125 | # Игнорируем каталоги с зависимостями и кэшем Python 126 | __pycache__/ 127 | *.pyc 128 | *.pyo 129 | venv/ 130 | 131 | # Игнорируем файлы и каталоги Git 132 | .git/ 133 | 134 | # Игнорируем каталог с логами 135 | logs/ 136 | 137 | # Игнорируем временные директории и файлы 138 | tmp/ 139 | 140 | # Осторожно с исключением файлов конфигурации и секретов. 141 | # Если эти файлы необходимы для запуска вашего приложения, их исключение может привести к сбоям. 142 | # *.config 143 | # *.env 144 | # *.secret 145 | 146 | # Игнорируем директории и файлы, созданные IDE или текстовыми редакторами 147 | .vscode/ 148 | .idea/ 149 | 150 | # Добавьте другие папки и файлы, которые не должны быть включены в ваш Docker-образ 151 | 152 | ## 11. Также там-же делаем файл .gitignore следующего содержания: 153 | 154 | # Игнорируем каталоги с зависимостями и кэшем Python 155 | __pycache__/ 156 | *.pyc 157 | *.pyo 158 | venv/ 159 | 160 | # Игнорируем локальные конфигурационные файлы и секреты 161 | *.config 162 | *.env 163 | *.secret 164 | 165 | # Игнорируем каталог с логами 166 | logs/ 167 | 168 | # Игнорируем каталог с бинарными файлами и дистрибутивами 169 | dist/ 170 | *.egg-info/ 171 | 172 | # Игнорируем IDE-специфичные файлы (например, для PyCharm) 173 | .idea/ 174 | .vscode/ 175 | 176 | 177 | # Если есть тестовые данные, которые не должны попадать в репозиторий 178 | # test_data/ 179 | 180 | # Добавьте другие папки и файлы, которые не должны быть включены в ваш Git-репозитарий 181 | 182 | 183 | ## 12. Также там-же делаем файл docker-compose.yml, в котором создаем наши службы, пробрасываем порты, перечисляем зависимости. Этот файл служит основой запуска вашего проекта. 184 | Мой предыдущий проект имел файл со следующим содержанием: бот, база данных postgres, база данных redis, nats сервер и nats воркер (для взаимодействия с nats сервером) 185 | В 19м пункте смотрите, как собирался контейнер для nats сервера. 186 | 187 | version: "3" 188 | services: 189 | имя_службы_бота: 190 | build: . 191 | container_name: имя_службы_бота 192 | ports: 193 | - "8080:8080" 194 | command: [ "python", "app.py" ] # app.py - Название главного файла проекта 195 | depends_on: 196 | - nats_server # указываем зависимость от NATS сервера 197 | - redis # добавляем зависимость от Redis 198 | - postgres # добавляем зависимость от PostgreSQL 199 | restart: always 200 | 201 | nats_worker: 202 | build: . 203 | container_name: nats_worker 204 | command: [ "python", "nats_worker.py" ] 205 | depends_on: 206 | - nats_server # указываем зависимость от NATS сервера 207 | - redis # добавляем зависимость от Redis 208 | - postgres # добавляем зависимость от PostgreSQL 209 | restart: always 210 | 211 | # Имейте в виду, что в конфиг файле бота в .env или settings.toml, смотря что используете, 212 | # адрес хоста должен быть не 127.0.0.1, а именем службы из вашего docker-compose: NATS_HOST='nats_server' 213 | nats_server: # Добавляем NATS сервер как новую службу. 214 | build: 215 | context: . 216 | dockerfile: Dockerfile.nats # Указываем путь к Dockerfile.nats в котором все настройки и параметры запуска (см. п.19) 217 | ports: 218 | - "4222:4222" # открываем порт для внешних соединений 219 | - "6222:6222" 220 | - "8222:8222" # Для HTTP мониторинга 221 | volumes: 222 | - "nats_data:/app/data" # Папка для хранения данных (в моем случае в папку проекта в папке data) 223 | # - "nats_logs:/app/logs" # Папка для логов (не обязательна) 224 | restart: always 225 | 226 | # Имейте в виду, что в конфиг файле бота в .env или settings.toml, смотря что используете, 227 | # адрес хоста должен быть не 127.0.0.1, а именем службы из вашего docker-compose: REDIS_HOST='redis' 228 | redis: # добавляем Redis сервер как новую службу 229 | image: "redis:latest" # можно указать конкретную версию вместо latest 230 | volumes: 231 | - redis_data:/usr/local/etc/redis 232 | ports: 233 | - "6379:6379" # открываем порт для внешних соединений 234 | restart: always 235 | 236 | # Имейте в виду, что в конфиг файле бота в .env или settings.toml, смотря что используете, 237 | # адрес хоста должен быть не 127.0.0.1, а именем службы из вашего docker-compose: POSTGRES_HOST='postgres' 238 | postgres: # добавляем PostgreSQL сервер как новую службу 239 | image: "postgres:latest" # можно указать конкретную версию вместо latest 240 | volumes: 241 | - postgres_data:/var/lib/postgresql/data 242 | environment: 243 | POSTGRES_DB: ${имя_переменной_из_env_файла} 244 | POSTGRES_USER: ${имя_переменной_из_env_файла} 245 | POSTGRES_PASSWORD: ${имя_переменной_из_env_файла} 246 | ports: 247 | - "5432:5432" # открываем порт для внешних соединений 248 | restart: always 249 | 250 | volumes: 251 | postgres_data: # объявляем volume для постоянного хранения данных PostgreSQL. Если не указать, то при остановке docker-compose и повторного запуска, ваши файлы пропадут 252 | nats_data: 253 | redis_data: 254 | 255 | 256 | ## 13. Я использую Git (GitHub) в качестве репозитария и считаю хорошей привычкой все делать через него. Также это позволяет удобно и быстро разворачивать проекты в новом месте. Для себя избрал самый быстрый и надежный способ – использовать SSH ключ, поэтому моя инструкция ниже. 257 | ### a. Далее создаем SSH ключ на сервере, если SSH ключ уже присутствует на сервер, то сразу к пункту “c”: 258 | ssh-keygen -t rsa -b 4096 -C "ваша почта, с которой вы регались на github" 259 | Просто нажимайте "Enter" для всех вопросов, если вы хотите использовать параметры по умолчанию. 260 | ### b. Запуск SSH-агента и добавление вашего ключа: 261 | eval "$(ssh-agent -s)" 262 | ssh-add ~/.ssh/id_rsa 263 | ### c. Копирование SSH-ключа в буфер обмена. Команда выведет ваш публичный SSH-ключ. Скопируйте его в буфер обмена: 264 | cat ~/.ssh/id_rsa.pub 265 | ### d. Добавление нового SSH-ключа на GitHub: 266 | Перейдите на GitHub и зайдите в "Settings" (находится в правом верхнем углу). 267 | В меню слева выберите "SSH and GPG keys" -> "New SSH key". 268 | Вставьте скопированный ключ в поле "Key" и дайте ему название. 269 | 270 | 271 | ## 14. Клонирование репозитория с использованием SSH: 272 | ### a. Перейдите в папку, в которой вы планируете размещать свои проекты. Я обычно создаю папку apps и все проекты клонирую туда: 273 | mkdir apps 274 | cd apps 275 | ### b. Запустите команду клонирования проекта, которую можно скопировать с GitHub, нажав зеленую кнопочку code, выбрав SSH: 276 | git clone git@github.com:ваше_имя_пользователя_github/название_проекта.git 277 | После этого сервер вас спросит, действительно ли доверяется этому ssh ключу, подтвердите и проект будет скопирован к вам на сервер в apps/название_проекта_из_github 278 | 279 | 280 | ## 15. Обновляемся, собираем и запускаем контейнер, смотрим логи: 281 | ### a. Перейдите в папку с проектом (см п. 14) 282 | cd apps/название_проекта 283 | ### b. Если вы внесли какие-то изменения в проект и необходимо их применить на сервере (если контейнер уже запущен, то сначала остановить): 284 | git pull 285 | ### c. Остановить запущенный контейнер: 286 | docker-compose down 287 | ### d. Собрать и запустить контейнер (с указанными аргументами контейнер пересобирается и работает, если сервер будет перезагружен): 288 | docker-compose up -d --build 289 | ### e. Если необходимо зайти внутрь запущенного контейнера и провести там какие-то манипуляции: 290 | docker exec -it container_id_or_name /bin/bash 291 | ### f. Если вы хотите видеть логи приложения: 292 | docker-compose logs -f имя_контейнера_из_docker-compose.yml 293 | 294 | 295 | ## 16. Alembic. 296 | Если в вашем проекте база данных, то таблицы должны быть размечены прежде, чем все заработает. Вы можете это сделать вручную, зайдя внутрь соответствующего контейнера (службы postgres из файла docker-compose.yml) или если вы используете миграцию от Alembic, то команды для запуска и разметки таблиц бд, не заходя внутрь контейнера: 297 | ### a. Создание новой миграции: 298 | docker exec -it container_id_or_name alembic revision --autogenerate -m "Initial migration" 299 | ### b. Применение новой миграции: 300 | docker exec -it container_id_or_name alembic upgrade head 301 | И не забудьте, что Alembic должен быть установлен в вашем контейнере. Если вы его добавляли в файл requirements.txt вашего проекта, то он конечно будет уже в контейнере. 302 | 303 | 304 | ## 17. Использование Pyenv (не для Docker, а именно на сервере). 305 | Pyenv позволяет установить несколько версий Python и переключаться между ними, если нужно. Если бы вопрос с Cron я смог решить в docker-compose, то не стал бы этим заморачиваться: 306 | ### a. Установка pyenv: 307 | curl https://pyenv.run | bash 308 | ### b. Добавляем pyenv в $PATH: 309 | echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc 310 | echo 'eval "$(pyenv init --path)"' >> ~/.bashrc 311 | source ~/.bashrc 312 | ### c. Теперь необходимо обновить файлы конфигурации вашей оболочки, чтобы pyenv автоматически загружался при старте. Откройте файл .bashrc в текстовом редакторе: 313 | nano ~/.bashrc 314 | ### d. Вставьте следующие строки в конец файла: 315 | export PYENV_ROOT="$HOME/.pyenv" 316 | command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" 317 | eval "$(pyenv init -)" 318 | eval "$(pyenv virtualenv-init -)" 319 | ### f. Сохраните изменения и закройте редактор. Примените изменения: 320 | source ~/.bashrc 321 | ### g. Устанавливаем Python: 322 | pyenv install 3.11.5 323 | ### h. Устанавливаем его как глобальную версию: 324 | pyenv global 3.11.5 325 | ### i. Теперь ваша система должна использовать выбранную версию Python по умолчанию. Вы можете проверить это, запустив: 326 | python --version 327 | Эта команда должна показать Python 3.11.x. 328 | 329 | 330 | ## 18. Использование Cron. 331 | Чтобы запускать какой-то файл по расписанию, необходимо, чтобы все библиотеки, используемые в этом файле были установлены в системе (в нашем случае в окружении Pyenv, которое в п.17 мы установили и настроили): 332 | ### a. Переходим в папку с проектом: 333 | cd путь_до_проекта/название_вашего_проекта 334 | ### b. Устанавливаем все необходимые библиотеки (зависимости): 335 | pip install -r requirements.txt 336 | ### c. Для дальнейшего использования cron нам необходимо знать в какой директории установлен питон: 337 | pyenv which python 338 | ### d. Открываем список заданий cron: 339 | crontab -e 340 | ### e. Добавляем вниз наше задание: 341 | */5 * * * * cd /home/ваше_имя_пользователя/ваш_путь/до_папки_проекта && /home/ ваше_имя_пользователя /.pyenv/versions/3.11.5/bin/python имя_запускаемого_файла.py >> /home/ваше_имя_пользователя/ваш_путь/до_папки_с_логами/cron.log 2>&1 342 | 343 | 0 0 * * * - это пример, для запуска каждый день в 00:00 344 | Здесь: 345 | • Первый 0 обозначает минуты (0 минут). 346 | • Второй 0 обозначает часы (0 часов, или полночь). 347 | • Звёздочки обозначают "любое значение" для дней месяца, месяцев и дней недели соответственно. 348 | 349 | 350 | ## 19. Для сборки docker контейнера nats сервера создаем в корне вашего проекта файл Dockerfile.nats следующего содержания: 351 | # Используем базовый образ Debian 352 | FROM debian:bullseye-slim 353 | 354 | # Устанавливаем необходимые пакеты (wget и tar) - для загрузки и распаковки наших образов 355 | RUN apt-get update && \ 356 | apt-get install -y wget tar 357 | 358 | # Загружаем и устанавливаем nats-server 359 | RUN wget https://github.com/nats-io/nats-server/releases/download/v2.9.15/nats-server-v2.9.15-linux-amd64.tar.gz && \ 360 | tar -zxf nats-server-*.tar.gz && \ 361 | cp nats-server-*-linux-amd64/nats-server /usr/bin/ && \ 362 | rm -rf nats-server-*-linux-amd64 nats-server-*.tar.gz 363 | 364 | # Загружаем и устанавливаем natscli 365 | RUN wget https://github.com/nats-io/natscli/releases/download/v0.0.35/nats-0.0.35-amd64.deb && \ 366 | dpkg -i nats-0.0.35-amd64.deb && \ 367 | rm nats-0.0.35-amd64.deb 368 | 369 | # Команда для запуска NATS сервера с JetStream и другими параметрами 370 | CMD ["nats-server", "-js", "--store_dir", "/app/data", "--net", "nats_server", "--addr", "0.0.0.0", "--port", "4222", "--http_port", "8222", "--debug", "--trace"] 371 | # Как можете видеть, я запускаю сервер с параметром --net nats_server, так как так у меня называется служба в docker-compose.yml 372 | 373 | Еще небольшое замечание. Если вы используете nats, то вы должны создавать stream. Либо делаете это динамически в коде, либо вручную, тогда в конец вышеприведенного докер файла необходимо добавить еще команду по запуску потока. Официальная документация по запуску потока тут: https://docs.nats.io/running-a-nats-service/nats_admin/jetstream_admin/streams 374 | 375 | 376 | 377 | - 378 | 379 | **Если вы хотели бы дополнить или что-то поправить, буду рад вашим комментариям https://t.me/EVGENIY_JEM** 380 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | имя_службы_бота: 4 | build: . 5 | container_name: имя_службы_бота 6 | ports: 7 | - "8080:8080" 8 | command: [ "python", "app.py" ] # app.py - Название главного файла проекта 9 | depends_on: 10 | - nats_server # указываем зависимость от NATS сервера 11 | - redis # добавляем зависимость от Redis 12 | - postgres # добавляем зависимость от PostgreSQL 13 | restart: always 14 | 15 | nats_worker: 16 | build: . 17 | container_name: nats_worker 18 | command: [ "python", "nats_worker.py" ] 19 | depends_on: 20 | - nats_server # указываем зависимость от NATS сервера 21 | - redis # добавляем зависимость от Redis 22 | - postgres # добавляем зависимость от PostgreSQL 23 | restart: always 24 | 25 | # Имейте в виду, что в конфиг файле бота в .env или settings.toml, смотря что используете, 26 | # адрес хоста должен быть не 127.0.0.1, а именем службы из вашего docker-compose: NATS_HOST='nats_server' 27 | nats_server: # Добавляем NATS сервер как новую службу. 28 | build: 29 | context: . 30 | dockerfile: Dockerfile.nats # Указываем путь к Dockerfile.nats в котором все настройки и параметры запуска (см. п.18) 31 | ports: 32 | - "4222:4222" # открываем порт для внешних соединений 33 | - "6222:6222" 34 | - "8222:8222" # Для HTTP мониторинга 35 | volumes: 36 | - "nats_data:/app/data" # Папка для хранения данных (в моем случае в папку проекта в папке data) 37 | # - "nats_logs:/app/logs" # Папка для логов (не обязательна) 38 | restart: always 39 | 40 | # Имейте в виду, что в конфиг файле бота в .env или settings.toml, смотря что используете, 41 | # адрес хоста должен быть не 127.0.0.1, а именем службы из вашего docker-compose: REDIS_HOST='redis' 42 | redis: # добавляем Redis сервер как новую службу 43 | image: "redis:latest" # можно указать конкретную версию вместо latest 44 | volumes: 45 | - redis_data:/usr/local/etc/redis 46 | ports: 47 | - "6379:6379" # открываем порт для внешних соединений 48 | restart: always 49 | 50 | # Имейте в виду, что в конфиг файле бота в .env или settings.toml, смотря что используете, 51 | # адрес хоста должен быть не 127.0.0.1, а именем службы из вашего docker-compose: POSTGRES_HOST='postgres' 52 | postgres: # добавляем PostgreSQL сервер как новую службу 53 | image: "postgres:latest" # можно указать конкретную версию вместо latest 54 | volumes: 55 | - postgres_data:/var/lib/postgresql/data 56 | environment: 57 | POSTGRES_DB: ${имя_переменной_из_env_файла} 58 | POSTGRES_USER: ${имя_переменной_из_env_файла} 59 | POSTGRES_PASSWORD: ${имя_переменной_из_env_файла} 60 | ports: 61 | - "5432:5432" # открываем порт для внешних соединений 62 | restart: always 63 | 64 | volumes: 65 | postgres_data: # объявляем volume для постоянного хранения данных PostgreSQL. Если не указать, то при остановке docker-compose и повторного запуска, ваши файлы пропадут 66 | nats_data: 67 | redis_data: 68 | --------------------------------------------------------------------------------