我的 Dockerized AdonisJS 项目遇到问题,Playwright 无法启动浏览器,导致错误消息:
M browserType.launch: Executable doesn't exist at /root/.cache/ms-playwright/chromium-1105/chrome-linux/chrome
这是我的 Dockerfile:
FROM node:20.11.1-alpine as base
# Install dependencies needed by Playwright
RUN apk add --no-cache \
libxkbcommon \
dbus \
ttf-freefont \
udev \
xvfb \
zlib \
chromium \
chromium-chromedriver \
nss \
freetype \
freetype-dev \
harfbuzz \
ca-certificates \
&& rm -rf /var/cache/apk/*
# install dependences
FROM base as deps
WORKDIR /app
COPY . .
COPY package.json package-lock.json ./
RUN npm install
# Install Playwright and browsers
RUN npx playwright install
# Production only deps stage
FROM base as production-deps
WORKDIR /app
ADD package.json package-lock.json ./
RUN npm install
# Install Playwright and browsers
RUN npx playwright install
# Build
FROM base as build
WORKDIR /app
COPY --from=deps /app/node_modules /app/node_modules
COPY . .
COPY .env.example .env
RUN npm run build
# Set the entry point for the container
FROM base
ENV NODE_ENV=production
WORKDIR /app
COPY --from=production-deps /app/node_modules /app/node_modules
COPY --from=build /app/build /app
COPY .env.example .env
EXPOSE 3333
CMD ["node", "./bin/server.js"]
Dockerfile 为 Playwright 和我的 AdonisJS 项目安装所有必需的依赖项。但是,当我运行容器时,我收到上述错误。
我已经验证了 npx playwright install 在 Docker 构建过程中执行。此外,Dockerfile 会将所有文件(包括模块)复制到名为 app 的文件夹中。
我正在尝试,但不起作用Playwright 不会在 Docker 容器中启动浏览器
JSON 包
{
"name": "",
"version": "0.0.0",
"private": true,
"type": "module",
"license": "UNLICENSED",
"scripts": {
"start": "node bin/server.js",
"build": "node ace build",
"dev": "node ace serve --watch",
"test": "node ace test",
"lint": "eslint .",
"format": "prettier --write .",
"typecheck": "tsc --noEmit"
},
"imports": {
"#controllers/*": "./app/controllers/*.js",
"#exceptions/*": "./app/exceptions/*.js",
"#models/*": "./app/models/*.js",
"#mails/*": "./app/mails/*.js",
"#services/*": "./app/services/*.js",
"#listeners/*": "./app/listeners/*.js",
"#events/*": "./app/events/*.js",
"#middleware/*": "./app/middleware/*.js",
"#validators/*": "./app/validators/*.js",
"#providers/*": "./providers/*.js",
"#policies/*": "./app/policies/*.js",
"#abilities/*": "./app/abilities/*.js",
"#database/*": "./database/*.js",
"#start/*": "./start/*.js",
"#tests/*": "./tests/*.js",
"#config/*": "./config/*.js"
},
"devDependencies": {
"@adonisjs/assembler": "^7.1.1",
"@adonisjs/eslint-config": "^1.2.1",
"@adonisjs/prettier-config": "^1.2.1",
"@adonisjs/tsconfig": "^1.2.1",
"@japa/api-client": "^2.0.2",
"@japa/assert": "^2.1.0",
"@japa/plugin-adonisjs": "^3.0.0",
"@japa/runner": "^3.1.1",
"@swc/core": "^1.3.107",
"@types/hbs": "^4.0.4",
"@types/jsdom": "^21.1.6",
"@types/luxon": "^3.4.2",
"@types/node": "^20.11.25",
"autoprefixer": "^10.4.17",
"eslint": "^8.56.0",
"pino-pretty": "^10.3.1",
"postcss": "^8.4.35",
"tailwindcss": "^3.4.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"vite": "^5.1.4"
},
"dependencies": {
"@adonisjs/auth": "^9.1.1",
"@adonisjs/core": "^6.2.2",
"@adonisjs/cors": "^2.2.1",
"@adonisjs/lucid": "^20.1.0",
"@adonisjs/session": "^7.1.1",
"@adonisjs/vite": "^2.0.2",
"@vinejs/vine": "^1.7.1",
"better-sqlite3": "^9.4.3",
"edge.js": "^6.0.1",
"handlebars": "^4.7.8",
"hbs": "^4.2.0",
"jsdom": "^24.0.0",
"luxon": "^3.4.4",
"playwright": "^1.42.0",
"puppeteer": "^22.3.0",
"reflect-metadata": "^0.2.1"
},
"eslintConfig": {
"extends": "@adonisjs/eslint-config/app"
},
"prettier": "@adonisjs/prettier-config"
}
我的 Docker 设置或 Playwright 配置中是否缺少某些内容可能会导致此问题?任何建议或见解将不胜感激。
我无法访问您项目的所有详细信息,但这里有一个可行的最小设置,您可以在其基础上构建您的设置。
🗎
Dockerfile
(我从 Alpine 基础映像更改为 Debian 基础映像,因为它可以更好地处理 Chrome 系统依赖项。同时从 build
阶段复制 Chrome 可执行文件。)
FROM node:20.11.1 as base
RUN apt-get update -q && \
apt-get install -q -y libasound2 libatk-bridge2.0-0 libgtk-4-1 libnss3 xdg-utils
# =============================================================================
FROM base as deps
WORKDIR /app
COPY package.json .
RUN npm install
# =============================================================================
FROM base as build
WORKDIR /app
COPY --from=deps /app/node_modules /app/node_modules
COPY . .
RUN npm run build
# =============================================================================
FROM base
ENV NODE_ENV=production
WORKDIR /app
COPY --from=deps /app/node_modules /app/node_modules
COPY --from=deps /root/.cache/ /root/.cache/
COPY --from=build /app/build /app/bin
EXPOSE 3333
CMD ["node", "./bin/server.js"]
🗎
package.json
(我使用 postinstall
脚本来安装 Chromium 可执行文件。)
{
"name": "test",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "node ace serve --watch",
"build": "node ace build --production",
"start": "node server.js",
"test": "node ace test",
"postinstall": "playwright install chromium"
},
"devDependencies": {
"@adonisjs/assembler": "^5.9.6",
"@japa/preset-adonis": "^1.2.0",
"@japa/runner": "^2.5.1",
"@types/proxy-addr": "^2.0.3",
"@types/source-map-support": "^0.5.10",
"adonis-preset-ts": "^2.1.0",
"pino-pretty": "^11.0.0",
"typescript": "~4.6",
"youch": "^3.3.3",
"youch-terminal": "^2.2.3"
},
"dependencies": {
"@adonisjs/core": "^5.9.0",
"playwright": "^1.42.1",
"proxy-addr": "^2.0.7",
"reflect-metadata": "^0.2.1",
"source-map-support": "^0.5.21"
}
}
🗎
server.ts
(只需加载页面并检查标题是否正确。)
import { chromium } from 'playwright';
async function launchChrome() {
const browser = await chromium.launch({
headless: true,
});
const page = await browser.newPage();
await page.goto('https://example.com');
const expectedTitle = 'Example Domain';
const title = await page.title();
console.log(`Page Title: ${title}`);
if (title === expectedTitle) {
console.log('The page was loaded successfully.');
} else {
console.error('The page did not load as expected.');
}
await browser.close();
}
launchChrome().catch(err => {
console.error(err);
process.exit(1);
});