inbucket-inbucket
FAILURE
18m 48s
History Source
SummaryIterations3Transcript34Dockerfile
01Iteration 1
WRITEWriteFile· step #1
0s
Dockerfile1706 chars
text55 lines · 1706 chars
FROM --platform=linux/amd64 node:20 AS frontend
# Build the frontend (Elm/JS UI) for amd64 only to avoid arch issues
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

FROM golang:1.25-alpine3.22 AS backend
# Build the Go backend
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN make clean deps
RUN go build -o inbucket \
  -ldflags "-X 'main.version=$(git describe --tags --always)' -X 'main.date=$(date -Iseconds)'" \
  -v ./cmd/inbucket

FROM alpine:3.22
# Final runtime image
RUN apk --no-cache add tzdata wget
WORKDIR /opt/inbucket
RUN mkdir bin defaults ui
COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html defaults
COPY etc/docker/defaults/start-inbucket.sh /

ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck relies on wget
HEALTHCHECK --interval=5s --timeout=5s --retries=3 CMD /bin/sh -c 'wget localhost:$(echo ${INBUCKET_WEB_ADDR:-0.0.0.0:9000}|cut -d: -f2) -q -O - >/dev/null'

# Ports: SMTP, HTTP, POP3
EXPOSE 2500 9000 1100

# Persistent volumes for config and storage
VOLUME /config
VOLUME /storage

ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
WRITEWriteFile· step #2
1s
Dockerfile1726 bytes written
text56 lines · 1726 chars
FROM node:current-alpine3.23 AS frontend
# Build frontend (Elm/JS UI) for amd64 compatibility where possible. Use yarn via npm.
RUN npm install -g node-gyp
RUN npm install -g yarn
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

FROM golang:1.25-alpine3.22 AS backend
# Build the Go backend
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN make clean deps
RUN go build -o inbucket \
  -ldflags "-X 'main.version=$(git describe --tags --always)' -X 'main.date=$(date -Iseconds)'" \
  -v ./cmd/inbucket

FROM alpine:3.22
# Final runtime image with prerequisites
RUN apk --no-cache add tzdata wget
WORKDIR /opt/inbucket
RUN mkdir bin defaults ui
COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html defaults
COPY etc/docker/defaults/start-inbucket.sh /

ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck relies on wget
HEALTHCHECK --interval=5s --timeout=5s --retries=3 CMD /bin/sh -c 'wget localhost:$(echo ${INBUCKET_WEB_ADDR:-0.0.0.0:9000}|cut -d: -f2) -q -O - >/dev/null'

# Exposed ports
EXPOSE 2500 9000 1100

# Persisted volumes
VOLUME /config
VOLUME /storage

ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
WRITEWriteFile· step #3
0s
.dockerignore112 bytes written
dockerignore10 lines · 112 chars
# Ignore VCS and node_modules and build artifacts
.git
node_modules
vendor
ui/node_modules
.ui
*.log
.DS_Store

VERIFYVerifyBuild· step #4
25s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
02Iteration 2
WRITEWriteFile· step #1
1s
Dockerfile1759 bytes written
text59 lines · 1759 chars
# Docker build file for Inbucket: https://www.inbucket.org/

### Build frontend
# Due to architecture constraints, build frontend with a non-arm64 base.
FROM node:current-alpine3.23 AS frontend
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Build backend
FROM golang:1.25-alpine3.22 AS backend
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN make clean deps
RUN go build -o inbucket \
  -ldflags "-X 'main.version=$(git describe --tags --always)' -X 'main.date=$(date -Iseconds)'" \
  -v ./cmd/inbucket

### Run in minimal image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget
WORKDIR /opt/inbucket
RUN mkdir bin defaults ui
COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html defaults
COPY etc/docker/defaults/start-inbucket.sh /

# Configuration
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck
HEALTHCHECK --interval=5s --timeout=5s --retries=3 CMD /bin/sh -c 'wget localhost:$(echo ${INBUCKET_WEB_ADDR:-0.0.0.0:9000}|cut -d: -f2) -q -O - >/dev/null'

# Ports: SMTP, HTTP, POP3
EXPOSE 2500 9000 1100

# Persistent Volumes
VOLUME /config
VOLUME /storage

ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
WRITEWriteFile· step #2
0s
.dockerignore206 bytes written
dockerignore27 lines · 206 chars
node_modules
.ui-build
.DS_Store
.git
.gitignore
.idea
.vscode
.env
.env.local
*.log
.godata
*.zip
*.tar.gz
*.tgz
*.gz
*.bz2
*.7z
*.xz
*.bak
*.swp
*.swo
ui/dist
ui/elm-stuff
ui/node_modules
ui/.cache
build
VERIFYVerifyBuild· step #3
30s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
DOCKERDockerImageSearch· step #4
0s
search docker hubnode:20-alpine1 results
show lines1
Image node:20-alpine exists on Docker Hub.
DOCKERDockerImageSearch· step #5
1s
search docker hubgolang:1.25-alpine3.221 results
show lines1
Image golang:1.25-alpine3.22 exists on Docker Hub.
VERIFYVerifyBuild· step #6
34s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
READReadFile· step #7
0s
etc/docker/defaults/start-inbucket.sh522 chars · 25 lines
sh25 lines · 522 chars
#!/bin/sh
# start-inbucket.sh
# description: start inbucket (runs within a docker container)

INBUCKET_HOME="/opt/inbucket"
CONF_SOURCE="$INBUCKET_HOME/defaults"
CONF_TARGET="/config"

set -eo pipefail

install_default_config() {
  local file="$1"
  local source="$CONF_SOURCE/$file"
  local target="$CONF_TARGET/$file"

  if [ ! -e "$target" ]; then
    echo "Installing default $file to $CONF_TARGET"
    install "$source" "$target"
  fi
}

install_default_config "greeting.html"

exec "$INBUCKET_HOME/bin/inbucket" $* 
READReadFile· step #8
0s
etc/docker/defaults/greeting.html952 chars · 20 lines
html20 lines · 952 chars
<h1>Welcome to Inbucket</h1>

<p>Inbucket is an email testing service; it will accept email for any email
address and make it available to view without a password.</p>

<p>To view messages for a particular address, enter the username portion
of the address into the box on the upper right and click <em>View</em>.</p>

<p>This instance of Inbucket is running inside of a <a
  href="https://www.docker.com/" target="_blank">Docker</a> container.  It is
configured to retain messages for a maximum of 3 days, and will enforce a limit
of 300 messages per mailbox - the oldest messages will be deleted to stay under
that limit.</p>

<p>Messages addressed to any recipient in the <code>@bitbucket.local</code>
domain will be accepted, but immediately <b>discarded</b> without being written
to disk. Use this domain for load or soak testing your application.  Inbucket
will retain mail for any other domain by default, i.e.
<code>@inbucket.local</code>.</p>
READReadFile· step #9
24s
README.md962 chars · 24 lines
md24 lines · 962 chars
Summary (under 1500 chars):
- Inbucket: email testing service with built-in HTTP, SMTP, POP3; no external dependencies after compile.
- Docker
  - Image: inbucket/inbucket
  - Tags: latest (releases), edge (main)
  - Start: docker run -d --name inbucket -p 9000:9000 -p 2500:2500 -p 1100:1100 inbucket/inbucket
  - Open: http://localhost:9000/
- Build from source (requires Go and Node.js)
  - git clone https://github.com/inbucket/inbucket.git
  - cd inbucket/ui
  - yarn install
  - yarn build
  - cd ..
  - go build ./cmd/inbucket
- Run locally
  - ./inbucket
  - Default ports: SMTP 2500, Web 9000
- Configuration
  - Inbucket reads environment variables with sane defaults
  - See doc/config.md for details; Configurator tool recommended for generating a config
- Additional context
  - MIT License; Inbucket is written in Go and Elm
  - Latest version available on GitHub
  - Go REST client API docs: pkg.go.dev/github.com/inbucket/inbucket/pkg/rest/client
WRITEWriteFile· step #10
1s
Dockerfile1970 bytes written
text61 lines · 1970 chars
# Docker build file for Inbucket: https://www.inbucket.org/

### Build frontend
# Build frontend for amd64 due to architecture constraints for the Elm/Node frontend.
FROM node:20-alpine AS frontend

# Install build dependencies needed for node-gyp
RUN apk add --no-cache python3 make g++
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Build backend
FROM golang:1.25-alpine3.22 AS backend
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
# Build with git describe if available; fall back to a static value when .git is not present
RUN set -eux; V=$(git describe --tags --always 2>/dev/null || echo "dev"); D=$(date -Iseconds); \
  go build -o inbucket -ldflags "-X 'main.version=$V' -X 'main.date=$D'" -v ./cmd/inbucket

### Run in minimal image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget
WORKDIR /opt/inbucket
RUN mkdir bin defaults ui
COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html defaults
COPY etc/docker/defaults/start-inbucket.sh /

# Configuration
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck
HEALTHCHECK --interval=5s --timeout=5s --retries=3 CMD /bin/sh -c 'wget localhost:$(echo ${INBUCKET_WEB_ADDR:-0.0.0.0:9000}|cut -d: -f2) -q -O - >/dev/null'

# Ports: SMTP, HTTP, POP3
EXPOSE 2500 9000 1100

# Persistent Volumes
VOLUME /config
VOLUME /storage

ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
VERIFYVerifyBuild· step #11
24s
VerifyBuildrejected
Concerns: Frontend build relies on yarn but yarn is not installed in the frontend stage (RUN yarn install ...). This will fail; consider installing yarn or using npm/corepack to install yarn., The final image copies and marks /start-inbucket.sh as the entrypoint, but there is no explicit chmod +x in the Dockerfile. If the script is not executable in the source repo, the container may fail to start., Potential mismatch or uncertainty around where the HTTP UI is served (INBUCKET_WEB_UIDIR) and whether the healthcheck and smoke tests align with the actual runtime paths. Ensure the server exposes the expected UI route at port 9000.
WRITEWriteFile· step #12
1s
Dockerfile2082 bytes written
text65 lines · 2082 chars
# Docker build file for Inbucket: https://www.inbucket.org/

### Build frontend
# Build frontend for amd64 due to architecture constraints for the Elm/Node frontend.
FROM node:20-alpine AS frontend

# Install build dependencies needed for node-gyp and yarn
RUN apk add --no-cache python3 make g++ curl
RUN npm install -g yarn
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Build backend
FROM golang:1.25-alpine3.22 AS backend
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
# Build with git describe if available; fall back to a static value when .git is not present
RUN set -eux; V=$(git describe --tags --always 2>/dev/null || echo "dev"); D=$(date -Iseconds); \
  go build -o inbucket -ldflags "-X 'main.version=$V' -X 'main.date=$D'" -v ./cmd/inbucket

### Run in minimal image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget
WORKDIR /opt/inbucket
RUN mkdir bin defaults ui
COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html defaults
COPY etc/docker/defaults/start-inbucket.sh /

# Make sure startup script is executable
RUN chmod +x /start-inbucket.sh

# Configuration
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck
HEALTHCHECK --interval=5s --timeout=5s --retries=3 CMD /bin/sh -c 'wget localhost:$(echo ${INBUCKET_WEB_ADDR:-0.0.0.0:9000}|cut -d: -f2) -q -O - >/dev/null'

# Ports: SMTP, HTTP, POP3
EXPOSE 2500 9000 1100

# Persistent Volumes
VOLUME /config
VOLUME /storage

ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
VERIFYVerifyBuild· step #13
24s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
WRITEWriteFile· step #14
1s
Dockerfile2245 bytes written
text68 lines · 2245 chars
# Docker build file for Inbucket: https://www.inbucket.org/

### Build frontend
# Build frontend for amd64 due to architecture constraints for the Elm/Node frontend.
FROM node:20-alpine AS frontend

# Install build dependencies needed for node-gyp and yarn
RUN apk add --no-cache python3 make g++ curl
RUN npm install -g yarn
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Build backend
FROM golang:1.25-alpine3.22 AS backend
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
# Build with git describe if available; fall back to a static value when .git is not present
RUN set -eux; V=$(git describe --tags --always 2>/dev/null || echo "dev"); D=$(date -Iseconds); \
  go build -o inbucket -ldflags "-X 'main.version=$V' -X 'main.date=$D'" -v ./cmd/inbucket

### Run in minimal image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget
WORKDIR /opt/inbucket
RUN mkdir bin defaults ui
COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html defaults
COPY etc/docker/defaults/start-inbucket.sh /

# Make sure startup script is executable
RUN chmod +x /start-inbucket.sh

# Copy default greeting into config so runtime knows where to serve it from
RUN mkdir -p /config && cp /opt/inbucket/defaults/greeting.html /config/greeting.html

# Configuration
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck
HEALTHCHECK --interval=5s --timeout=5s --retries=3 CMD /bin/sh -c 'wget localhost:$(echo ${INBUCKET_WEB_ADDR:-0.0.0.0:9000}|cut -d: -f2) -q -O - >/dev/null'

# Ports: SMTP, HTTP, POP3
EXPOSE 2500 9000 1100

# Persistent Volumes
VOLUME /config
VOLUME /storage

ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
VERIFYVerifyBuild· step #15
32s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
03Iteration 3
WRITEWriteFile· step #1
0s
Dockerfile2069 chars
text72 lines · 2069 chars
# Multi-stage build for Inbucket

### Frontend (amd64 only)
FROM --platform=linux/amd64 node:current-alpine3.23 AS frontend
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Backend
FROM golang:1.25-alpine3.22 AS backend
ARG VERSION=unknown
ARG BUILD_DATE=unknown
ENV VERSION=${VERSION}
ENV BUILD_DATE=${BUILD_DATE}
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN go env -w GOPROXY=https://proxy.golang.org,direct
# Build with version metadata baked in (avoid git describe)
RUN go build -o inbucket -ldflags "-X 'main.version=${VERSION}' -X 'main.date=${BUILD_DATE}'" -v ./cmd/inbucket

### Runtime
FROM alpine:3.22
RUN apk --no-cache add tzdata wget

# Create non-root user for runtime
RUN adduser -D inbucket

WORKDIR /opt/inbucket

# Create required dirs and set permissions
RUN mkdir -p bin defaults ui /config /storage

COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html /config/greeting.html
COPY etc/docker/defaults/start-inbucket.sh /start-inbucket.sh

# Configuration defaults
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck
HEALTHCHECK --interval=5s --timeout=5s --start-period=5s CMD wget -qO- http://127.0.0.1:9000/health || exit 1

# Ports: SMTP, HTTP, POP3
EXPOSE 2500 9000 1100

# Persistent Volumes
VOLUME /config
VOLUME /storage

# Ensure runtime ownership
RUN chown -R inbucket:inbucket /opt/inbucket/bin /opt/inbucket/ui /config /storage

USER inbucket
ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
WRITEWriteFile· step #2
1s
Dockerfile2184 bytes written
text72 lines · 2184 chars
# Multi-stage build for Inbucket

### Frontend (amd64) build
FROM node:current-alpine3.23 AS frontend
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
# Ensure Yarn is available (via Corepack in Node images)
RUN corepack enable && corepack prepare yarn@stable --activate
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Backend
FROM golang:1.25-alpine3.22 AS backend
ARG VERSION=unknown
ARG BUILD_DATE=unknown
ENV VERSION=${VERSION}
ENV BUILD_DATE=${BUILD_DATE}
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN go env -w GOPROXY=https://proxy.golang.org,direct
# Build with version metadata baked in (avoid git describe relying on .git)
RUN make clean deps
RUN go build -o inbucket -ldflags "-X 'main.version=${VERSION}' -X 'main.date=${BUILD_DATE}'" -v ./cmd/inbucket

### Runtime image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget

# Non-root runtime user
RUN adduser -D inbucket

WORKDIR /opt/inbucket
RUN mkdir -p bin defaults ui /config /storage

COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html /config/greeting.html
COPY etc/docker/defaults/start-inbucket.sh /start-inbucket.sh

# Configuration (defaults)
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck against internal port 9000
HEALTHCHECK --interval=5s --timeout=5s --start-period=5s CMD wget -qO- http://127.0.0.1:9000/health || exit 1

# Exposed ports
EXPOSE 2500 9000 1100

# Volumes
VOLUME /config
VOLUME /storage

# Ensure runtime ownership and non-root execution
RUN chown -R inbucket:inbucket /opt/inbucket/bin /opt/inbucket/ui /config /storage
USER inbucket
ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
WRITEWriteFile· step #3
0s
.dockerignore173 bytes written
dockerignore15 lines · 173 chars
# Ignore git and node_modules and build artifacts
.git
node_modules
vendor
ui/dist
ui/node_modules
*.log
.DS_Store
**/*.swp
**/*.swo
.idea
.vscode
**/__pycache__
**/*.cache
VERIFYVerifyBuild· step #4
30s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
WRITEWriteFile· step #5
0s
Dockerfile2207 chars
text72 lines · 2207 chars
# Multi-stage build for Inbucket

### Frontend (amd64) build
FROM --platform=linux/amd64 node:current-alpine3.23 AS frontend
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
# Ensure Yarn is available (via Corepack in Node images)
RUN corepack enable && corepack prepare yarn@stable --activate
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Backend
FROM golang:1.25-alpine3.22 AS backend
ARG VERSION=unknown
ARG BUILD_DATE=unknown
ENV VERSION=${VERSION}
ENV BUILD_DATE=${BUILD_DATE}
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN go env -w GOPROXY=https://proxy.golang.org,direct
# Build with version metadata baked in (avoid git describe relying on .git)
RUN make clean deps
RUN go build -o inbucket -ldflags "-X 'main.version=${VERSION}' -X 'main.date=${BUILD_DATE}'" -v ./cmd/inbucket

### Runtime image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget

# Non-root runtime user
RUN adduser -D inbucket

WORKDIR /opt/inbucket
RUN mkdir -p bin defaults ui /config /storage

COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html /config/greeting.html
COPY etc/docker/defaults/start-inbucket.sh /start-inbucket.sh

# Configuration (defaults)
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck against internal port 9000
HEALTHCHECK --interval=5s --timeout=5s --start-period=5s CMD wget -qO- http://127.0.0.1:9000/health || exit 1

# Exposed ports
EXPOSE 2500 9000 1100

# Volumes
VOLUME /config
VOLUME /storage

# Ensure runtime ownership and non-root execution
RUN chown -R inbucket:inbucket /opt/inbucket/bin /opt/inbucket/ui /config /storage
USER inbucket
ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
WRITEWriteFile· step #6
1s
Dockerfile2184 bytes written
text72 lines · 2184 chars
# Multi-stage build for Inbucket

### Frontend (amd64) build
FROM node:current-alpine3.23 AS frontend
RUN npm install -g node-gyp
WORKDIR /build
COPY . .
WORKDIR /build/ui
RUN rm -rf .parcel-cache dist elm-stuff node_modules
# Ensure Yarn is available (via Corepack in Node images)
RUN corepack enable && corepack prepare yarn@stable --activate
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Backend
FROM golang:1.25-alpine3.22 AS backend
ARG VERSION=unknown
ARG BUILD_DATE=unknown
ENV VERSION=${VERSION}
ENV BUILD_DATE=${BUILD_DATE}
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN go env -w GOPROXY=https://proxy.golang.org,direct
# Build with version metadata baked in (avoid git describe relying on .git)
RUN make clean deps
RUN go build -o inbucket -ldflags "-X 'main.version=${VERSION}' -X 'main.date=${BUILD_DATE}'" -v ./cmd/inbucket

### Runtime image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget

# Non-root runtime user
RUN adduser -D inbucket

WORKDIR /opt/inbucket
RUN mkdir -p bin defaults ui /config /storage

COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html /config/greeting.html
COPY etc/docker/defaults/start-inbucket.sh /start-inbucket.sh

# Configuration (defaults)
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck against internal port 9000
HEALTHCHECK --interval=5s --timeout=5s --start-period=5s CMD wget -qO- http://127.0.0.1:9000/health || exit 1

# Exposed ports
EXPOSE 2500 9000 1100

# Volumes
VOLUME /config
VOLUME /storage

# Ensure runtime ownership and non-root execution
RUN chown -R inbucket:inbucket /opt/inbucket/bin /opt/inbucket/ui /config /storage
USER inbucket
ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
VERIFYVerifyBuild· step #7
17s
VerifyBuildrejected
Concerns: Dockerfile contains a non-comment line '### Frontend (amd64) build' that is not a valid Dockerfile instruction, which will cause the build to fail.
READReadFile· step #8
21s
Dockerfile1936 chars · 56 lines
text56 lines · 1936 chars
Multi-stage build plan for Inbucket:

Frontend (amd64)
- Base: node:current-alpine3.23 AS frontend
- Commands: npm install -g node-gyp
- Workdirs: /build, then /build/ui
- Cleanup: rm -rf .parcel-cache dist elm-stuff node_modules
- Yarn setup: corepack enable; corepack prepare yarn@stable --activate
- Install/build: yarn install --frozen-lockfile --non-interactive; yarn run build

Backend
- Base: golang:1.25-alpine3.22 AS backend
- Args: VERSION=unknown, BUILD_DATE=unknown
- Envs: VERSION, BUILD_DATE
- Build deps: apk add --no-cache --virtual .build-deps g++ git make
- Workdir: /build; COPY . .
- CGO: CGO_ENABLED=0
- GOPROXY: go env -w GOPROXY=https://proxy.golang.org,direct
- Build: RUN make clean deps
- Go build: go build -o inbucket -ldflags "-X 'main.version=${VERSION}' -X 'main.date=${BUILD_DATE}'" -v ./cmd/inbucket

Runtime image
- Base: alpine:3.22
- Packages: apk --no-cache add tzdata wget
- User: adduser -D inbucket
- Workdir: /opt/inbucket; mkdir -p bin defaults ui /config /storage
- Artifacts: COPY --from=backend /build/inbucket bin; COPY --from=frontend /build/ui/dist ui
- Defaults/files: COPY etc/docker/defaults/greeting.html /config/greeting.html; COPY etc/docker/defaults/start-inbucket.sh /start-inbucket.sh

Environment defaults
- INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
- INBUCKET_SMTP_TIMEOUT=30s
- INBUCKET_POP3_TIMEOUT=30s
- INBUCKET_WEB_GREETINGFILE=/config/greeting.html
- INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
- INBUCKET_WEB_UIDIR=ui
- INBUCKET_STORAGE_TYPE=file
- INBUCKET_STORAGE_PARAMS=path:/storage
- INBUCKET_STORAGE_RETENTIONPERIOD=72h
- INBUCKET_STORAGE_MAILBOXMSGCAP=300

Healthcheck
- CMD wget -qO- http://127.0.0.1:9000/health

Exposed ports
- 2500 9000 1100

Volumes
- /config
- /storage

Runtime setup
- chown -R inbucket:inbucket /opt/inbucket/bin /opt/inbucket/ui /config /storage
- USER inbucket
- ENTRYPOINT ["/start-inbucket.sh"]
- CMD ["-logjson"]
WRITEWriteFile· step #9
1s
Dockerfile2200 bytes written
text74 lines · 2200 chars
# Multi-stage build for Inbucket

# Frontend (amd64) build using Node.js 20
FROM node:20-alpine AS frontend
RUN npm install -g node-gyp
RUN apk add --no-cache python3 make g++
WORKDIR /build
COPY . .

WORKDIR /build/ui
# Clean any cached artifacts
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN corepack enable && corepack prepare yarn@stable --activate
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Backend
FROM golang:1.25-alpine3.22 AS backend
ARG VERSION=unknown
ARG BUILD_DATE=unknown
ENV VERSION=${VERSION}
ENV BUILD_DATE=${BUILD_DATE}
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN go env -w GOPROXY=https://proxy.golang.org,direct
# Build with version metadata baked in (avoid git describe relying on .git)
RUN make clean deps
RUN go build -o inbucket -ldflags "-X 'main.version=${VERSION}' -X 'main.date=${BUILD_DATE}'" -v ./cmd/inbucket

### Runtime image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget

# Non-root runtime user
RUN adduser -D inbucket

WORKDIR /opt/inbucket
RUN mkdir -p bin defaults ui /config /storage

COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html /config/greeting.html
COPY etc/docker/defaults/start-inbucket.sh /start-inbucket.sh

# Default configuration
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck against internal port 9000
HEALTHCHECK --interval=5s --timeout=5s --start-period=5s CMD wget -qO- http://127.0.0.1:9000/health || exit 1

# Exposed ports
EXPOSE 2500 9000 1100

# Volumes
VOLUME /config
VOLUME /storage

# Ensure runtime ownership and non-root execution
RUN chown -R inbucket:inbucket /opt/inbucket/bin /opt/inbucket/ui /config /storage
USER inbucket
ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
VERIFYVerifyBuild· step #10
29s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
READReadFile· step #11
0s
etc/docker/defaults/start-inbucket.sh522 chars · 25 lines
sh25 lines · 522 chars
#!/bin/sh
# start-inbucket.sh
# description: start inbucket (runs within a docker container)

INBUCKET_HOME="/opt/inbucket"
CONF_SOURCE="$INBUCKET_HOME/defaults"
CONF_TARGET="/config"

set -eo pipefail

install_default_config() {
  local file="$1"
  local source="$CONF_SOURCE/$file"
  local target="$CONF_TARGET/$file"

  if [ ! -e "$target" ]; then
    echo "Installing default $file to $CONF_TARGET"
    install "$source" "$target"
  fi
}

install_default_config "greeting.html"

exec "$INBUCKET_HOME/bin/inbucket" $* 
GREPGrepFiles· step #12
0s
/exec/in1 matches
show matches1
No matches found.
READReadFile· step #13
41s
ui/yarn.lock2177 chars · 55 lines
lock55 lines · 2177 chars
- Type: Yarn lockfile (v1)
- Purpose: lock exact resolved versions, tarball URLs, and integrity hashes for a Node project using Parcel, Elm, SWC, and related deps.

Notable package entries (selected top-level items with their versions):
- @babel/code-frame: 7.23.5
- @elm_binaries/darwin_arm64: 0.19.1-0
- @elm_binaries/darwin_x64: 0.19.1-0
- @elm_binaries/linux_x64: 0.19.1-0
- @elm_binaries/win32_x64: 0.19.1-0
- @fortawesome/fontawesome-free: 5.15.4
- @parcel/bundler-default: 2.11.0
- @parcel/cache: 2.11.0
- @parcel/diagnostic: 2.11.0
- @parcel/events: 2.11.0
- @parcel/fs: 2.11.0
- @parcel/graph: 3.1.0
- @parcel/logger: 2.11.0
- @parcel/package-manager: 2.11.0
- @parcel/plugin: 2.11.0
- @parcel/profiler: 2.11.0
- @parcel/rust: 2.11.0
- @parcel/source-map: 2.1.1
- @parcel/types: 2.11.0
- @parcel/utils: 2.11.0
- @parcel/workers: 2.11.0
- parcel: 2.11.0
- @swc/core: 1.4.0
- @swc/core-darwin-arm64: 1.4.0
- @swc/core-darwin-x64: 1.4.0
- @swc/core-linux-arm-gnueabihf: 1.4.0
- @swc/core-linux-arm64-gnu: 1.4.0
- @swc/core-linux-arm64-musl: 1.4.0
- @swc/core-linux-x64-gnu: 1.4.0
- @swc/core-linux-x64-musl: 1.4.0
- @swc/core-win32-arm64-msvc: 1.4.0
- @swc/core-win32-ia32-msvc: 1.4.0
- @swc/core-win32-x64-msvc: 1.4.0
- elm: 0.19.1-6
- elm-hot: 1.1.6
- elm-toodles/related Elm tooling entries are present (various Elm binaries)
- react-error-overlay: 6.0.9
- react-refresh: 0.9.0
- lodash: 4.17.21
- chalk: 4.1.2 and 2.4.2 (multiple entries with different ranges)
- caniuse-lite: 1.0.30001584
- json5: 2.2.3
- source-map: 0.6.1
- opensans-npm-webfont: 1.0.0
- css-select, css-tree, svgo, csso, posthtml-related packages (various versions)
- many additional transitive dependencies with their exact versions, tarball URLs, and SHA-512 integrity hashes (see lockfile for full map)

Notes:
- The file lists each package with version, resolved tarball URL, integrity hash, and its own dependencies.
- OS-specific Elm and SWC binaries are included (darwin/linux/win variants).
- No error messages present in this excerpt; it’s a straightforward dependency lockfile snapshot. If you want a full, parsed list of all packages with versions, I can generate a concise JSON or CSV.
WRITEWriteFile· step #14
1s
Dockerfile2278 bytes written
text77 lines · 2278 chars
# Multi-stage build for Inbucket

# Frontend (amd64) build using Node.js 20
FROM node:20-alpine AS frontend
RUN npm install -g node-gyp
RUN apk add --no-cache python3 make g++
WORKDIR /build
COPY . .

WORKDIR /build/ui
# Clean any cached artifacts
RUN rm -rf .parcel-cache dist elm-stuff node_modules
RUN corepack enable && corepack prepare yarn@stable --activate
RUN yarn install --frozen-lockfile --non-interactive
RUN yarn run build

### Backend
FROM golang:1.25-alpine3.22 AS backend
ARG VERSION=unknown
ARG BUILD_DATE=unknown
ENV VERSION=${VERSION}
ENV BUILD_DATE=${BUILD_DATE}
RUN apk add --no-cache --virtual .build-deps g++ git make
WORKDIR /build
COPY . .
ENV CGO_ENABLED=0
RUN go env -w GOPROXY=https://proxy.golang.org,direct
# Build with version metadata baked in (avoid git describe relying on .git)
RUN make clean deps
RUN go build -o inbucket -ldflags "-X 'main.version=${VERSION}' -X 'main.date=${BUILD_DATE}'" -v ./cmd/inbucket

### Runtime image
FROM alpine:3.22
RUN apk --no-cache add tzdata wget

# Non-root runtime user
RUN adduser -D inbucket

WORKDIR /opt/inbucket
RUN mkdir -p bin defaults ui /config /storage

COPY --from=backend /build/inbucket bin
COPY --from=frontend /build/ui/dist ui
COPY etc/docker/defaults/greeting.html /config/greeting.html
COPY etc/docker/defaults/start-inbucket.sh /start-inbucket.sh

# Ensure the startup script is executable
RUN chmod +x /start-inbucket.sh

# Configuration (defaults)
ENV INBUCKET_SMTP_DISCARDDOMAINS=bitbucket.local
ENV INBUCKET_SMTP_TIMEOUT=30s
ENV INBUCKET_POP3_TIMEOUT=30s
ENV INBUCKET_WEB_GREETINGFILE=/config/greeting.html
ENV INBUCKET_WEB_COOKIEAUTHKEY=secret-inbucket-session-cookie-key
ENV INBUCKET_WEB_UIDIR=ui
ENV INBUCKET_STORAGE_TYPE=file
ENV INBUCKET_STORAGE_PARAMS=path:/storage
ENV INBUCKET_STORAGE_RETENTIONPERIOD=72h
ENV INBUCKET_STORAGE_MAILBOXMSGCAP=300

# Healthcheck against internal port 9000
HEALTHCHECK --interval=5s --timeout=5s --start-period=5s CMD wget -qO- http://127.0.0.1:9000/health || exit 1

# Exposed ports
EXPOSE 2500 9000 1100

# Volumes
VOLUME /config
VOLUME /storage

# Ensure runtime ownership and non-root execution
RUN chown -R inbucket:inbucket /opt/inbucket/bin /opt/inbucket/ui /config /storage
USER inbucket
ENTRYPOINT ["/start-inbucket.sh"]
CMD ["-logjson"]
VERIFYVerifyBuild· step #15
27s
VerifyBuildbuild_failed
Build error
ERROR: permission denied while trying to connect to the docker API at unix:///var/run/docker.sock