Merge pull request 'Finalized Patch:' (#4) from dev/fixes into main
Reviewed-on: #4
This commit is contained in:
commit
642b05a50b
Notes:
riomoo
2026-01-05 16:04:38 -05:00
Activity: Mon Jan 5 04:04:38 PM EST 2026
7 changed files with 1081 additions and 617 deletions
|
|
@ -1,32 +1,40 @@
|
||||||
# Build stage
|
# Build stage
|
||||||
FROM golang:bookworm AS builder
|
FROM golang:alpine AS builder
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
musl-dev \
|
||||||
|
gcc \
|
||||||
|
wget \
|
||||||
|
xz \
|
||||||
|
git
|
||||||
|
|
||||||
# Install UPX
|
RUN wget https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-amd64_linux.tar.xz && \
|
||||||
RUN apt-get update && apt-get install -y wget xz-utils && rm -rf /var/lib/apt/lists/*
|
tar -xf upx-5.0.2-amd64_linux.tar.xz && \
|
||||||
|
mv upx-5.0.2-amd64_linux/upx /usr/local/bin/upx && \
|
||||||
RUN wget https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-amd64_linux.tar.xz
|
rm -r upx-5.0.2-amd64_linux upx-5.0.2-amd64_linux.tar.xz
|
||||||
RUN tar -xf upx-5.0.2-amd64_linux.tar.xz && mv upx-5.0.2-amd64_linux/upx /usr/local/bin/upx && rm -r upx-5.0.2-amd64_linux upx-5.0.2-amd64_linux.tar.xz
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY go.mod ./
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN mkdir -p /var/sockets
|
# Build with CGO and increased WASM memory limits
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w -extldflags '-static' -X main.GOMEMLIMIT=256MiB -X runtime.defaultGOGC=50" -trimpath -gcflags="-l=4" -asmflags=-trimpath -o bin/main app/gopherbook/main.go
|
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build \
|
||||||
|
-a \
|
||||||
|
-ldflags="-s -w -linkmode external -extldflags '-static' -X main.GOMEMLIMIT=512MiB -X runtime.defaultGOGC=50" \
|
||||||
|
-trimpath \
|
||||||
|
-o bin/main app/gopherbook/main.go
|
||||||
RUN upx --best --ultra-brute bin/main
|
RUN upx --best --ultra-brute bin/main
|
||||||
RUN chmod +x bin/main
|
RUN chmod +x bin/main
|
||||||
|
|
||||||
# Final stage with Chainguard static
|
|
||||||
FROM cgr.dev/chainguard/static:latest
|
FROM cgr.dev/chainguard/static:latest
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy the binary
|
|
||||||
COPY --from=builder /app/bin/main ./bin/main
|
COPY --from=builder /app/bin/main ./bin/main
|
||||||
|
|
||||||
# Create directories that will be mounted and set ownership
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
USER root:root
|
USER root:root
|
||||||
CMD ["./bin/main"]
|
CMD ["./bin/main"]
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ It is designed for people who want full control over their digital comic collect
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Upload & read `.cbz` (ZIP-based) comics directly in the browser
|
- Upload & read `.cbz` (ZIP-based) comics directly in the browser
|
||||||
|
- Supports 8 Megapixel images at 512MB memory limits
|
||||||
|
- (increase in bash script for higher Megapixels or remove the limitation if you don't care)
|
||||||
- Full support for password-protected/encrypted CBZ files (AES-256 via yeka/zip)
|
- Full support for password-protected/encrypted CBZ files (AES-256 via yeka/zip)
|
||||||
- Automatically tries all previously successful passwords when opening a new encrypted comic
|
- Automatically tries all previously successful passwords when opening a new encrypted comic
|
||||||
- Persists discovered passwords securely (AES-encrypted on disk, key derived from your login password)
|
- Persists discovered passwords securely (AES-encrypted on disk, key derived from your login password)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1462,10 +1462,38 @@
|
||||||
document.getElementById('readerTitle').textContent = comic.title || comic.filename;
|
document.getElementById('readerTitle').textContent = comic.title || comic.filename;
|
||||||
document.getElementById('readerModal').classList.add('active');
|
document.getElementById('readerModal').classList.add('active');
|
||||||
|
|
||||||
|
// If encrypted and no password set, try known passwords first
|
||||||
if (comic.encrypted && !comic.has_password) {
|
if (comic.encrypted && !comic.has_password) {
|
||||||
|
showMessage('Trying known passwords...', 'success');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/try-passwords/' + encodeURIComponent(comic.id), {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
if (data.success) {
|
||||||
|
showMessage('Password found! Loading comic...', 'success');
|
||||||
|
// Reload comics to get updated data
|
||||||
|
await loadComics();
|
||||||
|
currentComic = comics.find(c => c.id === comic.id);
|
||||||
|
// Continue to open reader normally
|
||||||
|
} else {
|
||||||
|
// No known password worked, show password modal
|
||||||
await showPasswordModal(comic);
|
await showPasswordModal(comic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await showPasswordModal(comic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showMessage('Error trying passwords: ' + err.message, 'error');
|
||||||
|
await showPasswordModal(comic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const encodedId = encodeURIComponent(currentComic.id);
|
const encodedId = encodeURIComponent(currentComic.id);
|
||||||
const url = '/api/pages/' + encodedId;
|
const url = '/api/pages/' + encodedId;
|
||||||
|
|
@ -1497,7 +1525,7 @@
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showMessage('Error: ' + err.message, 'error');
|
showMessage('Error: ' + err.message, 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openReaderAtBookmark(comic, bookmarkPage) {
|
async function openReaderAtBookmark(comic, bookmarkPage) {
|
||||||
currentComic = comic;
|
currentComic = comic;
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,15 @@ if podman container exists "$CONTAINER_NAME"; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Starting new container from image: $IMAGE_NAME..."
|
echo "Starting new container from image: $IMAGE_NAME..."
|
||||||
podman run -d --name "$CONTAINER_NAME" --memory=256m --restart unless-stopped \
|
# IMPROVED: Better memory settings and limits
|
||||||
-p 12010:8080 -v ./library:/app/library -v ./cache:/app/cache -v ./etc:/app/etc "$IMAGE_NAME"
|
podman run -d --name "$CONTAINER_NAME" \
|
||||||
|
--memory=512m \
|
||||||
|
--restart unless-stopped \
|
||||||
|
-p 12010:8080 \
|
||||||
|
-v ./library:/app/library \
|
||||||
|
-v ./cache:/app/cache \
|
||||||
|
-v ./etc:/app/etc \
|
||||||
|
"$IMAGE_NAME"
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Failed to start new container. Exiting script."
|
echo "Failed to start new container. Exiting script."
|
||||||
|
|
@ -33,3 +40,6 @@ echo "Cleaning up old images..."
|
||||||
podman image prune --force
|
podman image prune --force
|
||||||
|
|
||||||
echo "Update and cleanup complete!"
|
echo "Update and cleanup complete!"
|
||||||
|
echo "Container is running with memory limit: 512MB, swap: 512MB"
|
||||||
|
echo "Go memory limit (GOMEMLIMIT): 512MiB"
|
||||||
|
echo "Aggressive GC enabled (GOGC=50)"
|
||||||
|
|
|
||||||
7
go.mod
7
go.mod
|
|
@ -6,3 +6,10 @@ require (
|
||||||
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9
|
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9
|
||||||
golang.org/x/crypto v0.43.0
|
golang.org/x/crypto v0.43.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/ebitengine/purego v0.8.3 // indirect
|
||||||
|
github.com/gen2brain/avif v0.4.4 // indirect
|
||||||
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||||
|
github.com/tetratelabs/wazero v1.9.0 // indirect
|
||||||
|
)
|
||||||
|
|
|
||||||
8
go.sum
8
go.sum
|
|
@ -1,3 +1,11 @@
|
||||||
|
github.com/ebitengine/purego v0.8.3 h1:K+0AjQp63JEZTEMZiwsI9g0+hAMNohwUOtY0RPGexmc=
|
||||||
|
github.com/ebitengine/purego v0.8.3/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||||
|
github.com/gen2brain/avif v0.4.4 h1:Ga/ss7qcWWQm2bxFpnjYjhJsNfZrWs5RsyklgFjKRSE=
|
||||||
|
github.com/gen2brain/avif v0.4.4/go.mod h1:/XCaJcjZraQwKVhpu9aEd9aLOssYOawLvhMBtmHVGqk=
|
||||||
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
|
||||||
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9 h1:K8gF0eekWPEX+57l30ixxzGhHH/qscI3JCnuhbN6V4M=
|
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9 h1:K8gF0eekWPEX+57l30ixxzGhHH/qscI3JCnuhbN6V4M=
|
||||||
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9/go.mod h1:9BnoKCcgJ/+SLhfAXj15352hTOuVmG5Gzo8xNRINfqI=
|
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9/go.mod h1:9BnoKCcgJ/+SLhfAXj15352hTOuVmG5Gzo8xNRINfqI=
|
||||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue