如何在Heroku上运行二进制文件

时间:2016-06-05 04:47:45

标签: node.js heroku pandoc

我有一个简单的node.js应用程序,它在我的OSX开发环境中运行良好。但是当我将相同的代码推送到Heroku时,我会在意外的地方返回undefined

行为不可预测的库称为pandoc。它转换文档格式。我使用包装程序包node-pdc将其集成到我的节点应用程序中。 Pdc需要安装pandoc,但它接受一个路径来指定pandoc的位置,我正在本地做它并且效果很好。我在本地计算机上全局卸载了pandoc,以确保我指向可执行文件的正确位置。

这完全符合本地预期:

var pdc = require('pdc');
var path = require('path');
var fs = require('fs');
var Q = require('q');

// optional, if pandoc is not in PATH
pdc.path = path.resolve(__dirname +'/pandoc/1.15.0.6/bin/pandoc');

module.exports.mdToHtml = function (input, callback) {

    //TEST
    pdc('## Emerson', 'markdown', 'html', ['--template=smashingtemplate'], function(err, result){
        console.log(result); // <h2>Emerson</h2>
    });
    ...

但是在Heroku上,我在日志中看到undefined。它不会引发任何错误。为什么它适用于我的笔记本电脑而不适用于Heroku?

两个环境都在运行节点v4.0.0

更新1: 我测试了看Heroku上是否有pandoc ......

$ heroku run bash 

~ $ ls /app/pandoc/1.15.0.6/bin/      
pandoc
~ $ /app/pandoc/1.15.0.6/bin/pandoc --version
bash: /app/pandoc/1.15.0.6/bin/pandoc: cannot execute binary file: Exec format error
~ $ ls /app/pandoc/1.15.0.6/bin/ -lah 
total 73M
drwx------ 2 u35911 dyno 4.0K Jun  5 04:48 .
drwx------ 4 u35911 dyno 4.0K Jun  5 04:48 ..
-rwx------ 1 u35911 dyno  73M Jun  5 04:48 pandoc

二进制文件在那里。但我无法运行它们......

更新2

~ $ objdump -i /app/pandoc/1.15.0.6/bin/pandoc
BFD header file version (GNU Binutils for Ubuntu) 2.24
elf64-x86-64
 (header little endian, data little endian)
  i386
elf32-i386
 (header little endian, data little endian)
  i386
elf32-x86-64
 (header little endian, data little endian)
  i386
a.out-i386-linux
 (header little endian, data little endian)
  i386
pei-i386
 (header little endian, data little endian)
  i386
pei-x86-64
 (header little endian, data little endian)
  i386
elf64-l1om
 (header little endian, data little endian)
  l1om
elf64-k1om
 (header little endian, data little endian)
  k1om
elf64-little
 (header little endian, data little endian)
  i386
  l1om
  k1om
  plugin
elf64-big
 (header big endian, data big endian)
  i386
  l1om
  k1om
  plugin
elf32-little
 (header little endian, data little endian)
  i386
  l1om
  k1om
  plugin
elf32-big
 (header big endian, data big endian)
  i386
  l1om
  k1om
  plugin
pe-x86-64
 (header little endian, data little endian)
  i386
pe-i386
 (header little endian, data little endian)
  i386
plugin
 (header little endian, data little endian)
srec
 (header endianness unknown, data endianness unknown)
  i386
  l1om
  k1om
  plugin
symbolsrec
 (header endianness unknown, data endianness unknown)
  i386
  l1om
  k1om
  plugin
verilog
 (header endianness unknown, data endianness unknown)
  i386
  l1om
  k1om
  plugin
tekhex
 (header endianness unknown, data endianness unknown)
  i386
  l1om
  k1om
  plugin
binary
 (header endianness unknown, data endianness unknown)
  i386
  l1om
  k1om
  plugin
ihex
 (header endianness unknown, data endianness unknown)
  i386
  l1om
  k1om
  plugin

               elf64-x86-64 elf32-i386 elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little 
          i386 elf64-x86-64 elf32-i386 elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 ---------- ---------- elf64-little 
          l1om ------------ ---------- ------------ ---------------- -------- ---------- elf64-l1om ---------- elf64-little 
          k1om ------------ ---------- ------------ ---------------- -------- ---------- ---------- elf64-k1om elf64-little 
        plugin ------------ ---------- ------------ ---------------- -------- ---------- ---------- ---------- elf64-little 

               elf64-big elf32-little elf32-big pe-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex 
          i386 elf64-big elf32-little elf32-big pe-x86-64 pe-i386 ------ srec symbolsrec verilog tekhex binary ihex 
          l1om elf64-big elf32-little elf32-big --------- ------- ------ srec symbolsrec verilog tekhex binary ihex 
          k1om elf64-big elf32-little elf32-big --------- ------- ------ srec symbolsrec verilog tekhex binary ihex 
        plugin elf64-big elf32-little elf32-big --------- ------- ------ srec symbolsrec verilog tekhex binary ihex 

和...

~ $ uname -a    
Linux 7f4e1d74-8fc2-47d2-89b7-97bfc9db30dd 3.13.0-85-generic #129-Ubuntu SMP Thu Mar 17 20:50:15 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

我可能没有正确理解它,但看起来它们都是64架构。

~ $ file  /app/pandoc/1.15.0.6/bin/pandoc
/app/pandoc/1.15.0.6/bin/pandoc: Mach-O 64-bit x86_64 executable

更新3

关注@ mbs1的建议......

Creating a relocatable binary
-----------------------------

It is possible to compile pandoc such that the data files
pandoc uses are embedded in the binary.  The resulting binary
can be run from any directory and is completely self-contained.

    cabal install hsb2hs  # a required build tool
    cabal install --flags="embed_data_files" citeproc-hs
    cabal configure --flags="embed_data_files"
    cabal build

You can find the pandoc executable in `dist/build/pandoc`.  Copy this wherever
you please.

当我cabal build时,它说:

cabal: No cabal file found.
Please create a package description file <pkgname>.cabal 

解决方案

我无法使用任何需要cabal的解决方案。我终于使用stack让它工作了(一旦我弄清楚如何安装它)。

$ stack install pandoc --flag pandoc:embed-data_files

然后我将生成的exec文件复制出vm并将其推送到Heroku。

2 个答案:

答案 0 :(得分:2)

你需要在与Heroku使用的完全相同的操作系统上构建一个pandoc的可重定位二进制文​​件,这样一个Ubuntu Linux系统(如果你在Mac OS X上安装在虚拟机中),然后按照{{3} }或this。基本上下面应该创建一个可重新定位的二进制文件:

stack install pandoc --flag pandoc:embed_data_files

或者,您也可以使用this,这是一种pandoc即服务。

答案 1 :(得分:1)

您在本地运行OSX。 Heroku在Ubuntu Linux上运行。这些体系结构不是二进制兼容的。