Merged Patch: (#3)

- AVIF fixed
- Removed code
- Severe changes were needed

Reviewed-on: #3
Co-authored-by: riomoo <alister@kamikishi.net>
Co-committed-by: riomoo <alister@kamikishi.net>
This commit is contained in:
riomoo 2026-01-03 09:40:17 -05:00 committed by moobot
parent bab3b6c8f7
commit 6d61266e94
Signed by: moobot
GPG key ID: 1F58B1369E1C199C
7 changed files with 1081 additions and 617 deletions

View file

@ -1,32 +1,40 @@
# 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 apt-get update && apt-get install -y wget xz-utils && rm -rf /var/lib/apt/lists/*
RUN wget https://github.com/upx/upx/releases/download/v5.0.2/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
RUN wget https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-amd64_linux.tar.xz && \
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
COPY go.mod ./
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN mkdir -p /var/sockets
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
# Build with CGO and increased WASM memory limits
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 chmod +x bin/main
# Final stage with Chainguard static
FROM cgr.dev/chainguard/static:latest
WORKDIR /app
# Copy the binary
COPY --from=builder /app/bin/main ./bin/main
# Create directories that will be mounted and set ownership
EXPOSE 8080
USER root:root
CMD ["./bin/main"]

View file

@ -10,6 +10,8 @@ It is designed for people who want full control over their digital comic collect
## Features
- 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)
- 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)

File diff suppressed because it is too large Load diff

View file

@ -1456,49 +1456,77 @@
}
async function openReader(comic) {
currentComic = comic;
currentPage = 0;
currentComic = comic;
currentPage = 0;
document.getElementById('readerTitle').textContent = comic.title || comic.filename;
document.getElementById('readerModal').classList.add('active');
document.getElementById('readerTitle').textContent = comic.title || comic.filename;
document.getElementById('readerModal').classList.add('active');
if (comic.encrypted && !comic.has_password) {
await showPasswordModal(comic);
return;
}
const encodedId = encodeURIComponent(currentComic.id);
const url = '/api/pages/' + encodedId;
// If encrypted and no password set, try known passwords first
if (comic.encrypted && !comic.has_password) {
showMessage('Trying known passwords...', 'success');
try {
const res = await fetch(url);
const res = await fetch('/api/try-passwords/' + encodeURIComponent(comic.id), {
method: 'POST'
});
if (res.ok) {
const data = await res.json();
if (data.needs_password) {
alert('Password required but not set. Please re-open the comic.');
closeReader();
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);
return;
}
totalPages = data.page_count;
document.getElementById('totalPages').textContent = totalPages;
document.getElementById('pageInput').max = totalPages;
if (totalPages > 0) {
loadPage(0);
updateBookmarkUI();
} else {
showMessage('No pages found in comic', 'error');
}
} else {
const error = await res.text();
showMessage('Error loading comic: ' + error, 'error');
await showPasswordModal(comic);
return;
}
} catch (err) {
showMessage('Error: ' + err.message, 'error');
showMessage('Error trying passwords: ' + err.message, 'error');
await showPasswordModal(comic);
return;
}
}
const encodedId = encodeURIComponent(currentComic.id);
const url = '/api/pages/' + encodedId;
try {
const res = await fetch(url);
if (res.ok) {
const data = await res.json();
if (data.needs_password) {
alert('Password required but not set. Please re-open the comic.');
closeReader();
return;
}
totalPages = data.page_count;
document.getElementById('totalPages').textContent = totalPages;
document.getElementById('pageInput').max = totalPages;
if (totalPages > 0) {
loadPage(0);
updateBookmarkUI();
} else {
showMessage('No pages found in comic', 'error');
}
} else {
const error = await res.text();
showMessage('Error loading comic: ' + error, 'error');
}
} catch (err) {
showMessage('Error: ' + err.message, 'error');
}
}
async function openReaderAtBookmark(comic, bookmarkPage) {
currentComic = comic;
currentPage = bookmarkPage || 0;

View file

@ -21,8 +21,15 @@ if podman container exists "$CONTAINER_NAME"; then
fi
echo "Starting new container from image: $IMAGE_NAME..."
podman run -d --name "$CONTAINER_NAME" --memory=256m --restart unless-stopped \
-p 12010:8080 -v ./library:/app/library -v ./cache:/app/cache -v ./etc:/app/etc "$IMAGE_NAME"
# IMPROVED: Better memory settings and limits
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
echo "Failed to start new container. Exiting script."
@ -33,3 +40,6 @@ echo "Cleaning up old images..."
podman image prune --force
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
View file

@ -6,3 +6,10 @@ require (
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9
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
View file

@ -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/go.mod h1:9BnoKCcgJ/+SLhfAXj15352hTOuVmG5Gzo8xNRINfqI=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=