-
-
Notifications
You must be signed in to change notification settings - Fork 0
[hotfix] Add/Switch (to) docker non-root user #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
f7810aa
remove comments
gocanto 684cfb6
simple names
gocanto e777627
args
gocanto 74c4731
Empty - Commit
7234159
🔐 Test GPG signing
gocanto a6c32f7
🔐 Test GPG signing (isla)
gocanto c58b181
wip
gocanto bc02785
wip
gocanto 125b72a
wip
gocanto b6051fa
wip
gocanto 7331aec
wip
gocanto d197c3e
wip
gocanto 1b64eb3
pin alpine version instead
gocanto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,112 +1,144 @@ | ||
| # --- Build Arguments | ||
| ARG GO_VERSION=1.24 | ||
| ARG ALPINE_VERSION=latest | ||
|
|
||
| ARG APP_VERSION="0.0.0-dev" | ||
| # | ||
| # ---------------------------------------------------------------------------------------------------------------------- | ||
| # GLOBAL BUILD ARGUMENTS | ||
| # ---------------------------------------------------------------------------------------------------------------------- | ||
| # | ||
| # These args can be overridden at build time with `--build-arg NAME=value`. | ||
| # Otherwise, you could use you docker-compose file to achive the same purpose. | ||
| # | ||
| # ---------------------------------------------------------------------------------------------------------------------- | ||
| # | ||
|
|
||
| ARG APP_VERSION=0.0.0.1 | ||
| ARG BUILD_TAGS="posts,experience,profile,projects,social,talks,gus,gocanto" | ||
| ARG BINARY_NAME=oullin_api | ||
|
|
||
| ARG BINARY_NAME=server | ||
| ARG APP_HOST_PORT=8080 | ||
| # Non-root user/group settings. | ||
| ARG APP_USER=appuser | ||
| ARG APP_GROUP=appgroup | ||
| ARG APP_HOME=/home/${APP_USER} | ||
|
|
||
| ARG BUILD_DIR=/app | ||
| # Container runtime port. | ||
| ARG APP_HOST_PORT=8080 | ||
|
|
||
| # Application directory inside container. | ||
| ARG APP_DIR=/app | ||
|
|
||
| # Storage directories (relative to APP_DIR). | ||
| ARG STORAGE_DIR=storage | ||
| ARG LOGS_DIR=logs | ||
| ARG MEDIA_DIR=media | ||
| ARG FIXTURES_DIR=fixture | ||
|
|
||
| # --- Build Stage | ||
| FROM golang:${GO_VERSION}-alpine AS builder | ||
| # ---------------------------------------------------------------------------------------------------------------------- | ||
| # BUILDER STAGE | ||
| # ---------------------------------------------------------------------------------------------------------------------- | ||
| FROM golang:1.24-alpine AS builder | ||
|
|
||
| # --- Docker Args always go before ENV vars. | ||
| # Forwards build-time arguments into this specific stage so they can be referenced. | ||
| ARG BUILD_DIR | ||
| # Bring in the build args needed in this stage. | ||
| ARG APP_DIR | ||
| ARG BINARY_NAME | ||
| ARG APP_VERSION | ||
| ARG BUILD_TAGS | ||
|
|
||
| # --- Go env vars. | ||
| # Tell Go to keep its module & build caches under /app | ||
| ENV GOPATH=${BUILD_DIR}/.gopath | ||
| ENV GOMODCACHE=${BUILD_DIR}/.gopath/pkg/mod | ||
| ENV GOCACHE=${BUILD_DIR}/.gocache | ||
| RUN mkdir -p ${GOMODCACHE} ${GOCACHE} | ||
| # Configure Go build cache and module cache under our APP_DIR. | ||
| ENV GOPATH=${APP_DIR}/.gopath | ||
| ENV GOMODCACHE=${APP_DIR}/.gopath/pkg/mod | ||
| ENV GOCACHE=${APP_DIR}/.gocache | ||
|
|
||
| # Install timezone data so Go’s time.* calls work correctly. | ||
| RUN #apk add --no-cache tzdata | ||
| # Create the Go module & build cache directories. | ||
| RUN mkdir -p ${GOMODCACHE} ${GOCACHE} | ||
|
|
||
| # Sets the primary working directory for this stage of the build. | ||
| WORKDIR ${BUILD_DIR} | ||
| # Set the working directory for the build. | ||
| WORKDIR ${APP_DIR} | ||
|
|
||
| # Copies the Go module definition files into the builder. | ||
| # This is done first to leverage Docker's layer caching. The subsequent | ||
| # 'go mod download' step will only be re-run if these files have changed. | ||
| # Copy Go module files and download dependencies. | ||
| COPY go.mod go.sum ./ | ||
|
|
||
| RUN go mod download | ||
|
|
||
| # Copies the rest of the application's source code into the builder. | ||
| # Copy remaining source code into the builder. | ||
| COPY . . | ||
|
|
||
| # Compiles the Go application into a single, statically-linked binary. | ||
| # -tags: Applies build constraints, allowing for conditional compilation. | ||
| # -o: Specifies the output path and name for the compiled binary. | ||
| # -ldflags: Provides flags to the linker. | ||
| # -s: Strips the symbol table, reducing binary size. | ||
| # -w: Strips DWARF debugging information, further reducing size. | ||
| # -X: Injects a value into a string variable at build time. Here, it sets | ||
| # the application's version by targeting the 'Version' variable in the 'main' package. | ||
| RUN CGO_ENABLED=0 go build -tags "${BUILD_TAGS}" -o ${BUILD_DIR}/${BINARY_NAME} -ldflags="-s -w -X main.Version=${APP_VERSION}" . | ||
|
|
||
| # --- Final Stage | ||
| FROM alpine:${ALPINE_VERSION} | ||
| #USER root | ||
|
|
||
| # Forwards build-time arguments into this final stage so they can be referenced. | ||
| # Compile a statically-linked binary. | ||
| # | ||
| # * CGO_ENABLED=0: disable CGO for static builds. | ||
| # * -tags: apply build tags. | ||
| # * -o: output binaries path/name. | ||
| # * -ldflags: strip symbols and inject version. | ||
| # | ||
| RUN CGO_ENABLED=0 go build \ | ||
| -tags "${BUILD_TAGS}" \ | ||
| -o ${APP_DIR}/${BINARY_NAME} \ | ||
| -ldflags="-s -w -X main.Version=${APP_VERSION}" \ | ||
| . | ||
|
|
||
| # ---------------------------------------------------------------------------------------------------------------------- | ||
| # FINAL STAGE | ||
| # ---------------------------------------------------------------------------------------------------------------------- | ||
| FROM alpine:3.22 | ||
|
|
||
| # Bring in the runtime args. | ||
| ARG APP_USER | ||
| ARG APP_GROUP | ||
| #ARG APP_HOME | ||
| ARG BUILD_DIR | ||
| ARG APP_HOME | ||
| ARG APP_DIR | ||
| ARG BINARY_NAME | ||
| ARG STORAGE_DIR | ||
| ARG LOGS_DIR | ||
| ARG MEDIA_DIR | ||
| ARG FIXTURES_DIR | ||
| ARG APP_HOST_PORT | ||
|
|
||
| # Creates a dedicated, non-root user and group to run the application with. | ||
| #RUN addgroup -S ${APP_GROUP} && adduser -S ${APP_USER} -G ${APP_GROUP} -h ${APP_HOME} | ||
|
|
||
| # Install timezone data so Go’s time.* functions work correctly. | ||
| RUN apk add --no-cache tzdata | ||
| ENV TZ=Asia/Singapore | ||
|
|
||
| # Make sure the home exists & switch into it. | ||
| WORKDIR /app | ||
| # Create the system group for our non-root user. | ||
| RUN addgroup -S ${APP_GROUP} | ||
|
|
||
| # Create the system user, assign to group, set its home. | ||
| RUN adduser -S ${APP_USER} \ | ||
| -G ${APP_GROUP} \ | ||
| -h ${APP_HOME} \ | ||
| ${APP_USER} | ||
|
|
||
| # Ensure the user’s home directory actually exists. | ||
| RUN mkdir -p ${APP_HOME} | ||
|
|
||
| # Switch to the application directory (implicitly creates it if missing). | ||
| WORKDIR ${APP_DIR} | ||
|
|
||
| # Creates the necessary storage directories inside the container. | ||
| RUN mkdir -p ${STORAGE_DIR}/${LOGS_DIR} ${STORAGE_DIR}/${MEDIA_DIR} | ||
| RUN mkdir -p ${STORAGE_DIR}/${FIXTURES_DIR} ${STORAGE_DIR}/${FIXTURES_DIR} | ||
| # Create storage subdirectories under the APP_DIR. | ||
| # | ||
| # * logs/: for application logs | ||
| # * media/: for uploaded/static media | ||
| # * fixture/: for static fixtures data | ||
| # | ||
| RUN mkdir -p ${STORAGE_DIR}/${LOGS_DIR} | ||
| RUN mkdir -p ${STORAGE_DIR}/${MEDIA_DIR} | ||
| RUN mkdir -p ${STORAGE_DIR}/${FIXTURES_DIR} | ||
|
|
||
| # Copies the 'fixture' files from the local project directory into the container. | ||
| COPY ${STORAGE_DIR}/${FIXTURES_DIR} ./${STORAGE_DIR}/${FIXTURES_DIR}/ | ||
| # Copy fixture files from builder stage. | ||
| COPY ${STORAGE_DIR}/${FIXTURES_DIR} ${STORAGE_DIR}/${FIXTURES_DIR}/ | ||
gocanto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Copies the compiled application binary from the 'builder' stage. | ||
| COPY --from=builder ${BUILD_DIR}/${BINARY_NAME} ${BUILD_DIR}/ | ||
| RUN chmod +x ${BUILD_DIR}/${BINARY_NAME} | ||
| # Copy the compiled binary and mark it executable. | ||
| COPY --from=builder ${APP_DIR}/${BINARY_NAME} ${APP_DIR}/ | ||
| RUN chmod +x ${APP_DIR}/${BINARY_NAME} | ||
|
|
||
| # Copy timezone data from builder so Go’s time.* calls work correctly. | ||
| #RUN apk add --no-cache tzdata | ||
| #COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo | ||
| # Give ownership of home and app directories to our non-root user. | ||
| RUN chown -R ${APP_USER}:${APP_GROUP} ${APP_HOME} | ||
| RUN chown -R ${APP_USER}:${APP_GROUP} ${APP_DIR} | ||
|
|
||
| # Recursively sets the ownership of all files in the application's home directory. | ||
| #RUN chown -R ${APP_USER}:${APP_GROUP} ${APP_HOME} | ||
| # Switch to non-root user for all subsequent container processes. | ||
| USER ${APP_USER}:${APP_GROUP} | ||
|
|
||
| #USER ${APP_USER} | ||
| # Arguments do not exist at container runtime, so ${APP_DIR} and ${BINARY_NAME} are empty when the entryoint is called. | ||
| # Therefore, we need to send those values as environment variables for the shell to pick them up at runtime. | ||
| ENV APP_DIR=${APP_DIR} | ||
| ENV BINARY_NAME=${BINARY_NAME} | ||
|
|
||
| # Expose the application port. | ||
| EXPOSE ${APP_HOST_PORT} | ||
|
|
||
| #CMD ["./server"] | ||
| #CMD ["/app/${BINARY_NAME}"] | ||
| ENTRYPOINT ["/app/server"] | ||
| # Launch the binary (shell-form so that environment variables are expanded). | ||
| ENTRYPOINT ["/bin/sh", "-c", "exec ${APP_DIR}/${BINARY_NAME}"] | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.