imagemin / mozjpeg-bin

mozjpeg bin-wrapper that makes it seamlessly available as a local dependency
https://github.com/mozilla/mozjpeg
MIT License
119 stars 58 forks source link

Not working in node:alpine Docker base image #47

Closed kachkaev closed 3 years ago

kachkaev commented 5 years ago

I've got an app that relies on mozjpeg-bin the following way:

import imagemin from "imagemin";
import imageminMozjpeg from "imagemin-mozjpeg";

// ...

await imagemin(["/path/to/my/file.jpg"], "/output-path", {
  plugins: [imageminMozjpeg({ quality: 42 })],
});

Things work locally on macOS and in Docker, when an image is based on node:10.15.3 (Debian). However, when I switch to node:10.15.3-alpine, the following error shows up for each attempt to optimize an image:

Error in file: /path/to/my/file.jpg

spawn /app/node_modules/mozjpeg/vendor/cjpeg ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
    at onErrorNT (internal/child_process.js:415:16)
    at process._tickCallback (internal/process/next_tick.js:63:19)

I tried a few workaround including installing libjpeg-turbo and libjpeg-turbo-utils packages and even tried some crazy things like swapping the binary in node_modules/mozjpeg/vendor/cjpeg, but no result after hours of hacking. The only solution was to switch back to Debian at a cost of a large added container size.

What can be done to make mozjpeg work in Alpine? Happy to switch back, but unfortunately can't manage this myself.

divick commented 5 years ago

+1

divick commented 5 years ago

@kachkaev I have been able to resolve this issue. On investigating I found that imagemin-mozjpeg installs mozjpeg-bin but in absence of autoconf, automake, libtool, make, gcc, musl-dev and nasm cannot build mozjpeg-bin from source and pulls in a GLIBC linked binary from github. Since alpine linux has musl-dev, the cjpeg cannot run without rebuilding/relinking with musl libc.

Just install the above packages with apk add and then do npm install and it should work.

kachkaev commented 5 years ago

Great news @divick! Feel free to share the dockerfile recipe. I probably won’t change my setup for now, but people coming here from search will definitely be happy to see the solution!

divick commented 5 years ago

Additionally you may need zlib-dev, pkgconf and file packages to be installed in alpine image.

divick commented 5 years ago

Here is the recipe for docker image based on node:10-15-alpine, which has node v10 and yarn already installed.

One can use alpine-3.9 image too but would need to add build steps to install node and yarn/npm.

FROM node:10.15-alpine                                                                            

RUN apk --no-cache add shadow \                                                                   
    gcc \                                                                                         
    musl-dev \                                                                                    
    autoconf \                                                                                    
    automake \                                                                                    
    make \                                                                                        
    libtool \                                                                                     
    nasm \                                                                                        
    tiff \                                                                                        
    jpeg \                                                                                        
    zlib \                                                                                        
    zlib-dev \                                                                                    
    file \                                                                                        
    pkgconf \                                                                                     
    && yarn install
BenMatheja commented 3 years ago

Want to extend what @divick wrote. With the current image of node:alpine these dependencies allowed me to build mozjpeg within my drone-runner

- name: npm install
    image: node:alpine
    commands:
      - apk add autoconf automake libtool make tiff jpeg zlib zlib-dev pkgconf nasm file gcc musl-dev
      - npm install
1000ch commented 3 years ago

As above, we need to install appropriate dependencies for mozjpeg to use it on any platform including alpine.