|
| 1 | +ARG CRYSTAL_VERSION=latest |
| 2 | + |
| 3 | +FROM placeos/crystal:$CRYSTAL_VERSION AS build |
| 4 | +WORKDIR /app |
| 5 | + |
| 6 | +# Set the commit via a build arg |
| 7 | +ARG PLACE_COMMIT="DEV" |
| 8 | +# Set the platform version via a build arg |
| 9 | +ARG PLACE_VERSION="DEV" |
| 10 | + |
| 11 | +# Create a non-privileged user, defaults are appuser:10001 |
| 12 | +ARG IMAGE_UID="10001" |
| 13 | +ENV UID=$IMAGE_UID |
| 14 | +ENV USER=appuser |
| 15 | + |
| 16 | +# See https://stackoverflow.com/a/55757473/12429735 |
| 17 | +RUN adduser \ |
| 18 | + --disabled-password \ |
| 19 | + --gecos "" \ |
| 20 | + --home "/nonexistent" \ |
| 21 | + --shell "/sbin/nologin" \ |
| 22 | + --no-create-home \ |
| 23 | + --uid "${UID}" \ |
| 24 | + "${USER}" |
| 25 | + |
| 26 | +# Install package updates since image release |
| 27 | +RUN apk update && apk --no-cache --quiet upgrade |
| 28 | + |
| 29 | +RUN update-ca-certificates |
| 30 | + |
| 31 | +# Install shards for caching |
| 32 | +COPY shard.yml shard.yml |
| 33 | +COPY shard.override.yml shard.override.yml |
| 34 | +COPY shard.lock shard.lock |
| 35 | + |
| 36 | +RUN shards install --production --ignore-crystal-version --skip-postinstall --skip-executables |
| 37 | + |
| 38 | +# Add src |
| 39 | +COPY ./src /app/src |
| 40 | + |
| 41 | +# Build application |
| 42 | +RUN UNAME_AT_COMPILE_TIME=true \ |
| 43 | + PLACE_COMMIT=$PLACE_COMMIT \ |
| 44 | + PLACE_VERSION=$PLACE_VERSION \ |
| 45 | + shards build --production --error-trace --static |
| 46 | + |
| 47 | +SHELL ["/bin/ash", "-eo", "pipefail", "-c"] |
| 48 | + |
| 49 | +# Extract binary dependencies |
| 50 | +RUN mkdir -p /app/deps && for binary in /app/bin/*; do \ |
| 51 | + { ldd "$binary" 2>/dev/null || true; } | \ |
| 52 | + tr -s '[:blank:]' '\n' | \ |
| 53 | + grep '^/' | \ |
| 54 | + xargs -I % sh -c 'mkdir -p $(dirname deps%); cp % deps%;' || true; \ |
| 55 | + done |
| 56 | + |
| 57 | +# Generate OpenAPI docs while we still have source code access |
| 58 | +RUN ./bin/placeos-auth --docs > openapi.yml |
| 59 | + |
| 60 | +RUN git config --system http.sslCAInfo /etc/ssl/certs/ca-certificates.crt |
| 61 | + |
| 62 | +# Build a minimal docker image |
| 63 | +FROM scratch |
| 64 | +WORKDIR / |
| 65 | +ENV PATH=$PATH:/ |
| 66 | + |
| 67 | +# Copy the user information over |
| 68 | +COPY --from=build etc/passwd /etc/passwd |
| 69 | +COPY --from=build /etc/group /etc/group |
| 70 | + |
| 71 | +# These are required for communicating with external services |
| 72 | +COPY --from=build /etc/hosts /etc/hosts |
| 73 | + |
| 74 | +# These provide certificate chain validation where communicating with external services over TLS |
| 75 | +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ |
| 76 | +ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt |
| 77 | + |
| 78 | +# This is required for Timezone support |
| 79 | +COPY --from=build /usr/share/zoneinfo/ /usr/share/zoneinfo/ |
| 80 | + |
| 81 | +# This is your application |
| 82 | +COPY --from=build /app/deps / |
| 83 | +COPY --from=build /app/bin / |
| 84 | + |
| 85 | +# Copy the docs into the container, you can serve this file in your app |
| 86 | +COPY --from=build /app/openapi.yml /openapi.yml |
| 87 | + |
| 88 | +# Use an unprivileged user. |
| 89 | +USER appuser:appuser |
| 90 | + |
| 91 | +# Spider-gazelle has a built in helper for health checks |
| 92 | +HEALTHCHECK CMD ["/placeos-auth", "-c", "http://127.0.0.1:8080/auth/healthz"] |
| 93 | + |
| 94 | +# Run the app binding on port 8080 |
| 95 | +EXPOSE 8080 |
| 96 | +ENTRYPOINT ["/placeos-auth"] |
| 97 | +CMD ["/placeos-auth", "-b", "0.0.0.0", "-p", "8080"] |
0 commit comments