Код на салфетке
2.24K subscribers
749 photos
15 videos
2 files
792 links
Канал для тех, кому интересно программирование на Python и не только.

Сайт: https://pressanybutton.ru/
Чат: https://t.iss.one/+Li2vbxfWo0Q4ZDk6
Заметки автора: @writeanynotes

Реклама и взаимопиар: @Murzyev1995
Сотрудничество и др.: @proDreams
Download Telegram
- command: — Параметр определяет команду, которая будет выполнена при запуске контейнера, аналог CMD из Dockerfile. Команду разберём ниже.
- env_file: — Так же, как мы ранее указывали .env при запуске контейнера, указываем этот файл для сервиса Django.
- volumes: — Так же, как и с сервисом базы данных, указываем монтируемую директорию. Тут есть два варианта:- Вместо всей директории указать только монтируемые пути для static и media директорий, чтобы впоследствии дать доступ к ним веб-серверу.
- Указать всю директорию с проектом. Таким образом можно изменять файлы проекта "на лету", и для применения изменений достаточно будет перезагрузить контейнер с Django.



- depends_on: — Параметр, указывающий на зависимость от другого сервиса. В нашем случае это сервис базы данных. Это необходимо для того, чтобы сперва был запущен сервис с БД и только после этого сервис с Django.


Про команду запуска: первым аргументом идёт скрипт wait-for-it.sh. Далее передаём хост и порт базы данных. Обратите внимание, что в качестве хоста мы указываем имя сервиса базы данных. Таким образом, обращения сайта к базе данных будут происходить в пределах сервера. Специальный символ -- (double dash), является разделителем между двумя командами. Сперва выполняется команда до символа, затем команда после. Далее указываем, что запускаем uWSGI с конфигурационным файлом по указанному абсолютному пути внутри контейнера.


Сервис Telegram-бота.
Тут совсем просто и коротко.

Пропишем ключ bot со следующим содержимым:


bot:  
build: ./pressanybutton_bot
restart: always

Указываем откуда брать Dockerfile и политику перезапуска.


Подготовка NGINX.
Перед тем, как приступим к описанию сервиса с NGINX, необходимо подготовить его конфигурационный файл.

В директории project создадим директорию ssl. В эту директорию следует поместить SSL-сертификат и приватный ключ для используемого домена. Как получить сертификат, рассказано в посте "Certbot - бесплатный SSL-сертификат для сайта".

Затем в директории project, рядом с файлом docker-compose.yaml, создадим файл default.conf.template. В этом файле опишем конфигурацию веб-сервера.

У нас будет четыре блока конфигурации:

Первый будет блок upstream:


upstream pressanybutton {  
server unix:/code/pab_app.sock;
}

В нём указываем группу по имени pressanybutton. По этому имени будем обращаться в другом блоке для проксирования обращений. Внутри блока указываем, что сервером является Unix-сокет, который создаёт uWSGI в Django.

Следующий блок server прослушивает 80-й HTTP-порт и при обращении на домен по HTTP перенаправляет с 301-м HTTP-кодом на HTTPS протокол:


server {  
listen 80;
server_name www.pressanybutton.ru pressanybutton.ru;
return 301 https://$host$request_uri;
}

Далее ещё один блок переадресации: на этот раз прослушивается 443-й HTTPS-порт и при обращении на поддомен с www происходит переадресация на домен без www. Поскольку это HTTPS, в этом блоке указываем путь до SSL-сертификата и ключа:


server {  
listen 443 ssl;
ssl_certificate /code/ssl/cert.crt;
ssl_certificate_key /code/ssl/privkey.key;
server_name www.pressanybutton.ru;

return 301 https://pressanybutton.ru$request_uri;
}

Последний, самый большой и основной блок прослушивает 443-й HTTPS порт. Внутри блока также указываем:

- SSL-сертификат и его ключ.
- Вывод ошибок в терминал.
🔥4
- В параметре client_max_body_size указываем максимально допустимый размер загружаемого файла. В нашем случае это 100МБ.
- Указываем, что включено gzip-сжатие и настройки этого сжатия.
- Блок location / — В нём указываем, что используется uWSGI-сокет, на который происходят перенаправление со всех запросов на сайт.
- location /static/ и location /media/ — В них указываем, что если в пути запроса есть static или media, то необходимо отдавать файлы из соответствующих директорий. Также добавляем кэширование статических и медиа файлов на стороне клиента.



server {  
listen 443 ssl;
ssl_certificate /code/ssl/cert.pem;
ssl_certificate_key /code/ssl/privkey.pem;
server_name pressanybutton.ru;
error_log stderr warn;
access_log /dev/stdout main;
client_max_body_size 100M;

gzip on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_proxied any;
gzip_vary on;
gzip_types
application/javascript
application/json
application/ld+json
application/manifest+json
application/x-web-app-manifest+json
text/css
text/plain
text/xml
text/x-component
text/x-cross-stream;
gzip_disable "text/javascript";

location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass pressanybutton;
}

location /static/ {
alias /code/static/;
add_header Cache-Control "max-age=604800";
}
location /media/ {
alias /code/media/;
add_header Cache-Control "max-age=604800";
}
}

Конфигурация NGINX может быть разной в зависимости от конкретных потребностей проекта. Настройка кэширования, ограничения доступа и другие параметры могут быть изменены для повышения производительности и безопасности.


Сервис веб-сервера NGINX.
Последним сервисом опишем веб-сервер.

Пропишем ключ nginx со следующим содержимым:


nginx:  
image: nginx
restart: always
volumes:
- ./default.conf.template:/etc/nginx/templates/default.conf.template
- ./pressanybutton:/code/
- ./ssl:/code/ssl
ports:
- "80:80"
- "443:443"

Разберём параметры:

- volumes: — Прописываем три монтирования:- Монтируем файл конфигурации внутри контейнера.
- Монтируем директорию с Django. Нам это нужно для доступа к статическим и медиа файлам, а также к Unix-сокету.
- Монтируем директорию ssl для доступа к сертификатам внутри контейнера.



- ports: — Данный параметр указывает, какие порты будут доступны вне контейнера и с какими портами они связаны внутри контейнера. В данном случае прослушиваются и вещаются 80-й и 443-й порт — стандартные порты для веб.



Перед запуском.
Перед тем, как мы всё запустим, убедитесь, что в .env указаны верные параметры, например, хост базы данных это db, и что все файлы доступны.


Запуск Docker compose.
Для запуска Docker Compose достаточно выполнить команду:


sudo docker compose up -d

Разберём команду:

- sudo docker — Указывает, что мы обращаемся к приложению Docker с правами администратора (root).
- compose — Указывает, что нам необходим плагин Compose.
- up — Указывает, что мы хотим запустить Docker Compose-сервис из docker-compose.yaml, расположенного в этой директории.
- -d — Указывает, что мы запускаем сервис в фоновом режиме.


После выполнения команды начнётся скачивание и сборка образов.


Миграции и статика.
После того, как соберутся и запустятся сервисы, при переходе по адресу сайта может возникнуть ошибка, сообщающая о том, что таблицы в базе данных не найдены.
🔥4
Необходимо применить миграции. Для этого выполним следующие команды:


# Создадим миграции, если они не были созданы ранее.
sudo docker exec -it project-web-1 python /code/manage.py makemigrations

# Применим миграции.
sudo docker exec -it project-web-1 python /code/manage.py migrate

Разберём команды:

- exec — Указывает, что мы хотим выполнить команду внутри контейнера.
- -it — Указывает, что мы хотим интерактивный режим.
- project-web-1 — Имя контейнера.
- python /code/manage.py migrate — Команда, которую хотим выполнить внутри контейнера.


Если сейчас снова открыть сайт, он загрузится, но в нём могут отсутствовать стили и другая статика. Для решения этой проблемы выполним команду:


sudo docker exec -it project-web-1 python /code/manage.py collectstatic

Всё это можно сделать в исполняемом при сборке скрипте, но это тема для другого раза.


Дополнительно.

Остановка композ-сервиса.
Если вы хотите остановить и удалить все запущенные контейнеры, выполните команду:


sudo docker compose down


Логи контейнеров
Для просмотра логов запущенных контейнеров используйте команду:


sudo docker compose logs -f

После выполнения команды будут выведены логи всех контейнеров. Если необходимо посмотреть логи конкретного контейнера, сделать это можно, выполнив команду:


sudo docker logs имя_контейнера


Обновление образов.
Для обеспечения безопасности и стабильности проекта рекомендуется регулярно обновлять Docker образы и зависимости. Это можно сделать с помощью команды:


sudo docker compose pull

Эта команда обновит образы до последних версий, указанных в docker-compose.yaml.


Заключение.
Теперь вы знаете, как можно развернуть свой сайт на Django с использованием Docker Compose. На первый взгляд, всё это кажется сложным, и в процессе неизбежно возникнут трудности на разных этапах, но с каждым последующим разом начинает выполняться "на автомате". Вы начинаете понимать, где возникла ошибка и как её решить.

Данный пост – базовая инструкция, которую можно адаптировать и расширять в зависимости от специфики вашего проекта. Не забывайте регулярно обновлять ваши образы и контейнеры до последних версий для обеспечения безопасности и использования новых возможностей. С Docker Compose это делается довольно просто и эффективно.

На этом с Django мы не заканчиваем. Там ещё много всего, что можно сделать.



Файлы к посту, можно получить в боте по коду: 274821

Пост на сайте
Поддержать проект на Boosty
Поддержать проект в Telegram

#Docker #PostgreSQL #Django #AIOgram #Код_на_салфетке #NGINX #деплой #Гайд #разворачивание_проекта #Docker_compose
🔥4
В этот раз видео по шестой задаче!

Ссылка на задачу, если вы пропустили: https://t.iss.one/press_any_button/475

Видео версия "Что выведет этот код? №6":
https://youtube.com/shorts/NbwEAPnYjrg

Будем благодарны лайку и досмотру видео до конца, спасибо!
🔥7
Приветствуем!

Продолжаем рубрику "Вопросы и ответы"!

В течение недели вы в комментариях к этому посту можете задавать различные вопросы нашей команде. Вопросы могут быть о чём угодно (в рамках разумного): о постах, о Python, о разработке в целом.

Ровно через неделю мы подготовим пост с ответами на появившиеся вопросы.

Также у нас есть чат, в котором тоже можно задавать вопросы и просто общаться)
🔥5
Приветствую, друзья!

Пятница наконец-то здесь, и это прекрасный повод отметить конец рабочей недели и насладиться предстоящими выходными. Пусть ваш вечер будет спокойным и приятным, а выходные принесут вам массу радости и позитивных эмоций.

Фильм: Ветер крепчает

Год: 2013

Мальчик Дзиро мечтает о полетах и красивых самолетах, способных обогнать ветер. Вот только пилотом ему не стать — он с рождения близорук. Но Дзиро не расстается с мечтой о небе, он начинает придумывать идеальный самолет и со временем становится одним из лучших авиаконструкторов мира. На пути к успеху он не только встретит много интересных людей, переживет Великое землетрясение в Токио и жестокие войны, но и обретет любовь своей жизни – прекрасную Наоко.

https://www.sspoisk.ru/film/693969/

Приятного просмотра!
🔥2
Сделали Shorts по второй задаче из рубрики "Что выведет этот код?"!

Ссылка на задачу, если вы пропустили: https://t.iss.one/press_any_button/410

Видео версия "Что выведет этот код? №2":
https://youtube.com/shorts/kE4tjQECbNI

Будем благодарны лайку и досмотру видео до конца, спасибо!
🔥4
Приветствуем!

Напоминаем, что у нас проходит конкурс по программированию!
Прочитать условие и принять участие можно тут: https://t.iss.one/press_any_button/757

Список участников на текущий момент:
- Виктор Вангели
- Худайберген
- Ηe_ΙΙροcΤο_Tακ
- Виктор Королев

Сдали pull request:
- Виктор Королев

Осталось 2.5 дня до вечера понедельника! Торопитесь!
Пусть у нас уже пять заявленных участников, только один сделал задание. Если не наберётся 3-х участников, конкурс будет отменён ☹️
🔥3😢2👍1
Что выведет код с изображения? №29
Anonymous Poll
13%
9
26%
IndexError
0%
3 3
35%
SyntaxError
0%
3 3 3 3
23%
ValueError
3%
27
Что выведет этот код? №29

Ответ завтра в разборе. Пишите свои варианты в комментарии!
Обновление библиотеки - AIOgram 3.9.0
Автор: Иван Ашихмин

Вышла новая версия библиотеки AIOgram 3.9.0.

Установить новую версию можно выполнив команду:
pip install -U aiogram


Главное.
- Добавлен инструмент разрешения ChatMember и обновлено руководство по миграции 2.x.
🔥21
- Добавлена полная поддержка Bot API 7.6.
- Добавлены классы aiogram.types.paid_media.PaidMedia, aiogram.types.paid_media_info.PaidMediaInfo, aiogram.types.paid_media_preview.PaidMediaPreview, aiogram.types.paid_media_photo.PaidMediaPhoto и aiogram.types.paid_media_video.PaidMediaVideo, содержащие информацию о платных медиа.
- Добавлен метод aiogram.methods.send_paid_media.SendPaidMedia и классы aiogram.types.input_paid_media.InputPaidMedia, aiogram.types.input_paid_media_photo.InputPaidMediaPhoto и aiogram.types.input_paid_media_video.InputPaidMediaVideo для поддержки отправки платных медиа.
- Документировано, что методы aiogram.methods.copy_message.CopyMessage и aiogram.methods.copy_messages.CopyMessages не могут быть использованы для копирования платных медиа.
- Добавлено поле can_send_paid_media в класс aiogram.types.chat_full_info.ChatFullInfo.
- Добавлено поле paid_media в классы aiogram.types.message.Message и aiogram.types.external_reply_info.ExternalReplyInfo.
- Добавлен класс aiogram.types.transaction_partner_telegram_ads.TransactionPartnerTelegramAds, содержащий информацию о транзакциях Telegram Star, связанных с платформой Telegram Ads.
- Добавлено поле invoice_payload в класс aiogram.types.transaction_partner_user.TransactionPartnerUser, содержащее указанный ботом payload счета.
- Изменен режим открытия по умолчанию для Direct Link Mini Apps.
- Добавлена поддержка запуска Web Apps через ссылку t.iss.one в классе aiogram.types.menu_button_web_app.MenuButtonWebApp.
- Добавлено поле section_separator_color в класс ThemeParams.


Исправления.
- Исправлено разрешение контекста события для callback-запроса, который поступает от бизнес-аккаунта.

Пост на сайте
Поддержать проект на Boosty
Поддержать проект в Telegram

#перевод #список_изменений #aiogram #telegram #новая_версия #telegram_бот #bot_api #changelog
🔥3
Вчера была достаточно интересная задача. Её решило 38% из 24-х человек (а что так мало участвовавших?).

Код задачи:
a = 3
b = a,
c = b * a

print(c[2] * *b)



Разбор задачи
Объявляем три переменные:
- a - Со значением 3.
- b - Кортеж с единственным элементом из переменной a, т.е. 3
- c - С результатом умножения кортежа b на a.

Затем в функции print выводим результат умножения третьего элемента из кортежа c на единственный элемент в кортеже b.

Очевидно, будет ошибка!
Всё верно. Будет ошибка SyntaxError, поскольку нельзя распаковывать коллекцию внутри математической операции.

В задаче с прошлой субботы, распаковка была в начале выражения, поэтому она сработала корректно, сейчас же она находится внутри выражения и сработать уже не может.

Что будет если убрать ошибку?
Тут есть два варианта развития:
Первый. Если мы просто убёрем распаковку:
a = 3
b = a,
c = b * a

print(c[2] * b)


То в данном случае третий элемент кортежа c - 3 будет умножен на кортеж b и мы получим ответ (3, 3, 3).

Второй. Если мы хотим умножить именно на значение в кортеже:
a = 3
b = a,
c = b * a

print(c[2] * b[0])


То в данном случае получим выражение 3 * 3 и ответ 9.
🤯4
Подготовили разбор задачи на YouTube Shorts!

https://youtube.com/shorts/AX86xkxqGHE?feature=share

В этом видео мы немного изменили формат. Напишите в комментарии как вам?

Будем благодарны за лайк и досмотр видео до конца. Спасибо!
👍1🔥1
Код на салфетке
Обновление библиотеки - AIOgram 3.9.0 Автор: Иван Ашихмин Вышла новая версия библиотеки AIOgram 3.9.0. Установить новую версию можно выполнив команду: pip install -U aiogram Главное. - Добавлен инструмент разрешения ChatMember и обновлено руководство по…
Telegram в последнее время активно обновляют свой Bot API, aiogram'у только и остаётся поспевать за ним.

Вышло обновление aiogram 3.10.0. На целый пост не тянет, поэтому просто заметка.

Главное.
- Добавлен класс aiogram.types.refunded_payment.RefundedPayment, содержащий информацию о возвращенном платеже.
- Добавлено поле refunded_payment в класс aiogram.types.message.Message, описывающее служебное сообщение о возвращенном платеже.
Приветствуем!

Вот-вот закончится приём работ для конкурса!

Дедлайн сдачи пуллреквестов - 19:00 по МСК!

На данный момент работы сдали четыре участника:
- Виктор Вангели
- Виктор Королев
- Ηe_ΙΙροcΤο_Tακ
- Анастасия Бастрыкина

Торопитесь! Ещё можно успеть!

После окончания приёма работ будет опубликован пост со ссылками на работы и голосованием.

Также. Завтра в 18:00 по МСК будет будет стрим на котором посмотрим на отправленные варианты и разберём их.
🔥4👏1
Внезапно у нашего конкурса появился ещё один спонсор — Юрий Б.!

Он предложил интересный дополнительный розыгрыш «Везунчик на салфетке» среди выполнивших задание участников!

Все подробности и сам розыгрыш этого дополнительного приза (или призов?😉) состоится завтра на стриме!

Спешите! До закрытия приёма работ осталось не так много времени!
🔥6😱1
Приём работ для конкурса ОКОНЧЕН!

Представляю вам конкурсантов:
1. Виктор Вангели - Выполненная работа
2. Виктор Королев - Выполненная работа
3. Александр Вязников - Выполненная работа
4. Анастасия Бастрыкина - Выполненная работа

Проголосуйте за понравившийся вариант решения в опросе ниже!

Завтра в 18:00 на стриме мы разберём решения участников, а также разыграем среди них дополнительный приз 😉

Результаты будут подведены в среду в 19:00. По результатам голосования, победитель получит 2000 рублей!

Вариант от редакции доступен в основной ветке репозитория.
🔥6👍1👏1