mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40cc019a51 | ||
|
|
781094ab05 | ||
|
|
21cfe2e535 | ||
|
|
4f72684080 | ||
|
|
5ac514366e | ||
|
|
d5d6285eef | ||
|
|
0e34b41bce | ||
|
|
e157066bcc | ||
|
|
f43a63ac6e | ||
|
|
a5828fa01a | ||
|
|
662d3ff795 | ||
|
|
a97f05db3b | ||
|
|
5a439ca70c |
2
.github/workflows/continuous_delivery.yml
vendored
2
.github/workflows/continuous_delivery.yml
vendored
@@ -24,4 +24,4 @@ jobs:
|
|||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
run: |
|
run: |
|
||||||
make release GOTENBERG_VERSION=${{ github.event.release.tag_name }}
|
make release GOTENBERG_VERSION=${{ github.event.release.tag_name }}
|
||||||
make release GOTENBERG_VERSION=${{ github.event.release.tag_name }} DOCKER_REGISTRY=thecodingmachine
|
make release GOTENBERG_VERSION=${{ github.event.release.tag_name }} DOCKER_REPOSITORY=thecodingmachine
|
||||||
|
|||||||
2
.github/workflows/continuous_integration.yml
vendored
2
.github/workflows/continuous_integration.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
- name: Run linters
|
- name: Run linters
|
||||||
uses: golangci/golangci-lint-action@v2
|
uses: golangci/golangci-lint-action@v2
|
||||||
with:
|
with:
|
||||||
version: v1.39
|
version: v1.42
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
needs:
|
needs:
|
||||||
|
|||||||
22
Makefile
22
Makefile
@@ -5,13 +5,13 @@ help: ## Show the help
|
|||||||
.PHONY: it
|
.PHONY: it
|
||||||
it: build build-tests ## Initialize the development environment
|
it: build build-tests ## Initialize the development environment
|
||||||
|
|
||||||
GOLANG_VERSION=1.16
|
GOLANG_VERSION=1.17
|
||||||
DOCKER_REGISTRY=gotenberg
|
DOCKER_REPOSITORY=gotenberg
|
||||||
GOTENBERG_VERSION=snapshot
|
GOTENBERG_VERSION=snapshot
|
||||||
GOTENBERG_USER_GID=1001
|
GOTENBERG_USER_GID=1001
|
||||||
GOTENBERG_USER_UID=1001
|
GOTENBERG_USER_UID=1001
|
||||||
PDFTK_VERSION=1353200058 # See https://gitlab.com/pdftk-java/pdftk/-/releases - Binary package.
|
PDFTK_VERSION=1353200058 # See https://gitlab.com/pdftk-java/pdftk/-/releases - Binary package.
|
||||||
GOLANGCI_LINT_VERSION=v1.39.0 # See https://github.com/golangci/golangci-lint/releases.
|
GOLANGCI_LINT_VERSION=v1.42.0 # See https://github.com/golangci/golangci-lint/releases.
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: ## Build the Gotenberg's Docker image
|
build: ## Build the Gotenberg's Docker image
|
||||||
@@ -21,7 +21,7 @@ build: ## Build the Gotenberg's Docker image
|
|||||||
--build-arg GOTENBERG_USER_GID=$(GOTENBERG_USER_GID) \
|
--build-arg GOTENBERG_USER_GID=$(GOTENBERG_USER_GID) \
|
||||||
--build-arg GOTENBERG_USER_UID=$(GOTENBERG_USER_UID) \
|
--build-arg GOTENBERG_USER_UID=$(GOTENBERG_USER_UID) \
|
||||||
--build-arg PDFTK_VERSION=$(PDFTK_VERSION) \
|
--build-arg PDFTK_VERSION=$(PDFTK_VERSION) \
|
||||||
-t $(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION) \
|
-t $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION) \
|
||||||
-f build/Dockerfile .
|
-f build/Dockerfile .
|
||||||
|
|
||||||
GOTENBERG_GRACEFUL_SHUTDOWN_DURATION=30s
|
GOTENBERG_GRACEFUL_SHUTDOWN_DURATION=30s
|
||||||
@@ -57,7 +57,7 @@ PDFENGINES_DISABLE_ROUTES=false
|
|||||||
run: ## Start a Gotenberg container
|
run: ## Start a Gotenberg container
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-p $(API_PORT):$(API_PORT) \
|
-p $(API_PORT):$(API_PORT) \
|
||||||
$(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION) \
|
$(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION) \
|
||||||
gotenberg \
|
gotenberg \
|
||||||
--gotenberg-graceful-shutdown-duration=$(GOTENBERG_GRACEFUL_SHUTDOWN_DURATION) \
|
--gotenberg-graceful-shutdown-duration=$(GOTENBERG_GRACEFUL_SHUTDOWN_DURATION) \
|
||||||
--api-port=$(API_PORT) \
|
--api-port=$(API_PORT) \
|
||||||
@@ -92,24 +92,24 @@ run: ## Start a Gotenberg container
|
|||||||
build-tests: ## Build the tests' Docker image
|
build-tests: ## Build the tests' Docker image
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg GOLANG_VERSION=$(GOLANG_VERSION) \
|
--build-arg GOLANG_VERSION=$(GOLANG_VERSION) \
|
||||||
--build-arg DOCKER_REGISTRY=$(DOCKER_REGISTRY) \
|
--build-arg DOCKER_REPOSITORY=$(DOCKER_REPOSITORY) \
|
||||||
--build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) \
|
--build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) \
|
||||||
--build-arg GOLANGCI_LINT_VERSION=$(GOLANGCI_LINT_VERSION) \
|
--build-arg GOLANGCI_LINT_VERSION=$(GOLANGCI_LINT_VERSION) \
|
||||||
-t $(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION)-tests \
|
-t $(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION)-tests \
|
||||||
-f test/Dockerfile .
|
-f test/Dockerfile .
|
||||||
|
|
||||||
.PHONY: tests
|
.PHONY: tests
|
||||||
tests: ## Start the testing environment
|
tests: ## Start the testing environment
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-v $(PWD):/tests \
|
-v $(PWD):/tests \
|
||||||
$(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION)-tests \
|
$(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION)-tests \
|
||||||
bash
|
bash
|
||||||
|
|
||||||
.PHONY: tests-once
|
.PHONY: tests-once
|
||||||
tests-once: ## Run the tests once (prefer the "tests" command while developing)
|
tests-once: ## Run the tests once (prefer the "tests" command while developing)
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v $(PWD):/tests \
|
-v $(PWD):/tests \
|
||||||
$(DOCKER_REGISTRY)/gotenberg:$(GOTENBERG_VERSION)-tests \
|
$(DOCKER_REPOSITORY)/gotenberg:$(GOTENBERG_VERSION)-tests \
|
||||||
gotest
|
gotest
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
@@ -123,11 +123,11 @@ godoc: ## Run a webserver with Gotenberg godoc (go get golang.org/x/tools/cmd/go
|
|||||||
godoc -http=:6060
|
godoc -http=:6060
|
||||||
|
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
release: ## Build the Gotenberg's Docker image for linux/amd64 and linux/arm64 platforms, then push it to a Docker Registry
|
release: ## Build the Gotenberg's Docker image for linux/amd64 and linux/arm64 platforms, then push it to a Docker repository
|
||||||
./scripts/release.sh \
|
./scripts/release.sh \
|
||||||
$(GOLANG_VERSION) \
|
$(GOLANG_VERSION) \
|
||||||
$(GOTENBERG_VERSION) \
|
$(GOTENBERG_VERSION) \
|
||||||
$(GOTENBERG_USER_GID) \
|
$(GOTENBERG_USER_GID) \
|
||||||
$(GOTENBERG_USER_UID) \
|
$(GOTENBERG_USER_UID) \
|
||||||
$(PDFTK_VERSION) \
|
$(PDFTK_VERSION) \
|
||||||
$(DOCKER_REGISTRY)
|
$(DOCKER_REPOSITORY)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Open a terminal and run the following command:
|
|||||||
docker run --rm -p 3000:3000 gotenberg/gotenberg:7
|
docker run --rm -p 3000:3000 gotenberg/gotenberg:7
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, using the historic Docker registry from our sponsor [TheCodingMachine](https://www.thecodingmachine.com):
|
Alternatively, using the historic Docker repository from our sponsor [TheCodingMachine](https://www.thecodingmachine.com):
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run --rm -p 3000:3000 thecodingmachine/gotenberg:7
|
docker run --rm -p 3000:3000 thecodingmachine/gotenberg:7
|
||||||
|
|||||||
@@ -19,15 +19,14 @@ RUN go mod download &&\
|
|||||||
|
|
||||||
# Copy the source code.
|
# Copy the source code.
|
||||||
COPY cmd ./cmd
|
COPY cmd ./cmd
|
||||||
COPY internal ./internal
|
|
||||||
COPY pkg ./pkg
|
COPY pkg ./pkg
|
||||||
|
|
||||||
# Build the binary.
|
# Build the binary.
|
||||||
ARG GOTENBERG_VERSION
|
ARG GOTENBERG_VERSION
|
||||||
|
|
||||||
RUN go build -o gotenberg -ldflags "-X 'github.com/gotenberg/gotenberg/v7/internal/app/gotenberg.version=$GOTENBERG_VERSION'" cmd/gotenberg/main.go
|
RUN go build -o gotenberg -ldflags "-X 'github.com/gotenberg/gotenberg/v7/cmd.Version=$GOTENBERG_VERSION'" cmd/gotenberg/main.go
|
||||||
|
|
||||||
FROM debian:buster-slim
|
FROM debian:bullseye-slim
|
||||||
|
|
||||||
ARG GOTENBERG_VERSION
|
ARG GOTENBERG_VERSION
|
||||||
|
|
||||||
@@ -51,6 +50,11 @@ ARG GOTENBERG_USER_GID
|
|||||||
ARG GOTENBERG_USER_UID
|
ARG GOTENBERG_USER_UID
|
||||||
ARG PDFTK_VERSION
|
ARG PDFTK_VERSION
|
||||||
|
|
||||||
|
# Script for installing either Google Chrome stable on amd64 architecture or
|
||||||
|
# Chromium on arm64 architecture.
|
||||||
|
# See https://github.com/gotenberg/gotenberg/issues/328.
|
||||||
|
COPY build/install-chromium.sh /tmp/install-chromium.sh
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Create a non-root user.
|
# Create a non-root user.
|
||||||
# All processes in the Docker container will run with this dedicated user.
|
# All processes in the Docker container will run with this dedicated user.
|
||||||
@@ -62,7 +66,7 @@ RUN \
|
|||||||
# Note: procps for "top" command (useful when debugging processes).
|
# Note: procps for "top" command (useful when debugging processes).
|
||||||
# Note: tini is a helper for reaping zombie processes.
|
# Note: tini is a helper for reaping zombie processes.
|
||||||
apt-get update -qq &&\
|
apt-get update -qq &&\
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends curl gnupg procps tini &&\
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends curl gnupg procps tini python3 default-jre-headless &&\
|
||||||
# Install fonts.
|
# Install fonts.
|
||||||
# Credits:
|
# Credits:
|
||||||
# https://github.com/arachnys/athenapdf/blob/master/cli/Dockerfile.
|
# https://github.com/arachnys/athenapdf/blob/master/cli/Dockerfile.
|
||||||
@@ -85,6 +89,7 @@ RUN \
|
|||||||
fonts-telu \
|
fonts-telu \
|
||||||
fonts-thai-tlwg \
|
fonts-thai-tlwg \
|
||||||
ttf-wqy-zenhei \
|
ttf-wqy-zenhei \
|
||||||
|
fonts-arphic-ukai \
|
||||||
fonts-arphic-uming \
|
fonts-arphic-uming \
|
||||||
fonts-ipafont-mincho \
|
fonts-ipafont-mincho \
|
||||||
fonts-ipafont-gothic \
|
fonts-ipafont-gothic \
|
||||||
@@ -103,23 +108,25 @@ RUN \
|
|||||||
fonts-sil-gentium \
|
fonts-sil-gentium \
|
||||||
fonts-sil-gentium-basic &&\
|
fonts-sil-gentium-basic &&\
|
||||||
rm -f ./ttf-mscorefonts-installer_3.8_all.deb &&\
|
rm -f ./ttf-mscorefonts-installer_3.8_all.deb &&\
|
||||||
echo "deb https://httpredir.debian.org/debian/ buster-backports main contrib non-free" >> /etc/apt/sources.list &&\
|
# Install Google Chrome / Chromium.
|
||||||
|
/tmp/install-chromium.sh &&\
|
||||||
|
# Install LibreOffice.
|
||||||
|
# Note: we use the sid distribution to get the latest LibreOffice version.
|
||||||
|
# See https://github.com/gotenberg/gotenberg/pull/322.
|
||||||
|
echo "deb https://httpredir.debian.org/debian/ sid main contrib non-free" >> /etc/apt/sources.list &&\
|
||||||
apt-get update -qq &&\
|
apt-get update -qq &&\
|
||||||
# Install Chromium and LibreOffice.
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends -t sid libreoffice &&\
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends chromium &&\
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends -t buster-backports libreoffice &&\
|
|
||||||
# Download unoconv (Python script).
|
# Download unoconv (Python script).
|
||||||
curl -Ls https://raw.githubusercontent.com/dagwieers/unoconv/master/unoconv -o /usr/bin/unoconv &&\
|
curl -Ls https://raw.githubusercontent.com/dagwieers/unoconv/master/unoconv -o /usr/bin/unoconv &&\
|
||||||
chmod +x /usr/bin/unoconv &&\
|
chmod +x /usr/bin/unoconv &&\
|
||||||
# unoconv will look for the Python binary, which has to be at version 3.
|
# unoconv will look for the Python binary, which has to be at version 3.
|
||||||
ln -s /usr/bin/python3 /usr/bin/python &&\
|
ln -s /usr/bin/python3 /usr/bin/python &&\
|
||||||
# Download PDFtk.
|
# Download PDFtk.
|
||||||
# Credits: https://github.com/thecodingmachine/gotenberg/pull/273.
|
# See https://github.com/gotenberg/gotenberg/pull/273.
|
||||||
curl -o /usr/bin/pdftk-all.jar "https://gitlab.com/pdftk-java/pdftk/-/jobs/$PDFTK_VERSION/artifacts/raw/build/libs/pdftk-all.jar" &&\
|
curl -o /usr/bin/pdftk-all.jar "https://gitlab.com/pdftk-java/pdftk/-/jobs/$PDFTK_VERSION/artifacts/raw/build/libs/pdftk-all.jar" &&\
|
||||||
chmod a+x /usr/bin/pdftk-all.jar &&\
|
chmod a+x /usr/bin/pdftk-all.jar &&\
|
||||||
# See https://github.com/nextcloud/docker/issues/380.
|
# See https://github.com/nextcloud/docker/issues/380.
|
||||||
mkdir -p /usr/share/man/man1mkdir -p /usr/share/man/man1 &&\
|
mkdir -p /usr/share/man/man1mkdir -p /usr/share/man/man1 &&\
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends default-jre-headless &&\
|
|
||||||
# Cleanup.
|
# Cleanup.
|
||||||
# Note: the Debian image does automatically a clean after each install thanks to a hook.
|
# Note: the Debian image does automatically a clean after each install thanks to a hook.
|
||||||
# Therefore, there is no need for apt-get clean.
|
# Therefore, there is no need for apt-get clean.
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# Note: ARG instructions do not create additional layers.
|
# Note: ARG instructions do not create additional layers.
|
||||||
# Instead, next layers will concatenate them.
|
# Instead, next layers will concatenate them.
|
||||||
ARG DOCKER_REGISTRY
|
ARG DOCKER_REPOSITORY
|
||||||
ARG GOTENBERG_VERSION
|
ARG GOTENBERG_VERSION
|
||||||
|
|
||||||
FROM $DOCKER_REGISTRY/gotenberg:$GOTENBERG_VERSION
|
FROM $DOCKER_REPOSITORY/gotenberg:$GOTENBERG_VERSION
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
|
|||||||
15
build/install-chromium.sh
Executable file
15
build/install-chromium.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ARCH=$(dpkg --print-architecture)
|
||||||
|
|
||||||
|
if [[ "$ARCH" == "amd64" ]]; then
|
||||||
|
curl https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
|
||||||
|
echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | tee /etc/apt/sources.list.d/google-chrome.list
|
||||||
|
apt-get update -qq
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends --allow-unauthenticated google-chrome-stable
|
||||||
|
mv /usr/bin/google-chrome-stable /usr/bin/chromium
|
||||||
|
else
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends chromium
|
||||||
|
fi
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package gotenberg
|
package gotenbergcmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -25,10 +25,13 @@ Version: %s
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
`
|
`
|
||||||
|
|
||||||
var version = "snapshot"
|
// Version is the... version of the Gotenberg application. We set it at the
|
||||||
|
// build stage of the Docker image.
|
||||||
|
var Version = "snapshot"
|
||||||
|
|
||||||
|
// Run starts the Gotenberg application. Call this in the main of your program.
|
||||||
func Run() {
|
func Run() {
|
||||||
fmt.Printf(banner, version)
|
fmt.Printf(banner, Version)
|
||||||
|
|
||||||
// Creates the roo` FlagSet and adds the modules flags to it.
|
// Creates the roo` FlagSet and adds the modules flags to it.
|
||||||
fs := flag.NewFlagSet("gotenberg", flag.ExitOnError)
|
fs := flag.NewFlagSet("gotenberg", flag.ExitOnError)
|
||||||
@@ -1,16 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gotenbergapp "github.com/gotenberg/gotenberg/v7/internal/app/gotenberg"
|
gotenbergcmd "github.com/gotenberg/gotenberg/v7/cmd"
|
||||||
|
|
||||||
// Gotenberg modules.
|
// Gotenberg modules.
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/standard"
|
_ "github.com/gotenberg/gotenberg/v7/pkg/standard"
|
||||||
// PDF engines.
|
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice/pdfengine"
|
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/pdfcpu"
|
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/pdftk"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
gotenbergapp.Run()
|
gotenbergcmd.Run()
|
||||||
}
|
}
|
||||||
|
|||||||
24
go.mod
24
go.mod
@@ -1,11 +1,11 @@
|
|||||||
module github.com/gotenberg/gotenberg/v7
|
module github.com/gotenberg/gotenberg/v7
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexliesenfeld/health v0.6.0
|
github.com/alexliesenfeld/health v0.6.0
|
||||||
github.com/andybalholm/brotli v1.0.3 // indirect
|
github.com/andybalholm/brotli v1.0.3 // indirect
|
||||||
github.com/chromedp/cdproto v0.0.0-20210808225517-c36c1bd4c35e
|
github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4
|
||||||
github.com/chromedp/chromedp v0.7.4
|
github.com/chromedp/chromedp v0.7.4
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
@@ -36,3 +36,23 @@ require (
|
|||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.7
|
||||||
golang.org/x/tools v0.1.5 // indirect
|
golang.org/x/tools v0.1.5 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
|
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||||
|
github.com/dsnet/compress v0.0.1 // indirect
|
||||||
|
github.com/gobwas/httphead v0.1.0 // indirect
|
||||||
|
github.com/gobwas/pool v0.2.1 // indirect
|
||||||
|
github.com/gobwas/ws v1.1.0 // indirect
|
||||||
|
github.com/gorilla/css v1.0.0 // indirect
|
||||||
|
github.com/hhrutter/lzw v0.0.0-20190829144645-6f07a24e8650 // indirect
|
||||||
|
github.com/hhrutter/tiff v0.0.0-20190829141212-736cae8d0bc7 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -9,8 +9,8 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3
|
|||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/chromedp/cdproto v0.0.0-20210713064928-7d28b402946a/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
github.com/chromedp/cdproto v0.0.0-20210713064928-7d28b402946a/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||||
github.com/chromedp/cdproto v0.0.0-20210808225517-c36c1bd4c35e h1:uYQIvPKwL7YQh+tQC+EUXmvWosBeOYbJZKrh4NnS0UM=
|
github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4 h1:cD7F5LfNjC4dtb+BQe1KxxE8RsceYtS+Kyo+yEs4iUc=
|
||||||
github.com/chromedp/cdproto v0.0.0-20210808225517-c36c1bd4c35e/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
github.com/chromedp/cdproto v0.0.0-20210823203301-2c0adcc9edc4/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||||
github.com/chromedp/chromedp v0.7.4 h1:U+0d3WbB/Oj4mDuBOI0P7S3PJEued5UZIl5AJ3QulwU=
|
github.com/chromedp/chromedp v0.7.4 h1:U+0d3WbB/Oj4mDuBOI0P7S3PJEued5UZIl5AJ3QulwU=
|
||||||
github.com/chromedp/chromedp v0.7.4/go.mod h1:dBj+SXuQHznp6ZPwZeDDEBZKwclUwDLbZ0hjMialMYs=
|
github.com/chromedp/chromedp v0.7.4/go.mod h1:dBj+SXuQHznp6ZPwZeDDEBZKwclUwDLbZ0hjMialMYs=
|
||||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||||
|
|||||||
@@ -382,11 +382,7 @@ func (a *API) Start() error {
|
|||||||
checks := append(a.healthChecks, health.WithTimeout(a.processTimeout))
|
checks := append(a.healthChecks, health.WithTimeout(a.processTimeout))
|
||||||
checker := health.NewChecker(checks...)
|
checker := health.NewChecker(checks...)
|
||||||
|
|
||||||
return func(echoCtx echo.Context) error {
|
return echo.WrapHandler(health.NewHandler(checker))
|
||||||
health.NewHandler(checker).ServeHTTP(echoCtx.Response().Writer, echoCtx.Request())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}(),
|
}(),
|
||||||
timeoutMiddleware(hardTimeout),
|
timeoutMiddleware(hardTimeout),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -257,12 +257,18 @@ func (mod Chromium) Routes() ([]api.MultipartFormDataRoute, error) {
|
|||||||
// drastically. In such a scenario, the given context may also be done before
|
// drastically. In such a scenario, the given context may also be done before
|
||||||
// the end of the conversion.
|
// the end of the conversion.
|
||||||
func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath string, options Options) error {
|
func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath string, options Options) error {
|
||||||
|
debug := debugLogger{logger: logger.Named("chromium.debug")}
|
||||||
userProfileDirPath := gotenberg.NewDirPath()
|
userProfileDirPath := gotenberg.NewDirPath()
|
||||||
|
|
||||||
args := append(chromedp.DefaultExecAllocatorOptions[:],
|
args := append(chromedp.DefaultExecAllocatorOptions[:],
|
||||||
|
chromedp.CombinedOutput(debug),
|
||||||
chromedp.ExecPath(mod.binPath),
|
chromedp.ExecPath(mod.binPath),
|
||||||
chromedp.NoSandbox,
|
chromedp.NoSandbox,
|
||||||
// See:
|
// See:
|
||||||
|
// https://github.com/gotenberg/gotenberg/issues/327
|
||||||
|
// https://github.com/chromedp/chromedp/issues/904
|
||||||
|
chromedp.DisableGPU,
|
||||||
|
// See:
|
||||||
// https://github.com/puppeteer/puppeteer/issues/661
|
// https://github.com/puppeteer/puppeteer/issues/661
|
||||||
// https://github.com/puppeteer/puppeteer/issues/2410
|
// https://github.com/puppeteer/puppeteer/issues/2410
|
||||||
chromedp.Flag("font-render-hinting", "none"),
|
chromedp.Flag("font-render-hinting", "none"),
|
||||||
@@ -284,7 +290,9 @@ func (mod Chromium) PDF(ctx context.Context, logger *zap.Logger, URL, outputPath
|
|||||||
allocatorCtx, cancel := chromedp.NewExecAllocator(ctx, args...)
|
allocatorCtx, cancel := chromedp.NewExecAllocator(ctx, args...)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
taskCtx, cancel := chromedp.NewContext(allocatorCtx)
|
taskCtx, cancel := chromedp.NewContext(allocatorCtx,
|
||||||
|
chromedp.WithDebugf(debug.Printf),
|
||||||
|
)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// We validate the "main" URL against our allow / deny lists.
|
// We validate the "main" URL against our allow / deny lists.
|
||||||
|
|||||||
31
pkg/modules/chromium/debug.go
Normal file
31
pkg/modules/chromium/debug.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package chromium
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// debugLogger is wrapper around a zap.Logger which is used for debugging
|
||||||
|
// Chromium.
|
||||||
|
type debugLogger struct {
|
||||||
|
logger *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write logs the bytes in a debug message.
|
||||||
|
func (debug debugLogger) Write(p []byte) (n int, err error) {
|
||||||
|
debug.logger.Debug(string(p))
|
||||||
|
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf logs a debug message.
|
||||||
|
func (debug debugLogger) Printf(format string, v ...interface{}) {
|
||||||
|
debug.logger.Debug(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface guards.
|
||||||
|
var (
|
||||||
|
_ io.Writer = (*debugLogger)(nil)
|
||||||
|
)
|
||||||
24
pkg/modules/chromium/debug_test.go
Normal file
24
pkg/modules/chromium/debug_test.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package chromium
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDebugLogger_Write(t *testing.T) {
|
||||||
|
actual, err := debugLogger{logger: zap.NewNop()}.Write([]byte("foo"))
|
||||||
|
expected := len([]byte("foo"))
|
||||||
|
|
||||||
|
if actual != expected {
|
||||||
|
t.Errorf("expected %d but got %d", expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected not error but got: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDebugLogger_Printf(t *testing.T) {
|
||||||
|
debugLogger{logger: zap.NewNop()}.Printf("%s", "foo")
|
||||||
|
}
|
||||||
@@ -432,6 +432,29 @@ func TestConvertMarkdownHandler(t *testing.T) {
|
|||||||
outputDir: "/tmp/foo",
|
outputDir: "/tmp/foo",
|
||||||
expectOutputPathsCount: 1,
|
expectOutputPathsCount: 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ctx: func() *api.MockContext {
|
||||||
|
ctx := &api.MockContext{Context: &api.Context{}}
|
||||||
|
|
||||||
|
ctx.SetDirPath("/tmp/foo")
|
||||||
|
ctx.SetFiles(map[string]string{
|
||||||
|
"index.html": "/tests/test/testdata/chromium/markdown/sample3/index.html",
|
||||||
|
"markdown1.md": "/tests/test/testdata/chromium/markdown/sample3/markdown.md",
|
||||||
|
})
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
}(),
|
||||||
|
api: func() API {
|
||||||
|
chromiumAPI := struct{ ProtoAPI }{}
|
||||||
|
chromiumAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ Options) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return chromiumAPI
|
||||||
|
}(),
|
||||||
|
outputDir: "/tmp/foo",
|
||||||
|
expectOutputPathsCount: 1,
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
func() {
|
func() {
|
||||||
if tc.outputDir != "" {
|
if tc.outputDir != "" {
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import (
|
|||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/chromium"
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/chromium"
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/gc"
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/gc"
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice"
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice"
|
||||||
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice/pdfengine"
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice/unoconv"
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice/unoconv"
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/logging"
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/logging"
|
||||||
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/pdfcpu"
|
||||||
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/pdfengines"
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/pdfengines"
|
||||||
|
_ "github.com/gotenberg/gotenberg/v7/pkg/modules/pdftk"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ GOTENBERG_VERSION="$2"
|
|||||||
GOTENBERG_USER_GID="$3"
|
GOTENBERG_USER_GID="$3"
|
||||||
GOTENBERG_USER_UID="$4"
|
GOTENBERG_USER_UID="$4"
|
||||||
PDFTK_VERSION="$5"
|
PDFTK_VERSION="$5"
|
||||||
DOCKER_REGISTRY="$6"
|
DOCKER_REPOSITORY="$6"
|
||||||
|
|
||||||
GOTENBERG_VERSION="${GOTENBERG_VERSION//v}"
|
GOTENBERG_VERSION="${GOTENBERG_VERSION//v}"
|
||||||
SEMVER=( ${GOTENBERG_VERSION//./ } )
|
SEMVER=( ${GOTENBERG_VERSION//./ } )
|
||||||
@@ -26,22 +26,22 @@ docker buildx build \
|
|||||||
--build-arg PDFTK_VERSION="$PDFTK_VERSION" \
|
--build-arg PDFTK_VERSION="$PDFTK_VERSION" \
|
||||||
--platform linux/amd64 \
|
--platform linux/amd64 \
|
||||||
--platform linux/arm64 \
|
--platform linux/arm64 \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:latest" \
|
-t "$DOCKER_REPOSITORY/gotenberg:latest" \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}" \
|
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}" \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}" \
|
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}" \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}" \
|
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}" \
|
||||||
--push \
|
--push \
|
||||||
-f build/Dockerfile .
|
-f build/Dockerfile .
|
||||||
|
|
||||||
# Cloud Run variant.
|
# Cloud Run variant.
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--build-arg DOCKER_REGISTRY="$DOCKER_REGISTRY" \
|
--build-arg DOCKER_REPOSITORY="$DOCKER_REPOSITORY" \
|
||||||
--build-arg GOTENBERG_VERSION="$GOTENBERG_VERSION" \
|
--build-arg GOTENBERG_VERSION="$GOTENBERG_VERSION" \
|
||||||
--platform linux/amd64 \
|
--platform linux/amd64 \
|
||||||
--platform linux/arm64 \
|
--platform linux/arm64 \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:latest-cloudrun" \
|
-t "$DOCKER_REPOSITORY/gotenberg:latest-cloudrun" \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}-cloudrun" \
|
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}-cloudrun" \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}-cloudrun" \
|
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}-cloudrun" \
|
||||||
-t "$DOCKER_REGISTRY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}-cloudrun" \
|
-t "$DOCKER_REPOSITORY/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}-cloudrun" \
|
||||||
--push \
|
--push \
|
||||||
-f build/Dockerfile.cloudrun .
|
-f build/Dockerfile.cloudrun .
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
ARG GOLANG_VERSION
|
ARG GOLANG_VERSION
|
||||||
ARG DOCKER_REGISTRY
|
ARG DOCKER_REPOSITORY
|
||||||
ARG GOTENBERG_VERSION
|
ARG GOTENBERG_VERSION
|
||||||
ARG GOLANGCI_LINT_VERSION
|
ARG GOLANGCI_LINT_VERSION
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ FROM golang:$GOLANG_VERSION-stretch as golang
|
|||||||
|
|
||||||
# We're extending the Gotenberg's Docker image because our code relies on external
|
# We're extending the Gotenberg's Docker image because our code relies on external
|
||||||
# dependencies like Google Chrome, LibreOffice, etc.
|
# dependencies like Google Chrome, LibreOffice, etc.
|
||||||
FROM $DOCKER_REGISTRY/gotenberg:$GOTENBERG_VERSION
|
FROM $DOCKER_REPOSITORY/gotenberg:$GOTENBERG_VERSION
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
|
|||||||
18
test/testdata/chromium/markdown/sample3/index.html
vendored
Normal file
18
test/testdata/chromium/markdown/sample3/index.html
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Gutenberg</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Table in markdown</h1>
|
||||||
|
|
||||||
|
<h2>toHTML</h2>
|
||||||
|
{{ toHTML "markdown.md" }}
|
||||||
|
|
||||||
|
<h2>Actual HTML</h2>
|
||||||
|
<textarea readonly="readonly" cols="100" rows="50">
|
||||||
|
{{ toHTML "markdown.md" }}
|
||||||
|
</textarea>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
test/testdata/chromium/markdown/sample3/markdown.md
vendored
Normal file
5
test/testdata/chromium/markdown/sample3/markdown.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
| Tables | Are | Cool |
|
||||||
|
|----------|:-------------:|------:|
|
||||||
|
| col 1 is | left-aligned | $1600 |
|
||||||
|
| col 2 is | centered | $12 |
|
||||||
|
| col 3 is | right-aligned | $1 |
|
||||||
Reference in New Issue
Block a user