diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile new file mode 100644 index 0000000..25470b0 --- /dev/null +++ b/contrib/docker/Dockerfile @@ -0,0 +1,45 @@ +# Build stage +FROM golang:1.23-bookworm AS build + +WORKDIR /src +COPY . . + +RUN go mod download +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /gosh . + +# Runtime stage +FROM gcr.io/distroless/static-debian12:latest + +# gosh needs root at startup to chroot() and setuid()/setgid() +# It drops privileges itself to the configured user/group + +# Copy the binary +COPY --from=build /gosh /gosh + +# Create passwd/group files for user.Lookup() to work +# Using UID/GID 65532 which is the "nonroot" user in distroless +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ + +# We need to add passwd and group files for gosh's user.Lookup() +# distroless has no shell, so we create these in the build stage +FROM golang:1.23-bookworm AS passwd-builder +RUN echo 'root:x:0:0:root:/root:/sbin/nologin' > /tmp/passwd && \ + echo 'gosh:x:65532:65532:gosh:/nonexistent:/sbin/nologin' >> /tmp/passwd +RUN echo 'root:x:0:' > /tmp/group && \ + echo 'gosh:x:65532:' >> /tmp/group + +# Final stage +FROM gcr.io/distroless/static-debian12:latest + +COPY --from=build /gosh /gosh +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=passwd-builder /tmp/passwd /etc/passwd +COPY --from=passwd-builder /tmp/group /etc/group + +# Create store directory (will be owned by root initially, gosh chowns it) +WORKDIR /data + +EXPOSE 8080 + +ENTRYPOINT ["/gosh"] +CMD ["-config", "/config/gosh.yml"] diff --git a/contrib/docker/config/gosh.yml b/contrib/docker/config/gosh.yml new file mode 100644 index 0000000..44a0c78 --- /dev/null +++ b/contrib/docker/config/gosh.yml @@ -0,0 +1,53 @@ +--- +# Container configuration for gosh +# +# Mount structure: +# /config/gosh.yml - this file +# /config/index.html - custom index template (optional) +# /config/favicon.ico - favicon (optional) +# /config/custom.css - custom styles (optional) +# /data/ - persistent storage + +user: "gosh" +group: "gosh" + +store: + path: "/data/store" + + id_generator: + type: "random" + length: 8 + +webserver: + listen: + protocol: "tcp" + bound: ":8080" + + protocol: "http" + + url_prefix: "" + + # Custom index.html template + custom_index: "/config/index.html" + + # Optional: static files served by gosh + # Uncomment and adjust as needed + # static_files: + # "/favicon.ico": + # path: "/config/favicon.ico" + # mime: "image/vnd.microsoft.icon" + # "/custom.css": + # path: "/config/custom.css" + # mime: "text/css" + + item_config: + max_size: "10MiB" + max_lifetime: "24h" + + mime_drop: + - "application/vnd.microsoft.portable-executable" + - "application/x-msdownload" + mime_map: + "text/html": "text/plain" + + contact: "admin@example.com" diff --git a/contrib/docker/config/index.html b/contrib/docker/config/index.html new file mode 100644 index 0000000..2ddf407 --- /dev/null +++ b/contrib/docker/config/index.html @@ -0,0 +1,146 @@ + + +
++ Upload your files to this server and share them with your friends or, if + non-existent, shady people from the Internet. +
++ Your file will expire after {{.Expires}} or earlier, if explicitly + specified. Optionally, the file can be deleted directly after the first + retrieval. For each upload, a deletion URL will also be generated which + can be used to delete the file before expiration. In addition, the + maximum file size is {{.Size}}. +
++ This is no place to share questionable or illegal data. Please use another + service or stop it completely. Get some help. +
++ The gosh software can be obtained from + https://github.com/oxzi/gosh +
+ +$ curl -F 'file=@foo.png' {{.Proto}}://{{.Hostname}}{{.Prefix}}/
+
+ Burn after reading:
+
+ $ curl -F 'file=@foo.png' -F 'burn=1' {{.Proto}}://{{.Hostname}}{{.Prefix}}/
+
+ Set a custom expiry date, e.g., one minute:
+
+ $ curl -F 'file=@foo.png' -F 'time=1m' {{.Proto}}://{{.Hostname}}{{.Prefix}}/
+
+ Or all together:
+
+ $ curl -F 'file=@foo.png' -F 'time=1m' -F 'burn=1' {{.Proto}}://{{.Hostname}}{{.Prefix}}/
+
+ Print only URL as response:
+
+ $ curl -F 'file=@foo.png' -F {{.Proto}}://{{.Hostname}}{{.Prefix}}/?onlyURL
+
+