AWS Lambda Node.js 12环境安装LibreOffice部署后无法运行命令如何解决
错误根因
你遇到的failed to read path from javaldx报错由两个核心问题导致:
- Dockerfile中使用
RUN export HOME=/tmp仅在镜像构建阶段临时生效,Lambda函数实际运行时默认的HOME环境变量指向/var/task,该目录LibreOffice没有写入权限,javaldx工具读取Java路径时需要在HOME目录下生成临时配置文件,权限不足就会触发报错 - 启动soffice命令缺少必要的无头运行参数,且没有指定正确的输入/输出路径,你将下载的文档写入了
/tmp目录,但命令默认读取当前工作目录下的文件,找不到目标文件也会触发连锁报错
修复步骤
1. 调整Dockerfile
将临时export的环境变量改为镜像全局生效的ENV变量,同时补充Java路径配置和LibreOffice必要依赖,修改后的Dockerfile如下:
FROM public.ecr.aws/lambda/nodejs:12 RUN yum install wget tar libXext libXrender libXtst -y RUN yum install java-1.8.0-openjdk-devel -y # 配置全局环境变量,运行时生效 ENV JAVA_HOME=/usr/lib/jvm/jre-1.8.0-openjdk ENV HOME=/tmp ENV LD_LIBRARY_PATH=/opt/libreoffice7.2/program:$LD_LIBRARY_PATH RUN mkdir "LibreOffice_7.2_Linux_x86-64_rpm" ADD LibreOffice_*_Linux_x86-64_rpm ./LibreOffice_7.2_Linux_x86-64_rpm RUN ls -la RUN cd LibreOffice_*_Linux_x86-64_rpm && cd RPMS && yum -y localinstall *.rpm RUN chmod -R 777 /opt/libreoffice7.2 ADD test.docx ./ COPY index.js package*.json ./ RUN npm install CMD [ "index.handler" ]
2. 调整handler代码
补充soffice无头运行必要参数,指定正确的输入文件路径和输出目录,修改后的核心代码如下:
/* Amplify Params - DO NOT EDIT ENV REGION STORAGE_DOCBACKENDD3C9A483_BUCKETNAME Amplify Params - DO NOT EDIT */ const {writeFileSync, readFileSync} = require('fs'); const {execSync} = require('child_process'); const {S3} = require('aws-sdk'); const s3 = new S3( { params: { Bucket: "documentgenerationb25c0536d4054b9faeafca747e3f295559-dev", apiVersion: '2006-03-01' } } ); // 补充必要运行参数,指定输出目录为/tmp const convertCommand = `/opt/libreoffice7.2/program/soffice --headless --norestore --nofirststartwizard --nolockcheck --convert-to pdf --outdir /tmp`; exports.handler = async () => { const filename = "test.docx" const {Body: inputFileBuffer} = await s3.getObject({Key: `public/${filename}`}).promise(); writeFileSync(`/tmp/${filename}`, inputFileBuffer); // 指定输入文件的完整路径 execSync(`${convertCommand} /tmp/${filename}`); const outputFilename = `test1-brandon.pdf`; const outputFileBuffer = readFileSync(`/tmp/${outputFilename}`); await s3 .putObject({ Key: `public/${outputFilename}`, Body: outputFileBuffer, ACL: 'public-read', ContentType: 'application/pdf' }) .promise(); return `https://documentgenerationb25c0536d4054b9faeafca747e3f295559-dev.s3.amazonaws.com/public/${outputFilename}`; };
可选优化
如果你的业务不需要LibreOffice的Java相关功能,可以在转换命令中追加--java-disable参数,直接跳过javaldx的检查逻辑,进一步降低报错概率。
内容的提问来源于stack exchange,提问作者Brandon Heng
相关产品推荐
相关产品推荐

