Простая проблема развертывания Python - целый мир боли - PullRequest
21 голосов
/ 30 апреля 2010

У нас есть несколько приложений Python 2.6, работающих на Linux. Некоторые из них являются веб-приложениями Pylons, другие - просто длительными процессами, которые мы запускаем из командной строки, используя nohup. Мы также используем virtualenv, как в разработке, так и в производстве. Каков наилучший способ развертывания этих приложений на рабочем сервере?

В процессе разработки мы просто помещаем дерево исходных текстов в любой каталог, настраиваем virtualenv и запускаем - достаточно просто. Мы могли бы сделать то же самое в производстве, и, возможно, это действительно наиболее практичное решение, но просто немного неправильно запускать svn update в производстве. Мы также попробовали fab, но это никогда не работает с первого раза. Для каждого приложения что-то еще идет не так. Меня поражает, что весь процесс слишком сложен , учитывая, что то, чего мы пытаемся достичь, в принципе очень просто. Вот что мы хотим от процесса развертывания.

  1. Мы должны быть в состоянии выполнить одну простую команду , чтобы развернуть обновленную версию приложения. (Если при первоначальном развертывании требуется дополнительная сложность, это нормально.)
  2. Когда мы запускаем эту команду, она должна копировать определенные файлы, либо из репозитория Subversion, либо из локальной рабочей копии, в указанную «среду» на сервере, что, вероятно, означает другую виртуальность. У нас есть и промежуточная, и производственная версии приложений на одном сервере, поэтому их нужно как-то разделить. Если он устанавливается в пакеты сайтов, это тоже нормально, если он работает.
  3. У нас есть некоторые файлы конфигурации на сервере, которые должны быть сохранены (т. Е. Не перезаписаны и не удалены в процессе развертывания).
  4. Некоторые из этих приложений импортируют модули из других приложений , поэтому они должны каким-либо образом ссылаться друг на друга как пакеты. Это та часть, с которой у нас больше всего проблем! Мне все равно, работает ли он через относительный импорт, пакеты сайтов или что-то еще, если он надежно работает как при разработке, так и при производстве.
  5. В идеале процесс развертывания должен автоматически устанавливать внешние пакеты, от которых зависят наши приложения (например, psycopg2).

Это действительно так! Как тяжело это может быть?

Ответы [ 8 ]

23 голосов
/ 11 мая 2010

Разработка и развертывание кода Python значительно упрощены благодаря setuptools в сочетании с virtualenv и pip .

Основные идеи

Самая хитрая часть, которую я обнаружил, - это запуск среды разработки, которая максимально точно отражает развернутую установку, в то же время соблюдая инструменты и идиомы Pythonic.Но оказывается, что этого очень легко достичь с помощью pip и setuptools, которые вместе позволяют вам «устанавливать» дерево разработки в среду Python, не перемещая файлы.(На самом деле setuptools делает все это сам по себе, но pip лучше действует как зависимости дескриптора внешнего интерфейса.)

Еще одна ключевая проблема - подготовка чистой среды с известным набором пакетов в обеих средах.Virtualenv Python - это хорошая посылка в этом отношении, позволяющая вам настраивать полностью настроенную среду Python с вашим собственным выбором пакетов, не требуя root-доступа, или пакетов ОС (rpm или dpkg), и не будучи ограниченным какими-либо пакетами и версиями.из них, которые установлены в вашем дистрибутиве.

Наконец, один неприятный медведь ошибок - это сложность создания сценариев командной строки, которые хорошо работают с PYTHON_PATH.Это также довольно элегантно решается с помощью setuptools.

Настройка

(Для простоты это довольно предписательно. Не стесняйтесь расходиться по мере необходимости.)

  1. Подготовьте рабочий каталог, который ваши Python-компоненты могут назвать домом.
  2. Возьмите последнюю версию virtualenv из нижней части этой страницы и распакуйте ее (не важно где).
  3. Из рабочего каталога настройте новую виртуальную среду Python:

    $ python <untarred_directory>/virtualenv.py venv
    
  4. Вы захотите выполнять большую часть своей работы изнутри этой виртуальной среды.Используйте эту команду для этого (. является ярлыком для source):

    $ . venv/bin/activate
    
  5. Установочный пункт:

    $ easy_install pip
    
  6. Создание каталогов для каждого устанавливаемого пакета, который вы хотите создать.

  7. В каждом каталоге вам понадобится файл setup.py, который определяет содержимое и структуру пакета.Setuptools документация - очень хороший ресурс для начала работы с этим.Стоит потратить время на поглощение больших кусков.

Разработка

Как только ваша древовидная структура готова, вы почти готовы начать кодирование.Но прямо сейчас пакеты, которые зависят друг от друга, не могут видеть друг друга, как в развернутой среде.Эта проблема решена с помощью небольшого хитрого трюка, который предлагает setuptools и который использует pip.Для каждого разрабатываемого пакета выполните следующую команду (убедитесь, что вы находитесь в виртуальной среде для своего проекта, как описано в шаге 3 выше):

$ pip install -e pkg1

Эта команда установит pkg1 в вашвиртуальная среда, и это делает это без копирования любых ваших файлов.Он просто добавляет ссылку на каталог site-packages, указывающую на корень разработки пакета, и создает в этом корне каталог egg-info.Вы также можете сделать это без пипа, как показано ниже:

$ cd pkg1
$ python setup.py develop

И это обычно будет работать, но если у вас есть сторонние зависимости (которые должны быть перечислены в setup.py, как объяснено здесь в документации к setuptools), pip умнее в их поиске.

Следует обратить внимание на то, что ни setuptools, ни pip не имеют смысла находить зависимости между вашими собственными пакетами.Если PkgB в каталоге B зависит от PkgA в каталоге A, то pip install -e B завершится ошибкой, поскольку pip не может узнать, что PkgA находится в каталоге A;вместо этого он попытается и не сможет загрузить PkgA из своих источников в онлайн-хранилище.Обходной путь - просто установить каждый пакет после его зависимостей.

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

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

Развертывание

Когда ваши пакеты готовы к действию, вы можете использовать setup.py для создания пакетов развертывания. Здесь слишком много вариантов, чтобы начать, но вам стоит начать:

$ cd pkg1
$ python setup.py --help
$ python setup.py --help-commands

Свободные концы

Из-за широкого характера вопроса этот ответ обязательно является неполным. Я не имел дело с долго работающими серверами, веб-платформами или самим процессом развертывания (в частности, с использованием pip install --index-url для управления частным хранилищем сторонних и внутренних пакетов и -e vcs+..., который будет пакеты из svn, git, hg или bzr). Но я надеюсь, что дал вам достаточно веревки, чтобы связать все это вместе (только не вешайте себя на это: -).

6 голосов
/ 09 мая 2010

Это действительно не сложно. Вам нужно играть в основном с buildout и supervisord IMO.

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

О nohup: Подход nohup не подходит для серьезных развертываний. У меня очень хороший опыт работы с супервизором. Это отличное решение для запуска приложений Python. Это очень легко настроить.

Некоторые конкретные ответы ниже.

  1. одна команда для развертывания: ответом является Buildout. Мы используем его уже пару лет без особых проблем
  2. Обычно это как будто вы извлекаете источник. Затем запустите buildout. Кроме того, может быть плохой идеей позволить установке скопировать в site-пакеты. Лучше держать среду отдельно.
  3. Конфиги не будут перезаписаны.
  4. Вы можете / должны рассмотреть возможность создания яиц для обычных упаковок. Как вы можете создать яйцо для пакета (скажем, commonlib) и загрузить его в свой репозиторий кода. Затем вы можете указать это как зависимость в вашем buildout.cfg
  5. Buildout способен создавать наиболее важные пакеты, полностью отделенные от установки центрального / верхнего уровня. Однако, по моему опыту, пакеты python с расширением c, если они установлены как пакеты ОС, намного проще.
5 голосов
/ 30 апреля 2010

Я работал над реализацией этого для наших рабочих проектов. Это несколько разных частей.

Во-первых, мы настраиваем virtualenv.py, используя их возможности начальной загрузки, чтобы добавить ваши собственные функции и флаги пост-создания. Это позволяет нам определять общие типы проектов, а также дает нам единственную команду для создания нового virtualenv, извлечения проекта из репозитория git и установки любых требований в virtualenv с использованием pip и needs.txt. файлы.

так наши команды выглядят так: python venv.py --no-site-packages -g $ git_proj -t $ tag_num $ venv_dir

http://pypi.python.org/pypi/virtualenv http://pip.openplans.org/

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

http://docs.fabfile.org/0.9.0/

У меня есть команда fab: make_tag, которая проверяет наличие неиспользованных коммитов, открывает файлы, для которых необходимо обновить строки версий, создает и загружает документы sphinx, а затем фиксирует последний тег в хранилище.

Обратная сторона - это команда fab deploy, которая, через ssh, выполнит git co указанного тега, запустит обновление pip для любых новых требований, запустит любые необходимые миграции базы данных, а затем сбросит веб-сервер, если это веб-приложение.

Вот пример функции тегирования: http://www.google.com/codesearch/p?hl=en#9tLIXCbI4vU/fabfile.py&q=fabfile.py%20git%20tag_new_version&sa=N&cd=1&ct=rc&l=143

Существует масса хороших файлов с тканями, которые вы можете просмотреть, используя поиск по коду Google. Я знаю, что я обманул некоторых для собственного использования.

Это определенно сложно и состоит из нескольких частей, чтобы все работало гладко. Однако, как только вы запустите его, гибкость и скорость работы просто потрясающие.

2 голосов
/ 30 апреля 2010

Посмотрите Buildout для воспроизводимых развертываний.

0 голосов
/ 29 января 2012

Звучит так, как будто вам нужен скрипт сборки. Так что пишите, используя shell, python, ant или ваш любимый инструмент для сборки. Если вам не нравится писать в XML, pant позволяет вам писать ant-скрипты на python. Несколько человек упомянули buildout , но у меня нет никакого опыта с этим.

Сначала определите ваши шаги. Похоже, вы хотите:

  1. Экспорт SVN из вашего рабочего тега (вы не хотите иметь рабочую копию в prod)
  2. набор virtualenv
  3. easy_install или pip установить необходимые пакеты (или, возможно, использовать предварительно загруженные и протестированные версии)
  4. скопировать файлы конфигурации производства в вашу цель (не рекомендуется хранить эту информацию в исходном репозитории - хотя вы можете иметь их версии отдельно)
  5. перезагрузите сервер и выполните любую другую задачу установки
  6. запуск тестов дыма и откат при сбое

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

0 голосов
/ 11 мая 2010

Если вы человек, занимающийся сборкой, вам следует знать о minitage.recipe.scripts способности генерировать файл для настройки среды Python. Источник на ваш веб-сервер и ваша сборка полностью переносима.

0 голосов
/ 10 мая 2010

Я бы использовал rsync для синхронизации внешних данных с вашего основного "основного" сервера с другими, а также с вашей платформы "бета-тестирования", с вашим рабочим "основным" сервером.

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

Subversion или Mercurial не будет плохой идеей и в этом случае. Mercurial имеет Преимущество в том, что вы можете «вытягивать» или «выдвигать» вместо простого обновления из одного центрального источника. Вы можете найти интересные случаи, когда децентрализованная модель (Mercurial) работает лучше.

0 голосов
/ 06 мая 2010

Еще один голос за ткань (еще не пробовал Buildout). Мы успешно используем его уже пару месяцев.

Если у вас возникли проблемы с тканью, другой вариант - Capistrano . Прекрасно работает (даже для не-рельсовых приложений). Только прекратил его использовать, потому что это странно - использовать Ruby для развертывания приложений Python;)

...