puppet 师/ Docker (目标.setAutoAttach):目标已关闭

egmofgnx  于 2023-02-21  发布在  Docker
关注(0)|答案(1)|浏览(228)

nestjs里有个项目
构建在Docker中生成
停靠文件

###################
# BUILD FOR LOCAL DEVELOPMENT
###################

FROM --platform=linux/amd64 node:18-alpine As development

# Create app directory
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY --chown=node:node package*.json ./

# Install app dependencies using the `npm ci` command instead of `npm install`
ENV PUPPETEER_SKIP_DOWNLOAD=true
RUN npm ci

# Bundle app source
COPY --chown=node:node . .

# Use the node user from the image (instead of the root user)
USER node

###################
# BUILD FOR PRODUCTION
###################

FROM --platform=linux/amd64 node:18-alpine As build

WORKDIR /usr/src/app

COPY --chown=node:node package*.json ./

# In order to run `npm run build` we need access to the Nest CLI which is a dev dependency. In the previous development stage we ran `npm ci` which installed all dependencies, so we can copy over the node_modules directory from the development image
COPY --chown=node:node --from=development /usr/src/app/node_modules ./node_modules

COPY --chown=node:node . .

# Run the build command which creates the production bundle
RUN npm run build

# Set NODE_ENV environment variable
ENV NODE_ENV production

# Running `npm ci` removes the existing node_modules directory and passing in --only=production ensures that only the production dependencies are installed. This ensures that the node_modules directory is as optimized as possible
ENV PUPPETEER_SKIP_DOWNLOAD=true
RUN npm ci --only=production && npm cache clean --force

USER node

###################
# PRODUCTION
###################

FROM --platform=linux/amd64 node:18-alpine As production

# Copy the bundled code from the build stage to the production image
COPY --chown=node:node --from=build /usr/src/app/node_modules ./node_modules
COPY --chown=node:node --from=build /usr/src/app/dist ./dist

RUN apk add chromium

EXPOSE 3010
ENV PORT 3010

ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Start the server using the production build
CMD [ "node", "dist/main.js" ]

启动容器时,控制台中出现错误

[Nest]  ERROR [ExceptionHandler] Protocol error (Target.setAutoAttach): Target closed.
 ProtocolError: Protocol error (Target.setAutoAttach): Target closed.
    at /node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:104:24
    at new Promise (<anonymous>)
    at Connection.send (/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Connection.js:100:16)
    at ChromeTargetManager.initialize (/node_modules/puppeteer-core/lib/cjs/puppeteer/common/ChromeTargetManager.js:247:82)
    at CDPBrowser._attach (/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Browser.js:156:76)
    at CDPBrowser._create (/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Browser.js:49:23)
    at ChromeLauncher.launch (/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ChromeLauncher.js:130:53)
    at async InstanceWrapper.useFactory [as metatype] (/node_modules/@noahqte/nest-puppeteer/dist/puppeteer-core.module.js:38:24)
    at async Injector.instantiateClass (/node_modules/@nestjs/core/injector/injector.js:355:37)
    at async callback (/node_modules/@nestjs/core/injector/injector.js:56:34)

我一直在考虑解决这个错误很长一段时间了。尝试了不同的方法来解决它
puppet 师通过nestjs-puppeteer库连接
服务

constructor(
    private appService: AppService,
    @InjectBrowser() private readonly browser: Browser,
  ) {}
async onSendForm1(data, @Ctx() ctx?: Context) {
    const page = await this.browser.newPage()
    await page.setRequestInterception(true)
    await page.once('request', (interceptedRequest) => {
      interceptedRequest.continue({ method: 'POST', postData: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } })
    })
    await page.goto('http://localhost:3010', { waitUntil: 'networkidle2' })
    const fileName = Guid.newGuid().toString()
    await page.pdf({
      path: `${this.appService.pathFile}${fileName}.pdf`,
      scale: 0.9,
      format: 'A4',
      landscape: false,
      pageRanges: '1,3',
    })
    await page.close()
    await this.browser.close()
}

app.module

@Module({
  imports: [
    PuppeteerModule.forRoot({ pipe: true, isGlobal: true }),
  ],
  controllers: [AppController],
  providers: [AppService],
  exports: [AppService],
})

如果指定env ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser,则容器中的 chrome 有效
你能帮忙吗

db2dz4w8

db2dz4w81#

我找到了解决问题的办法
第1步:删除模板
npm uninstall nestjs-puppeteer
步骤2:我必须更改dockerfile
停靠文件

FROM node:18-alpine As development

# Create app directory
WORKDIR /usr/src/app

ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY --chown=node:node package*.json ./

# Install app dependencies using the `npm ci` command instead of `npm install`
RUN npm install

# Bundle app source
COPY --chown=node:node . .

# Use the node user from the image (instead of the root user)
USER node

###################
# BUILD FOR PRODUCTION
###################

FROM node:18-alpine As build

WORKDIR /usr/src/app

ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

COPY --chown=node:node package*.json ./

# In order to run `npm run build` we need access to the Nest CLI which is a dev dependency. In the previous development stage we ran `npm ci` which installed all dependencies, so we can copy over the node_modules directory from the development image
COPY --chown=node:node --from=development /usr/src/app/node_modules ./node_modules

COPY --chown=node:node . .

# Run the build command which creates the production bundle
RUN npm run build

# Set NODE_ENV environment variable
ENV NODE_ENV production

# Running `npm ci` removes the existing node_modules directory and passing in --only=production ensures that only the production dependencies are installed. This ensures that the node_modules directory is as optimized as possible
RUN npm install && npm cache clean --force

USER node

###################
# PRODUCTION
###################

FROM node:18-alpine As production

ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

EXPOSE 3010

RUN apk add --no-cache \
      chromium \
      nss \
      freetype \
      harfbuzz \
      ca-certificates \
      ttf-freefont \
      nano \
      sudo \
      bash

# Copy the bundled code from the build stage to the production image
COPY --chown=node:node --from=build /usr/src/app/dist ./dist
COPY --chown=node:node --from=build /usr/src/app/node_modules ./dist/node_modules

# Start the server using the production build
USER node
CMD [ "node", "dist/main.js" ]

步骤3:更改init浏览器
service.ts

import puppeteer from 'puppeteer'

const browser = await puppeteer.launch({
      headless: true,
      args: ['--disable-gpu', '--disable-dev-shm-usage', '--disable-setuid-sandbox', '--no-sandbox'],
    })
    const page = await browser.newPage()
    await page.setRequestInterception(true)
    page.once('request', (interceptedRequest) => {
      interceptedRequest.continue({
        method: 'POST',
        postData: JSON.stringify(data),
        headers: { 'Content-Type': 'application/json' },
      })
    })
    await page.goto('http://localhost:3010', { waitUntil: 'networkidle2' })
    await page.waitForSelector('body')
    const fileName = Guid.newGuid().toString()
    await page.pdf({
      path: `${this.appService.pathFile}${fileName}.pdf`,
      scale: 0.9,
      format: 'A4',
      landscape: false,
      pageRanges: '1,2',
    })
    await browser.close()

如果以root用户身份运行容器,则会发生此错误

相关问题