photostructure / exiftool-vendored.js

Fast, cross-platform Node.js access to ExifTool
https://photostructure.github.io/exiftool-vendored.js/
MIT License
442 stars 45 forks source link

exiftool-vendored not working... no response #202

Closed hahamini closed 2 months ago

hahamini commented 2 months ago

I'm trying to use exiftool-vendored with docker and docker compose. However, there appears to be a bug that causes it to stop when calling Exiftool. Probably similar to issue #152, but it doesn't work even though Perl is installed.

Perl check

/app $ perl -v

This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-thread-multi

Copyright 1987-2023, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at https://www.perl.org/, the Perl Home Page.

package.json

{
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "exiftool-vendored": "^28.2.0",
    "formidable": "^3.5.1",
    "fs": "^0.0.1-security",
    "image-size": "^1.1.1",
    "mysql2": "^3.11.0",
    "next": "^14.2.5",
    "optionator": "^0.9.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "sharp": "^0.33.4",
    "swiper": "^11.1.4"
  },
  "devDependencies": {
    "@types/formidable": "^3.4.5",
    "@types/node": "^18.11.9",
    "@types/react": "^18.0.25",
    "@types/react-dom": "^18.0.9",
    "eslint": "^8.57.0",
    "eslint-config-next": "^14.2.5",
    "postcss": "^8",
    "tailwindcss": "3.4.1",
    "typescript": "^4.9.3"
  }
}

Dockerfile

FROM node:18-alpine AS base

# Install Perl
RUN apk add --no-cache perl

# Step 1. Rebuild the source code only when needed
FROM base AS builder

WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
# Omit --production flag for TypeScript devDependencies
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  elif [ -f package-lock.json ]; then npm ci; \
  elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i; \
  # Allow install without lockfile, so example works even without Node.js installed locally
  else echo "Warning: Lockfile not found. It is recommended to commit lockfiles to version control." && yarn install; \
  fi

COPY src ./src
COPY public ./public
COPY next.config.js .
COPY tsconfig.json .

# Environment variables must be present at build time
# https://github.com/vercel/next.js/discussions/14030
ARG ENV_VARIABLE
ENV ENV_VARIABLE=${ENV_VARIABLE}
ARG NEXT_PUBLIC_ENV_VARIABLE
ENV NEXT_PUBLIC_ENV_VARIABLE=${NEXT_PUBLIC_ENV_VARIABLE}

# Next.js collects completely anonymous telemetry data about general usage. Learn more here: https://nextjs.org/telemetry
# Uncomment the following line to disable telemetry at build time
# ENV NEXT_TELEMETRY_DISABLED 1

# Build Next.js based on the preferred package manager
RUN \
  if [ -f yarn.lock ]; then yarn build; \
  elif [ -f package-lock.json ]; then npm run build; \
  elif [ -f pnpm-lock.yaml ]; then pnpm build; \
  else npm run build; \
  fi

# Note: It is not necessary to add an intermediate step that does a full copy of `node_modules` here

# Step 2. Production image, copy all the files and run next
FROM base AS runner

WORKDIR /app

# Install Perl
# RUN apk add --no-cache perl

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Ensure the upload directory has the correct permissions
RUN mkdir -p /app/uploads && chown -R nextjs:nodejs /app/uploads

USER nextjs

COPY --from=builder /app/public ./public

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

# Environment variables must be redefined at run time
ARG ENV_VARIABLE
ENV ENV_VARIABLE=${ENV_VARIABLE}
ARG NEXT_PUBLIC_ENV_VARIABLE
ENV NEXT_PUBLIC_ENV_VARIABLE=${NEXT_PUBLIC_ENV_VARIABLE}

# Uncomment the following line to disable telemetry at run time
# ENV NEXT_TELEMETRY_DISABLED 1

# Note: Don't expose ports here, Compose will handle that for us

CMD ["node", "server.js"]

docker-compose

version: "3"

services:
  next-app:
    container_name: next-app
    build:
      context: ./next-app
      dockerfile: prod.Dockerfile
      args:
        ENV_VARIABLE: ${ENV_VARIABLE}
        NEXT_PUBLIC_ENV_VARIABLE: ${NEXT_PUBLIC_ENV_VARIABLE}
    restart: always
    ports:
      - 3000:3000
    networks:
      - photos-web
    env_file:
      - ./next-app/.env.local
    volumes:
      - uploads:/app/uploads

  # Add more containers below (nginx, postgres, etc.)

# Define a network, which allows containers to communicate
# with each other, by using their container name as a hostname
networks:
  photos-web:
    external: true

volumes:
  uploads:
mceachen commented 2 months ago

Thanks for taking the time to provide all these details!

I won’t be able to reproduce and debug this for several days. I’d suggest enabling logging from batch-cluster and this library: I suspect that either your PATH doesn’t include perl (and necessary perl libraries).

You can also try manually running node_modules/exiftool-vendored.pl/bin/exiftool -ver from within your project directory within your docker container to verify things are ok in there.

hahamini commented 2 months ago

@mceachen Based on your advice, I found the cause. I wrote Dockerfile using multistage, but the build result did not include exiftool-vendored.pl.

npm run build
# No exiftool-vendored.pl in build directory .next/standalone/node_modules.

I don't know why. So I solved it by adding the following code to my Dockerfile. COPY --from=builder --chown=nextjs:nodejs /app/node_modules/exiftool-vendored.pl ./node_modules/exiftool-vendored.pl

Thanks