MacOS环境下构建Golang Docker镜像时如何解决/bin/sh: 1: source: not found错误?
Hey there! Let's break down what's going wrong here and fix it step by step.
First, let's diagnose the two main issues
Why the
source/.command fails (or says "file not found")
Docker uses/bin/shas the default shell forRUNcommands, and while.is the POSIX-compatible alternative to Bash'ssource, your bigger problem is timing: you're trying to load the.envfile before you've copied it into the container! Look at your Dockerfile order:RUN . .envcomes way beforeCOPY . ./, so the file doesn't exist in the container at that point.Environment variables don't persist across
RUNlayers
EachRUNcommand runs in a separate shell session. Even if you loaded.envcorrectly in oneRUN, those variables won't be available in subsequentRUNcommands unless you chain everything in a single shell session.
Solution 1: Load .env during build (if you need variables for build steps)
If you need the environment variables to run commands like go build or go mod download, adjust your Dockerfile to copy the .env first, then chain all dependent commands in one Bash session:
FROM golang:latest WORKDIR /go/src/todo_list # First, copy your .env file into the container (critical!) COPY .env ./ # Run all commands that need the env vars in a single Bash session RUN /bin/bash -c "source .env && go mod download && go mod verify" # Copy the rest of your code COPY go.mod ./ COPY go.sum ./ COPY . ./ WORKDIR /go/src/todo_list/cmd/main EXPOSE 9010 RUN go build main.go CMD ["./main", "-migrate"]
Solution 2: Load .env at runtime (recommended for most cases)
If your environment variables are only needed when the Go app runs (not during build), you don't need to touch .env in the Dockerfile at all. Instead, pass the variables when starting the container:
First, clean up your Dockerfile:
FROM golang:latest WORKDIR /go/src/todo_list COPY go.mod ./ COPY go.sum ./ RUN go mod download COPY . ./ WORKDIR /go/src/todo_list/cmd/main EXPOSE 9010 RUN go mod verify RUN go build main.go CMD ["./main", "-migrate"]
Then run your container with the --env-file flag to load your local .env:
docker run --env-file .env -p 9010:9010 your-image-name
This is better because:
- Sensitive env vars aren't baked into your image
- You can use different
.envfiles for development/production without rebuilding the image - Add
.envto your.dockerignoreto avoid accidentally copying it into the image
Bonus: If your Go app reads .env directly
If you're using a library like github.com/joho/godotenv to load .env in your code, just make sure to copy the file into the container and point your app to it:
# Add this line after COPY . ./ COPY .env ./cmd/main/
Then your app can load it normally at runtime.
内容的提问来源于stack exchange,提问作者JiwanJeon94

