Error when testing on Docker node:14.5.0-alpine3.12
Overview
When we fill out a PDF in a docker container, it seems to work. Reading back in the filed out PDF results in an error:
"Error (2651941): Missing 'endstream' or incorrect stream length"
"Error: Couldn't find trailer dictionary"
"Error (2651941): Missing 'endstream' or incorrect stream length"
"Error: Couldn't find trailer dictionary"
"Error: Couldn't read xref table"
NOTE: This error does not happen on OSX. Everything works as expected in our dev environment.
Docker Build
During deployment, we are trying to get the smallest file down for the Docker image.
Node Alpine is "Size": 117240360
Our docker is now "Size": 726653809
This is theDockerfile:
FROM node:14.5.0-alpine3.12
RUN apk add --no-cache \
alpine-sdk \
build-base \
cairo \
cairo-dev \
poppler \
poppler-qt5-dev
CMD [ "node" ]
So... pretty simple. All those dev files do take up a lot of space to be sure.
Possible Issues?
During the npm install we are seeing a number of warnings that I thought we could share:
> pdf-fill-form@5.0.1 install /app/node_modules/pdf-fill-form
> node-gyp rebuild
make: Entering directory '/app/node_modules/pdf-fill-form/build'
CXX(target) Release/obj.target/pdf_fill_form/src/pdf-fill-form.o
In file included from ../src/pdf-fill-form.cc:1:
../../nan/nan.h: In function 'void Nan::AsyncQueueWorker(Nan::AsyncWorker*)':
../../nan/nan.h:2294:62: warning: cast between incompatible function types from 'void (*)(uv_work_t*)' {aka 'void (*)(uv_work_s*)'} to 'uv_after_work_cb' {aka 'void (*)(uv_work_s*, int)'} [-Wcast-function-type]
2294 | , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
| ^
In file included from ../../nan/nan.h:56,
from ../src/pdf-fill-form.cc:1:
../src/pdf-fill-form.cc: At global scope:
/root/.cache/node-gyp/14.5.0/include/node/node.h:738:43: warning: cast between incompatible function types from 'void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)' {aka 'void (*)(v8::Local<v8::Object>)'} to 'node::addon_register_func' {aka 'void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)'} [-Wcast-function-type]
738 | (node::addon_register_func) (regfunc), \
| ^
/root/.cache/node-gyp/14.5.0/include/node/node.h:772:3: note: in expansion of macro 'NODE_MODULE_X'
772 | NODE_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage)
| ^~~~~~~~~~~~~
../src/pdf-fill-form.cc:27:1: note: in expansion of macro 'NODE_MODULE'
27 | NODE_MODULE(pdf_fill_form, InitAll)
| ^~~~~~~~~~~
CXX(target) Release/obj.target/pdf_fill_form/src/NodePopplerAsync.o
In file included from ../src/NodePopplerAsync.cc:1:
../../nan/nan.h: In function 'void Nan::AsyncQueueWorker(Nan::AsyncWorker*)':
../../nan/nan.h:2294:62: warning: cast between incompatible function types from 'void (*)(uv_work_t*)' {aka 'void (*)(uv_work_s*)'} to 'uv_after_work_cb' {aka 'void (*)(uv_work_s*, int)'} [-Wcast-function-type]
2294 | , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
| ^
CXX(target) Release/obj.target/pdf_fill_form/src/NodePoppler.o
In file included from ../src/NodePoppler.cc:1:
../../nan/nan.h: In function 'void Nan::AsyncQueueWorker(Nan::AsyncWorker*)':
../../nan/nan.h:2294:62: warning: cast between incompatible function types from 'void (*)(uv_work_t*)' {aka 'void (*)(uv_work_s*)'} to 'uv_after_work_cb' {aka 'void (*)(uv_work_s*, int)'} [-Wcast-function-type]
2294 | , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
| ^
../src/NodePoppler.cc: In function 'Nan::NAN_METHOD_RETURN_TYPE ReadBufferSync(Nan::NAN_METHOD_ARGS_TYPE)':
../src/NodePoppler.cc:539:7: warning: variable 'n' set but not used [-Wunused-but-set-variable]
539 | int n = 0;
| ^
../src/NodePoppler.cc: In function 'Nan::NAN_METHOD_RETURN_TYPE ReadSync(Nan::NAN_METHOD_ARGS_TYPE)':
../src/NodePoppler.cc:565:7: warning: variable 'n' set but not used [-Wunused-but-set-variable]
565 | int n = 0;
| ^
SOLINK_MODULE(target) Release/obj.target/pdf_fill_form.node
COPY Release/pdf_fill_form.node
make: Leaving directory '/app/node_modules/pdf-fill-form/build'
npm WARN savvy-docker-node@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
For our tests, we are running this docker file called testing.Dockerfile
FROM docker-pdf-fill-form:testing
WORKDIR /app/
COPY . /app/
RUN npm install
CMD [ "npm", "run", "test" ]
And, since we are here, this is the unit test:
const { readBuffer, writeBuffer } = require('pdf-fill-form');
const fs = require('fs');
describe('Get Fields from PDF', () => {
const testFilename = 'unlocked.pdf';
const testWriteFilename = 'filled.pdf';
const testValue = 'COUNTY_SET_VALUE_FROM_TEST';
it('Returns fields', async () => {
const pdfSource1 = fs.readFileSync(`${__dirname}/${testFilename}`);
const result = await readBuffer(pdfSource1);
console.log(result[1]);
expect(result[1].page).toEqual(0);
expect(result[1].id).toEqual(65537);
expect(result[1].type).toEqual('text');
expect(result[1].name).toEqual('PI_County');
expect(result[1].value).toEqual('');
});
it('Can fill out a form', async () => {
const pdfSource1 = fs.readFileSync(`${__dirname}/${testFilename}`);
const filledPdf = await writeBuffer(
pdfSource1,
{ PI_County: 'COUNTY_SET_VALUE_FROM_TEST' },
{ save: 'pdf', antialias: true }
);
expect(filledPdf).toBeDefined();
fs.writeFileSync(`${__dirname}/${testWriteFilename}`, filledPdf);
const pdfSource2 = fs.readFileSync(`${__dirname}/${testWriteFilename}`);
const result = await readBuffer(pdfSource2);
console.log(result[1]);
expect(result[1].page).toEqual(0);
expect(result[1].id).toEqual(65537);
expect(result[1].type).toEqual('text');
expect(result[1].name).toEqual('PI_County');
expect(result[1].value).toEqual(testValue);
});
});
I'll work on getting this on github to easily run, but really you can create both Dockerfile and testing.Dockerfile.
Create a node project with the the test jest --verbose and add in the above test in the same directory as your PDF file. I use __tests__.
Then here are my docker commands:
Build main Docker Image: docker build -t docker-pdf-fill-form:testing .
Build testing Docker Image: docker build -t form-test -f testing.Dockerfile .
Run testing Docker Image: docker run form-test
Error when testing on Docker node:14.5.0-alpine3.12
Overview
When we fill out a PDF in a docker container, it seems to work. Reading back in the filed out PDF results in an error:
NOTE: This error does not happen on OSX. Everything works as expected in our dev environment.
Docker Build
During deployment, we are trying to get the smallest file down for the Docker image.
Node Alpine is
"Size": 117240360Our docker is now
"Size": 726653809This is the
Dockerfile:So... pretty simple. All those dev files do take up a lot of space to be sure.
Possible Issues?
During the
npm installwe are seeing a number of warnings that I thought we could share:For our tests, we are running this docker file called
testing.DockerfileAnd, since we are here, this is the unit test:
I'll work on getting this on github to easily run, but really you can create both
Dockerfileandtesting.Dockerfile.Create a node project with the the test
jest --verboseand add in the above test in the same directory as your PDF file. I use__tests__.Then here are my docker commands:
Build main Docker Image:
docker build -t docker-pdf-fill-form:testing .Build testing Docker Image:
docker build -t form-test -f testing.Dockerfile .Run testing Docker Image:
docker run form-test