Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM golang:1.23.4-alpine AS builder

WORKDIR /app

COPY go.mod go.sum ./

RUN go mod download && go mod verify

COPY . .

RUN go build -o transat-backend main.go

EXPOSE 3000

ENV PORT=3000

ENTRYPOINT [ "./transat-backend" ]
Comment on lines +1 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reduce image size via multi-stage build

Right now, the final image still contains the Go toolchain and build artifacts. Introduce a second runtime stage that copies only the compiled binary into a minimal base image (e.g., Alpine or scratch). This will dramatically shrink image size and attack surface.

Add this after line 11 in your Dockerfile:

# Stage 2: production image
FROM alpine:3.18 AS runtime
WORKDIR /app
COPY --from=builder /app/transat-backend ./
EXPOSE 3000
ENV PORT=3000
ENTRYPOINT ["./transat-backend"]
🤖 Prompt for AI Agents
In Dockerfile lines 1 to 17, the current image includes the full Go toolchain
and build artifacts, making it unnecessarily large. To fix this, implement a
multi-stage build by keeping the existing builder stage as is, then add a second
stage starting after line 11 using a minimal base image like alpine:3.18. In
this runtime stage, set the working directory, copy only the compiled binary
from the builder stage, expose port 3000, set the PORT environment variable, and
define the entrypoint to run the binary. This will significantly reduce the
final image size and improve security.

24 changes: 23 additions & 1 deletion compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,32 @@ services:
POSTGRES_USER: ${DB_USER} # Variable du fichier .env
POSTGRES_PASSWORD: ${DB_PASS} # Variable du fichier .env
ports:
- "5432:5432" # Mappe le port 5432 du conteneur au port 5432 de l'hôte
- "${DB_PORT}:5432" # Mappe le port 5432 du conteneur au port 5432 de l'hôte
volumes:
- postgres_data:/var/lib/postgresql/data # Persiste les données de la base de données

transat-backend:
build:
context: .
dockerfile: Dockerfile
command: go run main.go
Copy link

@coderabbitai coderabbitai bot May 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Leverage the compiled binary instead of go run

Overriding the Dockerfile’s ENTRYPOINT with go run main.go requires a Go toolchain at runtime and bypasses the built artifact. Prefer using the compiled binary:

-  command: go run main.go
+  command: ["./transat-backend"]
🤖 Prompt for AI Agents
In compose.yml at line 19, replace the command 'go run main.go' with the
execution of the compiled binary produced by the Dockerfile build process. This
avoids requiring the Go toolchain at runtime and ensures the container runs the
built artifact as intended. Adjust the command to invoke the binary directly,
typically by specifying its path relative to the container's working directory.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use go run main.go because I want the code to be compiled again at each code modification, with the watch. Is it correct?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@luclu7 You are absolutely correct! For your development setup with Docker Compose watch, using go run main.go is the right approach.

Here's why your setup works perfectly for development:

  1. Hot reload with recompilation: When you modify code, the sync+restart action syncs the files to /app and restarts the container
  2. Fresh compilation: On restart, go run main.go compiles the updated source code and runs it immediately
  3. Go toolchain available: Since you're using golang:1.23.4-alpine as your base image, the Go compiler is available at runtime

Your current setup gives you the hot reload development experience you want. The compiled binary approach I initially suggested would be more appropriate for production deployments where:

  • You want faster startup times
  • You don't need the Go toolchain at runtime
  • Code changes aren't expected

For production, you could consider a multi-stage Dockerfile that builds the binary and copies it to a minimal runtime image, but for development, your approach is spot on!

ports:
- "${PORT}:3000"
depends_on:
- db
environment:
- DB_HOST=db
develop:
watch:
- path: .
action: sync+restart
target: /app
ignore:
- .env
- .git
- .gitignore
- .idea

volumes:
postgres_data:
driver: local