11 Commits

Author SHA1 Message Date
estebanthi
85d380d8e4 Add CACHE_ENABLED toggle for IUAM cache
All checks were successful
CI / release (push) Successful in 1m15s
2026-01-23 17:22:18 +01:00
estebanthi
44660055af Switch to alpine chromium image
All checks were successful
CI / release (push) Successful in 2m17s
2026-01-18 15:07:34 +01:00
estebanthi
c14052556a fixed dockerfile
Some checks failed
CI / release (push) Failing after 2m16s
2026-01-18 14:34:32 +01:00
estebanthi
34822965d2 fixed byuild
All checks were successful
CI / release (push) Successful in 1m59s
2026-01-18 14:25:52 +01:00
estebanthi
2b65730d77 fixed
All checks were successful
CI / release (push) Successful in 1m45s
2026-01-18 14:17:43 +01:00
estebanthi
6557f28aab fixed dependencies
All checks were successful
CI / release (push) Successful in 1m54s
2026-01-18 14:10:33 +01:00
estebanthi
c8bfc9c219 fixed dependencies
Some checks failed
CI / release (push) Failing after 2m12s
2026-01-18 14:01:07 +01:00
estebanthi
0b019eaa04 fixed vulnerability
Some checks failed
CI / release (push) Failing after 1m55s
2026-01-18 13:54:38 +01:00
estebanthi
dcd929a4c5 Harden Docker production build
Some checks failed
CI / release (push) Failing after 37s
2026-01-18 11:38:14 +01:00
estebanthi
ca5402d15f fixed build
Some checks failed
CI / release (push) Failing after 2m54s
2026-01-18 08:51:15 +01:00
estebanthi
86ed863e59 fixed build
Some checks failed
CI / release (push) Failing after 51s
2026-01-18 08:48:30 +01:00
8 changed files with 1748 additions and 26 deletions

5
.dockerignore Normal file
View File

@@ -0,0 +1,5 @@
node_modules
cache
*.log
.DS_Store
.git

View File

@@ -17,8 +17,9 @@ jobs:
{
"name": "cf-bypass-fast",
"cache_ref": "cf-bypass-fast:buildcache",
"dockerfile": "./Dockerfile"
},
"dockerfile": "./Dockerfile",
"context": "./"
}
]
secrets:
registry_user: ${{ secrets.REGISTRY_USER }}

10
.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
node_modules/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
.DS_Store
.env
.env.*
!.env.example

View File

@@ -1,29 +1,48 @@
FROM node:20-slim
FROM node:20-alpine AS build
# Install Chrome and dependencies
RUN apt update && apt install -y \
wget gnupg ca-certificates xvfb \
fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 \
libatk1.0-0 libxss1 libnss3 libxcomposite1 libxdamage1 libxrandr2 libgbm1 \
&& wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
&& apt install -y ./google-chrome-stable_current_amd64.deb \
&& rm google-chrome-stable_current_amd64.deb
ENV NODE_ENV=production
RUN apk add --no-cache python3 make g++
RUN corepack enable
# Set working directory
WORKDIR /app
# Copy and install dependencies
COPY package*.json ./
RUN npm install
COPY package.json pnpm-lock.yaml ./
RUN corepack prepare pnpm@10.28.0 --activate \
&& pnpm install --frozen-lockfile --prod \
&& pnpm store prune
# Copy app code
COPY . .
# Expose port (match your app's port)
FROM node:20-alpine
ENV NODE_ENV=production
ENV CHROME_PATH=/usr/bin/chromium-browser
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
RUN apk add --no-cache chromium nss freetype harfbuzz ttf-freefont
# Remove npm/corepack to shrink attack surface and avoid bundled CVEs.
RUN rm -rf /usr/local/lib/node_modules/npm \
/usr/local/bin/npm \
/usr/local/bin/npx \
/usr/local/lib/node_modules/corepack \
/usr/local/bin/corepack
WORKDIR /app
COPY --from=build /app/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh
COPY --from=build --chown=node:node /app/package.json /app/package.json
COPY --from=build --chown=node:node /app/index.js /app/index.js
COPY --from=build --chown=node:node /app/endpoints /app/endpoints
COPY --from=build --chown=node:node /app/node_modules /app/node_modules
RUN mkdir -p /app/cache && chown -R node:node /app
USER node
EXPOSE 10000
# Start Xvfb and run the bot
CMD rm -f /tmp/.X99-lock && \
Xvfb :99 -screen 0 1024x768x24 & \
export DISPLAY=:99 && \
npm start
CMD ["/usr/local/bin/docker-entrypoint.sh"]

View File

@@ -63,6 +63,7 @@ npm start # Production mode
| `authToken` | `null` | API authentication token |
| `browserLimit` | `20` | Max concurrent browsers |
| `timeOut` | `60000` | Global timeout (ms) |
| `CACHE_ENABLED` | `true` | Enable IUAM response cache |
## 📡 API Endpoints

46
docker-entrypoint.sh Normal file
View File

@@ -0,0 +1,46 @@
#!/bin/sh
set -eu
resolve_chrome_path() {
if [ -n "${CHROME_PATH:-}" ] && [ -x "$CHROME_PATH" ]; then
return 0
fi
for candidate in \
/usr/bin/chromium-browser \
/usr/bin/chromium \
/usr/bin/google-chrome-stable \
/usr/bin/google-chrome \
/opt/google/chrome/google-chrome; do
if [ -x "$candidate" ]; then
CHROME_PATH="$candidate"
return 0
fi
done
if command -v chromium-browser >/dev/null 2>&1; then
CHROME_PATH="$(command -v chromium-browser)"
return 0
fi
if command -v chromium >/dev/null 2>&1; then
CHROME_PATH="$(command -v chromium)"
return 0
fi
if command -v google-chrome-stable >/dev/null 2>&1; then
CHROME_PATH="$(command -v google-chrome-stable)"
return 0
fi
if command -v google-chrome >/dev/null 2>&1; then
CHROME_PATH="$(command -v google-chrome)"
return 0
fi
echo "No Chrome/Chromium executable found. Set CHROME_PATH to a valid binary." >&2
exit 1
}
resolve_chrome_path
export CHROME_PATH
export PUPPETEER_EXECUTABLE_PATH="${PUPPETEER_EXECUTABLE_PATH:-$CHROME_PATH}"
exec node index.js

View File

@@ -13,6 +13,9 @@ global.timeOut = Number(process.env.timeOut) || 60000
const CACHE_DIR = path.join(__dirname, "cache")
const CACHE_FILE = path.join(CACHE_DIR, "cache.json")
const CACHE_TTL = 5 * 60 * 1000
const CACHE_ENABLED = process.env.CACHE_ENABLED
? !["0", "false", "no"].includes(process.env.CACHE_ENABLED.toLowerCase())
: true
function loadCache() {
if (!fs.existsSync(CACHE_FILE)) return {}
@@ -59,10 +62,10 @@ if (process.env.NODE_ENV !== 'development') {
async function createBrowser(proxyServer = null) {
const connectOptions = {
headless: false,
headless: "new",
turnstile: true,
connectOption: { defaultViewport: null },
disableXvfb: false,
disableXvfb: true,
}
if (proxyServer) {
@@ -109,7 +112,7 @@ app.post('/cloudflare', async (req, res) => {
}
let cacheKey, cached
if (data.mode === "iuam") {
if (CACHE_ENABLED && data.mode === "iuam") {
cacheKey = JSON.stringify(data)
cached = readCache(cacheKey)
@@ -147,7 +150,7 @@ app.post('/cloudflare', async (req, res) => {
.then(r => ({ ...r }))
.catch(err => ({ code: 500, message: err.message }))
if (!result.code || result.code === 200) {
if (CACHE_ENABLED && (!result.code || result.code === 200)) {
writeCache(cacheKey, result)
}
break

1637
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff