Создание окружения для разработки на odoo с помощью docker. С запуском pre-commit и возможностью использвоания отладчика

Установка docker и docker-compose в данной статье не рассматривается. Это легко гуглится)

Создание и настройка docker образа для работы с проектом

Создаем нативный образ для работы с odoo под arm или x86

FROM python:3.7.12-bullseye
# Переменные проекта
ARG USER_UID=9999
ARG USER_GID=9999
  

ARG USER_NAME=odoo
ARG PASSWORD=odoo

# Подготавливаем внутреннего пользователя
RUN groupadd --gid $USER_GID $USER_NAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME -p $(openssl passwd -crypt $PASSWORD) \
&& apt-get update \
&& apt-get install -y sudo \
&& echo $USER_NAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USER_NAME \
&& chmod 0440 /etc/sudoers.d/$USER_NAME\
&& mkdir /home/$USER_NAME/.ssh\
&& chown $USER_NAME:$USER_NAME /home/$USER_NAME/.ssh\
&& mkdir -p /home/$USER_NAME/.vscode-server\
&& chown -R $USER_NAME:$USER_NAME /home/$USER_NAME/.vscode-server\
&& apt-get -y install git postgresql-client node-less npm ssh \
&& python3 -m pip install pre-commit

# устанавливаем все необходимые зависимости

RUN apt-get -y install libxml2-dev libxslt1-dev libldap2-dev\
libsasl2-dev libtiff5-dev libjpeg62-turbo-dev libopenjp2-7-dev\
zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev\
libharfbuzz-dev libfribidi-dev libxcb1-dev libpq-dev\
openssl build-essential libssl-dev libxrender-dev \
git-core libx11-dev libxext-dev libfontconfig1-dev libfreetype6-dev fontconfig\
xvfb libfontconfig python3-virtualenv virtualenv

# Скачиваем и устанавливаем wkhtmltopdf который будет рендерить PDF файлы как нам нужно,
# пакет из официальных репозиториев не рендерит заголовки и подвалы

RUN wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.bullseye_arm64.deb \
&& apt-get install -y ./wkhtmltox_0.12.6.1-2.bullseye_arm64.deb

USER $USER_NAME

Для того, чтобы собрать образ (image) необходимо запустить следующую команду

docker build -f $HOME/projects/project-odoo/Dockerfile -t odoo-arm .

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

docker run odoo-arm  bash -c "pip3 install passlib"

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

docker ps -l

Находим образ с нужным именем

CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS                     PORTS     NAMES
f26b7ca2f1eb   odoo-arm   "bash -c 'cd /home/o…"   9 minutes ago   Exited (0) 5 minutes ago             upbeat_dijkstra

И сохраняем все получившиеся изменения в образ с нужным именем

docker commit f26b7ca2f1eb odoo-arm:v2.0_with_passlib

Настройка проекта для работы с docker

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

Свой взгляд на формирование проекта я изложил здесь

Теперь давайте поговорим про запуск docker контейнера с помощью которого у нас будет вестиcь разработка. Для того чтобы запустить odoo нам нужен работаютщий postgresql сервер, к которому будет подключаться odoo. Чтобы его (сервер базы данных postgresql) запустить мы воспользуемся инструментом оркестровки docker контейнеров - docker-compose. Docker-compose это система управления и запуска docker контейнров. Мы будем ее использовать для того, чтобы запустить сразу 2 образа с нужными нам настройками и параметрами. Для настройки запуска образов у нас в каталоге проекта лежит файл docker-compose.yml

Вот его содержимое:

version: "3.8"


services:
  db:
    image: postgres:13
    user: root
    tty: true
    ports:
      - 5432:5432
    environment:
      - POSTGRES_PASSWORD=odoo
      - POSTGRES_USER=odoo
      - POSTGRES_DB=postgres

  odoo:
    image: odoo-amd64
    user: odoo
    tty: true
    depends_on:
      - db
    environment:
      - PYTHONUNBUFFERED=1
    ports:
      - 8069:8069
      - 5678:5678
    volumes: 
      - /home/odoo/odoo:/home/odoo/odoo
      - /home/odoo/projects/odoo_demo_project-16/venv:/home/odoo/venv
      - /home/odoo/projects/odoo_demo_project-16/dev_odoo_docker_config_file.conf:/home/odoo/odoo.conf
      - /home/odoo/projects/odoo_demo_project-16/dev_project:/home/odoo/dev_project
      - /home/odoo/odoo_backups:/home/odoo/backups
      - /home/odoo/projects/odoo_demo_project-16/docker_home/.local:/home/odoo/.local
      - /home/odoo/projects/odoo_demo_project-16/docker_home/.cache:/home/odoo/.cache
      - /home/odoo/odoo_projects/github.com/aayartsev/odoo_demo_project:/home/odoo/extra-addons/odoo_demo_project

    command: bash -c ' cd /home/odoo && source /home/odoo/venv/bin/activate && python3 -u -m debugpy --listen 0.0.0.0:5678 /home/odoo/odoo/odoo-bin -c /home/odoo/odoo.conf --limit-time-real 99999 -d test_db -i first_module -u first_module'

Теперь давайте рассмотрим подробнее, что именно сздесь указано: Если в кратце то мы видим инструкцию для запуска двух сервисов с именами db и web. Если с сервисом db примерно все понятно, что мы берем образ для postgresql 13 запускаем все от внутреннего пользователя docker контейнера с именем root и указываем через параметры окружения первичные логин и пароль для подключения к базе. То на сервисе с именем web надо остановиться поподробнее: image - имя образа, который мы собрали в первой части этой статьи user - все действия внутри контейнера будут запускаться от имени этого пользователя в нашем случае это odoo depends_on - данный параметр указвает на то, что наш сервис web зависит от работающего сервиса db и система, автоматически сначала запустит его, а потом уже наш web. enviroment - в нашем случае мы указываем только один параметр PYTHONUNBUFFERED=1, который нужен для того, чтобы при отрабоке функции print() в нашем коде результат выводился в консоль. Очень полезно при отладке. ports - здесь мы укзаываем порты которые буду пробрасываться из этого контейнера на наш localhost, что позволит подключаться к сервису запущенному внутри контейнра просто обратившись на на этот порт по адресу localhost или 127.0.0.1. В нашем случае указаны 2 порта: - 8069 - порт по умолчанию который используется odoo, он нам нужен для подключение к системе через браузер, или программны образом - 5678 - порт который прослушивает дебаггер python, нам он нужен для подключения отладчика. volumes - в этом параметре мы указываем все каталоги и файлы, которые нам нужно пробросить внутрь контейнера, при этом, чтобы они были доступны и в нашей файловой системе.

# Пробрасываем каталог с исходниками платформы внутрь контейнера
- /home/odoo/odoo:/home/odoo/odoo
# Подключаем файл конфигурации из нашего проекта внутрь контейнра
- /home/odoo/projects/odoo_demo_project-16/venv:/home/odoo/venv
      - /home/odoo/projects/odoo_demo_project-16/dev_odoo_docker_config_file.conf:/home/odoo/odoo.conf
# Подключаем файлы проекта с которым будем работать внутрь контейнера
- /home/odoo/odoo_projects/github/OCA/manufacture:/home/odoo/extra-addons/manufacture
# Так же подключаем каталог для хранения файлов, где хранятся сессии и статические ресурсы системы, это нам нужно для того, чтобы при перезапуске контейнера эти данные не исчезали. 
- /home/odoo/projects/odoo_demo_project-16/docker_home/.local:/home/odoo/.local
# Плюс каталог в котором будуте хранится кэш для pre-commit
- /home/odoo/projects/odoo_demo_project-16/docker_home/.cache:/home/odoo/.cache

Все остальные файлы, которые указаны в файле конфигурации я пробрасываю для индивидуальной настроки pre-commit, т.к. macos имеет свои особенности и мне при его запуске необходиме внести исключение. command - по сути команда которая будет запущена при запуске контейнера.

У нас почти все готово, перед запуском системы, нам еще нужно устновть все пакеты python которые нужны для запуска самой odoo а так же для работы проктов-зависимостей и нашего проекта. Для этго мы запустим контейенр вот такой командой

docker run odoo-arm bash -c 'cd /home/odoo && python3 -m venv /home/odoo/venv && . /home/odoo/venv/bin/activate && wget -O odoo_requirements.txt https://raw.githubusercontent.com/odoo/odoo/16.0/requirements.txt && python3 -m pip install -r odoo_requirements.txt && python3 -m pip install debugpy==1.6.3'

Данная команда скачает файл со всеми python зависимостями для нашей 16 версией и установт в указанный каталог, после этого еще доустановит в наше окружение указанную версию debugpy. Этот пакет нам нужен для запуска системы с отладчиком.

Далее не забываем правильно настроить пути к каталогам с модулями в файле dev_odoo_docker_config_file.conf. Так же необходимо учитывать что там должны быть пути для файловой системы внутри контейнера. Смотрите файл docker-compose.yml параметр volumes - там указаны все проброшенные пути к модулям

Настройка VSCode с возможностью дебага

Установку и настройку VSCode я тут описывать не буду. Для правильной работы нам нужно установить дополнение Dockerиз маркет дополнений Затем мы открываем каталог с проектом odoo_demo_project-16. Нажимая на иконку с отладкой VSCode предложит настроить следующий файл

odoo_demo_project-16/.vscode/launch.json

Если вы правильно выполнили предыдущие настройки, то у вас внутри контейнера уже должен быть установлен пакет debugpy. А параметры запуска уже учиыватю использование данного модуля для отладки. Поэтому теперь нам нужно только подготовить саму VSCode для подключения к серверу отладки. Для правильной настройки нам в файле launch.json нужно указать адрес сервера к котрому нужно подключиться, а так же какой каталог вашего репозитория каком каталоге соотвествует внутри docker контейнера. Вот пример файл запуска отладчика:

{
	"configurations": [
		{
			"name": "Odoo: отладка в Docker",
			"type": "python",
			"request": "attach",
			"port": 5678,
			"host": "localhost",
			"pathMappings": [
				{
					"localRoot": "${workspaceFolder}/manufacture",
					"remoteRoot": "/home/odoo/extra-addons/manufacture"
				}
			]
		}
	]
}

Все, теперь после запуска контейнера с odoo вы нажав на F5 автоматически подключитесь к сервер отладки и можете использовать точки останова и прочее. Подробнее про настройку отладки можно почитать в официальной документации VSCode Для запуска pre-commit нам необходимо запустить следующую команду:

docker run odoo-arm bash -c 'cd /home/odoo/extra-addons/odoo_demo_project && ls && git config --global --add safe.directory /home/odoo/extra-addons/odoo_demo_project && pre-commit run --all-files'

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

Обсуждение

Обсудить, указать на ошибки и опечатки можно здесь