私の知る限り、唯一の解決策はの新しいバージョンをスラッグlibpq
に売り込むことです。
私が対象としているパッケージはlibpq5とlibpq-devで、ソース パッケージpostgresql-9.1からビルドされています。多くの手間を省くために、私のバイナリが信頼できる場合は、手順 8 にスキップして、私が作成したビルド済みのバイナリ libpq を使用できます。いいえ、私に感謝しないでください。
- バニラ 12.04 で新しい VM をスピンアップする
sudo apt-get update
apt-get source postgresql-9.1
(おそらく最初に必要になるでしょうsudo apt-get install dpkg-src
)
- 抽出されたソースで、ルールファイル (がまだ PostgreSQL 9.1.8
postgresql-9.1-9.1.8/debian/rules
の場合) を確認します。precise-updates
rules ファイルから、libpq を構築するために使用する必要がある構成オプションは次のとおりだと思います。
LDFLAGS="-Wl,--as-needed -Wl,-z,now" \
CFLAGS="-fPIC -DLINUX_OOM_ADJ=0" \
./configure --prefix=/app/vendor \
--enable-integer-datetimes \
--enable-thread-safety \
--enable-debug \
--disable-rpath \
--with-gnu-ld \
--with-pgport=5432 \
--with-system-tzdata=/usr/share/zoneinfo \
--without-tcl \
--without-perl \
--without-python \
--with-krb5 \
--with-gssapi \
--with-openssl \
--with-libxml \
--with-libxslt \
--with-ldap
--enable-nls --with-ossp-uuid --with-tcl --with-perl --without-python --with-pam
Heroku dyno では構成/ビルドの失敗につながるため、を削除/否定したことに注意してください。私はそれらのどれも必要としません、それらがまったく影響を与えるかどうかはlibpq5
わかりません.dynoで非常に必要とされているとは思えません.そうでない場合は、それを修正して楽しんでください.
make && make install
これですべての postgresql が にインストールされました/vendor
。取得する必要があるファイルは、 および で指定されpostgresql-9.1-9.1.8/debian/libpq5.install
ていpostgresql-9.1-9.1.8/debian/libpq-dev.install
ます。残念ながら、debian のインストール レイアウトに従っていないため、本当に必要なファイルを見つけるためにこれらのリストを調整する必要があります。私はこのリストを思いつきました:
tar c \
include/postgresql/internal/* \
include/libpq-fe.h \
include/libpq-events.h \
include/libpq/libpq-fs.h \
include/pg_config*.h \
include/postgres_ext.h \
include/postgresql/9.1/server/catalog/pg_type.h \
include/postgresql/9.1/server/catalog/genbki.h \
include/postgresql/9.1/server/nodes/nodes.h \
include/postgresql/9.1/server/utils/elog.h \
include/postgresql/9.1/server/utils/errcodes.h \
include/postgresql/9.1/server/utils/palloc.h \
include/postgresql/9.1/server/c.h \
include/postgresql/9.1/server/pg_config.h \
include/postgresql/9.1/server/pg_config_manual.h \
include/postgresql/9.1/server/pg_config_os.h \
include/postgresql/9.1/server/port.h \
include/postgresql/9.1/server/pg_trace.h \
include/postgresql/9.1/server/postgres.h \
include/postgresql/9.1/server/postgres_fe.h \
include/postgresql/9.1/server/postgres_ext.h \
include/postgresql/9.1/server/mb/pg_wchar.h \
lib/libpq.so \
bin/pg_config \
lib/libpq.so.5* \
| gzip --best > /tmp/libpq-5.4_9.1.8.tar.gz
pg_config.1.gz
マンページ ( ) とローカリゼーション メッセージ (LC_MESSAGES/pg_config-9.1.mo LC_MESSAGES/libpq*.mo
の下)を削除しなければならなかったことに注意してくださいshare/locale
。私はこのファイルのリストに対して Python をリンクpsycopg2
し、それを正常に使用することができましたが、これが重要であると思われる場合は、これを理解して修正することもできます。
私たちの悩みは事実上終わりました。結果のlibpq-5.4_9.1.8.tar.gz
ファイルを取得し、dyno のビルドパック (S3 など) にアクセスできる場所に配置してから、それをスラッグにベンダー化する必要があります。その方法がわからない場合、私の提案 (現在のPython buildpackの場合) は、スラッグにファイル 'bin/pre_compile' を作成し、これを入れることです。
#!/bin/sh
vendor() {
printf " "
echo -n "$1 "
curl --location --fail --silent $1 | tar -zx -C vendor && echo OK
}
echo " (lines by the app will be prefixed with ---->>)"
echo "---->> Fetching vendored binaries"
mkdir -p vendor
vendor "http://fusic.s3.amazonaws.com/executables/heroku/libpq-5.4_9.1.8.tar.gz"
echo "---->> Injecting shell environment"
# Even though Heroku's Python buildback has a hook mechanism, hooks can't
# change the buildpack's process environment (they are spawned, not
# sourced). This makes it possible to write hooks in any language, but
# makes vendoring stuff that should be linked against libraries installed
# during the rest of the build process harder. The kludge below hijacks
# $BIN_DIR/steps/pylibmc, which is sourced after this code and before pip
# is ran. Puked a little in my mouth.
# See also: https://twitter.com/aknin/status/290832546260979712
cat > $BIN_DIR/steps/pylibmc << EOF
echo "---->> Injected environment hook executing"
source .profile.d/activate_vendor_tree.sh
EOF
また、これを作成.profile.d/activate_vendor_tree.sh
して入れます:
#!sh
export PATH="/app/vendor/bin:$PATH"
export CFLAGS="-I/app/vendor/include"
export LDFLAGS="-L/app/vendor/lib -R/app/vendor/lib"
export LD_LIBRARY_PATH="/app/vendor/lib:$LD_LIBRARY_PATH"
スラッグをコンパイルすると、インストールしたプリフックが起動し、バックポートされた libpq をダウンロードして、それをスラッグにベンダします。Python ビルドパックまたは同様に制限されたビルドパック (上記の詳細なコメントを参照) を使用している場合、醜いが必要な環境インジェクション フックが作動し、要件が新しい libpq に対してコンパイルされます。アプリを実行すると、Heroku はコードを実行する前にすべてを便利にソースし.profile.d
、新しい libpq を再度有効にします。そうそう。
最後に、完了です。アプリを Heroku にデプロイすると、依存関係が新しい libpq にリンクされます。アプリがすでにデプロイされている場合、Heroku のスラッグ コンパイラがこれらの要件を再インストールしようとする前に、おそらくスラッグのキャッシュ ディレクトリをクリアする必要があります (新しい libpq にリンクできるようにするためです。これは厄介なトピックであり、範囲外です)このチュートリアルの;私が知っている唯一の方法はpre_compile
、キャッシュを削除する何かを に貼り付けることです)。うーん。