targetcmd

This commit is contained in:
Michael McGuinness
2025-01-07 13:25:11 +00:00
parent 7e1ccd2467
commit 0172e7ac21
8 changed files with 33 additions and 104 deletions
@@ -26,13 +26,20 @@ RUN --mount=type=cache,target=/go/pkg/mod/ \
# Placing it here allows the previous steps to be cached across architectures.
ARG TARGETARCH
ARG TARGETCMD
RUN if [ -z "$TARGETCMD" ]; then \
echo "Error: TARGETCMD is not set."; \
exit 1; \
fi
# Build the application.
# Leverage a cache mount to /go/pkg/mod/ to speed up subsequent builds.
# Leverage a bind mount to the current directory to avoid having to copy the
# source code into the container.
RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,target=. \
CGO_ENABLED=0 GOARCH=$TARGETARCH go build -o /bin/server ./cmd/grpc/main.go
CGO_ENABLED=0 GOARCH=$TARGETARCH go build -o /bin/server ./cmd/$TARGETCMD/main.go
################################################################################
# Create a new stage for running the application that contains the minimal
@@ -74,8 +81,5 @@ COPY database/migrations/ database/migrations/
# Copy the executable from the "build" stage.
COPY --from=build /bin/server /bin/
# Expose the port that the application listens on.
EXPOSE 8080
# What the container should run when it is started.
ENTRYPOINT [ "/bin/server" ]
-78
View File
@@ -1,78 +0,0 @@
# syntax=docker/dockerfile:1
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/
# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7
################################################################################
# Create a stage for building the application.
ARG GO_VERSION=1.23
#FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS build
FROM golang:${GO_VERSION} AS build
WORKDIR /src
# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /go/pkg/mod/ to speed up subsequent builds.
# Leverage bind mounts to go.sum and go.mod to avoid having to copy them into
# the container.
RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,source=go.sum,target=go.sum \
--mount=type=bind,source=go.mod,target=go.mod \
go mod download -x
# This is the architecture you're building for, which is passed in by the builder.
# Placing it here allows the previous steps to be cached across architectures.
ARG TARGETARCH
# Build the application.
# Leverage a cache mount to /go/pkg/mod/ to speed up subsequent builds.
# Leverage a bind mount to the current directory to avoid having to copy the
# source code into the container.
RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,target=. \
CGO_ENABLED=0 GOARCH=$TARGETARCH go build -o /bin/server ./cmd/queue/main.go
################################################################################
# Create a new stage for running the application that contains the minimal
# runtime dependencies for the application. This often uses a different base
# image from the build stage where the necessary files are copied from the build
# stage.
#
# The example below uses the alpine image as the foundation for running the app.
# By specifying the "latest" tag, it will also use whatever happens to be the
# most recent version of that image when you build your Dockerfile. If
# reproducability is important, consider using a versioned tag
# (e.g., alpine:3.17.2) or SHA (e.g., alpine@sha256:c41ab5c992deb4fe7e5da09f67a8804a46bd0592bfdf0b1847dde0e0889d2bff).
FROM alpine:latest AS final
# Install any runtime dependencies that are needed to run your application.
# Leverage a cache mount to /var/cache/apk/ to speed up subsequent builds.
RUN --mount=type=cache,target=/var/cache/apk \
apk --update add \
ca-certificates \
tzdata \
&& \
update-ca-certificates
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser
COPY database/migrations/ database/migrations/
# Copy the executable from the "build" stage.
COPY --from=build /bin/server /bin/
# What the container should run when it is started.
ENTRYPOINT [ "/bin/server" ]
+4 -5
View File
@@ -3,14 +3,13 @@
version: '3'
vars:
DOCKERFILE_DIR: "{{.CONTEXT}}/build/package"
DOCKERFILE: "{{.CONTEXT}}/build/Dockerfile"
tasks:
lint:
cmds:
- godolint {{.DOCKERFILE_DIR}}/grpc/Dockerfile
- godolint {{.DOCKERFILE_DIR}}/queue/Dockerfile
- godolint {{.DOCKERFILE}}
build:
cmds:
- docker build -t {{.IMAGE_NAME}}_grpc -f {{.DOCKERFILE_DIR}}/grpc/Dockerfile {{.CONTEXT}}
- docker build -t {{.IMAGE_NAME}}_queue -f {{.DOCKERFILE_DIR}}/queue/Dockerfile {{.CONTEXT}}
- docker build --build-arg TARGETCMD=queryService -t {{.IMAGE_NAME}}_queryservice -f {{.DOCKERFILE}} {{.CONTEXT}}
- docker build --build-arg TARGETCMD=queryRunner -t {{.IMAGE_NAME}}_queryrunner -f {{.DOCKERFILE}} {{.CONTEXT}}
+8 -6
View File
@@ -14,8 +14,9 @@ import (
)
type apiContainerConfig struct {
DB dbConfig
Network *testcontainers.DockerNetwork
ServiceName string
DB dbConfig
Network *testcontainers.DockerNetwork
}
func createAPIContainer(t *testing.T, ctx context.Context, config *apiContainerConfig) (*grpc.ClientConn, func()) {
@@ -25,7 +26,7 @@ func createAPIContainer(t *testing.T, ctx context.Context, config *apiContainerC
}
req := testcontainers.ContainerRequest{
Image: "queryorchestration_grpc:latest",
Image: fmt.Sprintf("queryorchestration_%s:latest", config.ServiceName),
Env: map[string]string{
"DB_USER": config.DB.User,
"DB_PASS": config.DB.Password,
@@ -68,14 +69,15 @@ func createAPIContainer(t *testing.T, ctx context.Context, config *apiContainerC
}
}
func createAPIDependencies(t *testing.T, ctx context.Context) (*grpc.ClientConn, func()) {
func createAPIDependencies(t *testing.T, ctx context.Context, serviceName string) (*grpc.ClientConn, func()) {
network := createNetwork(t, ctx)
dbconfig, dbContainer := createDB(t, ctx, network)
conn, containerCleanup := createAPIContainer(t, ctx, &apiContainerConfig{
DB: *dbconfig,
Network: network,
ServiceName: serviceName,
DB: *dbconfig,
Network: network,
})
return conn, func() {
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func TestName(t *testing.T) {
ctx := context.Background()
queue, cleanup := createQueueDependencies(t, ctx)
queue, cleanup := createQueueDependencies(t, ctx, "queryrunner")
defer cleanup()
document := document.Document{
+2 -2
View File
@@ -11,7 +11,7 @@ import (
func TestQuery(t *testing.T) {
ctx := context.Background()
conn, cleanup := createAPIDependencies(t, ctx)
conn, cleanup := createAPIDependencies(t, ctx, "queryservice")
defer cleanup()
client := serviceinterfaces.NewQueryServiceClient(conn)
@@ -22,5 +22,5 @@ func TestQuery(t *testing.T) {
Id: id,
})
assert.NotNil(t, err)
assert.Nil(t, err)
}
+10 -8
View File
@@ -19,9 +19,10 @@ import (
)
type queueContainerConfig struct {
Queue queueConfig
DB *dbConfig
Network *testcontainers.DockerNetwork
ServiceName string
Queue queueConfig
DB *dbConfig
Network *testcontainers.DockerNetwork
}
func createQueueContainer(t *testing.T, ctx context.Context, config *queueContainerConfig) testcontainers.Container {
@@ -31,7 +32,7 @@ func createQueueContainer(t *testing.T, ctx context.Context, config *queueContai
}
req := testcontainers.ContainerRequest{
Image: "queryorchestration_queue:latest",
Image: fmt.Sprintf("queryorchestration_%s:latest", config.ServiceName),
Env: map[string]string{
"QUEUE_URL": config.Queue.URL,
"AWS_DEFAULT_REGION": config.Queue.Region,
@@ -193,7 +194,7 @@ func assertMessageWait(t *testing.T, ctx context.Context, queue *queue, msgType
}
}
func createQueueDependencies(t *testing.T, ctx context.Context) (*queue, func()) {
func createQueueDependencies(t *testing.T, ctx context.Context, serviceName string) (*queue, func()) {
network := createNetwork(t, ctx)
dbconfig, dbContainer := createDB(t, ctx, network)
@@ -201,9 +202,10 @@ func createQueueDependencies(t *testing.T, ctx context.Context) (*queue, func())
queue := createQueue(t, ctx, network)
container := createQueueContainer(t, ctx, &queueContainerConfig{
Queue: *queue.Config,
DB: dbconfig,
Network: network,
ServiceName: serviceName,
Queue: *queue.Config,
DB: dbconfig,
Network: network,
})
return queue, func() {