Skip to content

Commit

Permalink
fix: buildx bake file spec (#7)
Browse files Browse the repository at this point in the history
- fix dockerfile
- remove i386 arch
- fix puppeteer running on arm
- use a fix from actions/setup-node#488 (comment)
- lint inside container
- remove double build for tests
- upgrade all deps
- fix linter errors
  • Loading branch information
olegstepura committed Nov 11, 2022
1 parent 1c7825d commit 3baa3da
Show file tree
Hide file tree
Showing 18 changed files with 2,774 additions and 3,888 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@ module.exports = {
'.eslintrc.js',
'.yarn',
'build',
'main.prod.js',
],
}
10 changes: 4 additions & 6 deletions .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ jobs:
runs-on: ubuntu-latest
env:
TAG: html-to-pdf
PUPPETEER_SKIP_DOWNLOAD: 1
DOCKER_BUILDKIT: 1
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '16'
cache: 'yarn'
- run: yarn install
- run: yarn lint --max-warnings 0
- name: Build container
run: docker build --file deploy/Dockerfile --target test --tag ${TAG} .
- name: Run lint in a container
run: docker run --rm ${TAG} yarn lint --max-warnings 0
- name: Run test in a container
run: docker run --rm ${TAG} yarn test
17 changes: 14 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3

# needed to properly run buildx, otherwise buildx fails
# https://github.com/docker/buildx/issues/495#issuecomment-1043341496
- name: Set up QEMU
id: qemu
uses: docker/setup-qemu-action@v2
with:
node-version: '16'
cache: 'yarn'
image: tonistiigi/binfmt:qemu-v6.2.0
platforms: amd64,arm64

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
with:
platforms: amd64,arm64

- name: Define docker image metadata
uses: docker/metadata-action@v4
id: meta
Expand All @@ -29,11 +38,13 @@ jobs:
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix=git-,format=short
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push
uses: docker/bake-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .npmversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.10.0
8.19.2
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v15.11.0
v19.0.1
6 changes: 6 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ vars:
nvm use;
COMPOSE: docker-compose --file deploy/docker-compose.yml

env:
DOCKER_TARGET: dev
PUPPETEER_SKIP_DOWNLOAD: 1

tasks:
default: task --list

Expand Down Expand Up @@ -85,5 +89,7 @@ tasks:

build:
desc: Build app image
env:
DOCKER_TARGET: prod
cmds:
- '{{ .COMPOSE }} build {{ .CLI_ARGS }}'
69 changes: 39 additions & 30 deletions deploy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
FROM node:16-alpine as builder

WORKDIR /app
COPY . /app

RUN yarn install && yarn build


FROM alpine:3.16 as prod

ARG RELEASE_ID
ARG CI_BUILD_DATE

ENV \
CHROME_BIN=/usr/bin/chromium-browser \
CHROME_PATH=/usr/lib/chromium/ \
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
RELEASE_ID=$RELEASE_ID \
CI_BUILD_DATE=$CI_BUILD_DATE
FROM node:19-alpine as base

# Installs latest Chromium package.
RUN \
Expand All @@ -30,48 +14,73 @@ RUN \
--repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing \
font-wqy-zenhei \
&& apk add --no-cache \
tini make gcc g++ python3 git nodejs npm yarn \
tini make gcc g++ python3 git \
&& mkdir -p /app/build \
&& adduser -D chrome \
&& chown -R chrome:chrome /app

WORKDIR /app

COPY deploy/local.conf /etc/fonts/local.conf
COPY --from=builder /app/build/main.prod.js .
COPY favicon.ico .
COPY deploy/docker-entrypoint.sh /docker-entrypoint.sh
COPY README.md .

# Run Chrome as non-privileged
USER chrome

ENTRYPOINT ["tini", "--"]

EXPOSE 4000
CMD ["/docker-entrypoint.sh"]


FROM prod as dev
FROM base as builder

# change user to bypass write limitations
USER root
ENV PUPPETEER_SKIP_DOWNLOAD=1

COPY . /app

RUN yarn install && yarn build


FROM base as prod

ENV \
CHROME_BIN=/usr/bin/chromium-browser \
CHROME_PATH=/usr/lib/chromium/ \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

COPY --from=builder /app/build/main.prod.js .

# Run Chrome as non-privileged
USER chrome


FROM base as dev

ENV \
CHROME_BIN=/usr/bin/chromium-browser \
CHROME_PATH=/usr/lib/chromium/ \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
RELEASE_ID=$RELEASE_ID \
CI_BUILD_DATE=$CI_BUILD_DATE

COPY . /app

RUN chown -R chrome ./

# change user back to one used by zenika image
USER chrome

RUN yarn install


FROM prod as test
FROM base as test

# change user to bypass write limitations
USER root
ENV \
CHROME_BIN=/usr/bin/chromium-browser \
CHROME_PATH=/usr/lib/chromium/ \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
RELEASE_ID=$RELEASE_ID \
CI_BUILD_DATE=$CI_BUILD_DATE

COPY . /app

RUN yarn
RUN yarn install
2 changes: 1 addition & 1 deletion deploy/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
build:
context: ../
dockerfile: deploy/Dockerfile
target: dev
target: "${DOCKER_TARGET}"
volumes:
- '../src/:/app/src/'
container_name: html-to-pdf
Expand Down
4 changes: 2 additions & 2 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ target "docker-metadata-action" {}
target "build" {
inherits = ["docker-metadata-action"]
context = "./"
dockerfile = "deploy/prod/Dockerfile"
dockerfile = "deploy/Dockerfile"
target = "prod"
platforms = [
"linux/386",
"linux/amd64",
"linux/arm64/v8",
]
Expand Down
72 changes: 36 additions & 36 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,49 @@
"test": "jest --colors"
},
"dependencies": {
"@sentry/node": "^6.7.2",
"@sentry/tracing": "^6.9.0",
"@types/body-parser": "^1.19.0",
"@types/marked": "^2.0.3",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"marked": "^2.1.2",
"prom-client": "^13.1.0",
"puppeteer": "^10.4.0"
"@sentry/node": "^7.19.0",
"@sentry/tracing": "^7.19.0",
"@types/body-parser": "^1.19.2",
"@types/marked": "^4.0.7",
"body-parser": "^1.20.1",
"express": "^4.18.2",
"marked": "^4.2.2",
"prom-client": "^14.1.0",
"puppeteer": "19.2.2",
"puppeteer-core": "19.2.2"
},
"devDependencies": {
"@types/express": "^4.17.12",
"@types/jest": "^26.0.23",
"@types/node": "^15.12.4",
"@types/puppeteer": "^5.4.4",
"@types/supertest": "^2.0.11",
"@types/terser-webpack-plugin": "^5.0.3",
"@types/express": "^4.17.14",
"@types/jest": "^29.2.2",
"@types/node": "^18.11.9",
"@types/supertest": "^2.0.12",
"@types/terser-webpack-plugin": "^5.0.4",
"@types/webpack": "^5.28.0",
"@types/webpack-node-externals": "^2.5.1",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
"@types/webpack-node-externals": "^2.5.3",
"@typescript-eslint/eslint-plugin": "^5.42.1",
"@typescript-eslint/parser": "^5.42.1",
"env-cmd": "^10.1.0",
"eslint": "^7.29.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-airbnb-typescript": "^12.3.1",
"eslint-config-prettier": "^8.3.0",
"eslint": "^8.27.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-ts": "^0.4.2",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-prettier": "^3.4.0",
"jest": "^27.0.5",
"nodemon": "^2.0.7",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.3.1",
"nodemon": "^2.0.20",
"npm-run-all": "^4.1.5",
"prettier": "^2.3.1",
"supertest": "^6.1.3",
"terser-webpack-plugin": "^5.1.3",
"ts-jest": "^27.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"typescript": "^4.2.4",
"webpack": "^5.37.0",
"webpack-cli": "^4.7.2"
"prettier": "^2.7.1",
"supertest": "^6.3.1",
"terser-webpack-plugin": "^5.3.6",
"ts-jest": "^29.0.3",
"ts-loader": "^9.4.1",
"ts-node": "^10.9.1",
"typescript": "^4.8.4",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0"
},
"engines": {
"node": "~15"
"node": "~16"
}
}
2 changes: 1 addition & 1 deletion src/router.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import express, { Request, Response, Router } from 'express'
import marked from 'marked'
import { marked } from 'marked'
import fs from 'fs'
import { register } from 'prom-client'
import { CaptureMime, CaptureParameters, CaptureType } from '~/interface'
Expand Down
2 changes: 2 additions & 0 deletions src/util/capture-return.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const captureAndReturn = async (
}
})
} catch (e) {
// eslint-disable-next-line no-console
console.error(e)
registerUnrecoverableError()
// it failed twice, we better exit now and restart node process
// eslint-disable-next-line no-console
Expand Down
6 changes: 3 additions & 3 deletions src/util/log-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import timestamp from '~/util/timestamp'

export const logRequestTime = async <T> (
requestInfo: string,
preRequestLog = false,
preRequestLog: boolean,
processRequest: () => Promise<T>,
): Promise<T> => {
const start = performance.now()
Expand Down Expand Up @@ -38,7 +38,7 @@ export const logRequestTime = async <T> (
export const processRequestError = async <T> (
requestInfo: string,
res: Response,
rethrow = false,
rethrow: boolean,
processRequest: () => Promise<T>,
): Promise<T | null> => {
let result: T | null = null
Expand All @@ -64,7 +64,7 @@ export const processRequestError = async <T> (
const logRequest = async <T> (
requestInfo: string,
res: Response,
preRequestLog = false,
preRequestLog: boolean,
processRequest: () => Promise<T>,
): Promise<T | null> => processRequestError(
requestInfo,
Expand Down
3 changes: 1 addition & 2 deletions test/unit/capture.capture.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import puppeteer from 'puppeteer'
import { mocked } from 'ts-jest/utils'
import capture, { defaultViewportOptions } from '~/controller/capture'
import { CaptureType } from '~/interface'

Expand All @@ -26,7 +25,7 @@ jest.mock('puppeteer', () => ({
}))

beforeEach(() => {
mocked(puppeteer.launch).mockClear()
jest.mocked(puppeteer.launch).mockClear()
Object.values(pageProto).forEach((v) => v.mockClear())
Object.values(browserProto).forEach((v) => v.mockClear())
})
Expand Down
2 changes: 1 addition & 1 deletion test/unit/error-trigger.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { checkUnrecoverableError, registerUnrecoverableError } from '~/util/error-trigger'

describe('Error trigger is persisted', () => {
it('should display readme when opening root', async () => {
it('check unrecoverable error', async () => {
expect(checkUnrecoverableError()).toBeFalsy()
registerUnrecoverableError()
expect(checkUnrecoverableError()).toBeTruthy()
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "ES5",
"module": "ESNext",
"module": "NodeNext",
"moduleResolution": "Node",
"lib": [
"ESNext",
Expand Down

0 comments on commit 3baa3da

Please sign in to comment.