How to pass .env file to docker image in a Go project? - docker

My Go project heriarchy is this:
The main function:
func main() {
path, _ := os.Getwd()
err := godotenv.Load(filepath.Join(path, ".env"))
if err != nil {
log.Fatal("Error loading .env file")
}
server.Init()
}
Here is my docker file content:
FROM golang:alpine AS build-env
LABEL MAINTAINER "Amit Pal <amit.pal#fynchmobility.com>"
ENV GOPATH /go
WORKDIR /go/src
COPY . /go/src/gothamcity
RUN cd /go/src/gothamcity && go build .
FROM alpine
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk*
WORKDIR /app
COPY --from=build-env /go/src/gothamcity/gothamcity /app
EXPOSE 8080
ENTRYPOINT [ "./gothamcity" ]
I ran the following command to build and run the docker image:
docker build -t gcr.io/${PROJECT_ID}/gothamcity:v1.0 .
docker run -ti gcr.io/miles-ee458/gothamcity:v1.0
I got the error:
2021/01/28 14:34:46 Error loading .env file
What am I doing wrong here? How can I pass the .env file to docker image and execute it?
Also, isn't COPY . /go/src/gothamcity copy the entire project to docker image?

COPY . /go/src/gothamcity only copies .env to build container. You have to explicitly copy it to your main container like this:
FROM golang:alpine AS build-env
LABEL MAINTAINER "Amit Pal <amit.pal#fynchmobility.com>"
ENV GOPATH /go
WORKDIR /go/src
COPY . /go/src/gothamcity
RUN cd /go/src/gothamcity && go build .
FROM alpine
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk*
WORKDIR /app
COPY --from=build-env /go/src/gothamcity/gothamcity /app
COPY .env /app
EXPOSE 8080
ENTRYPOINT [ "./gothamcity" ]
Reason is that when you are saying "FROM alpine" this becomes a brand new blank container. That's how multi-stage builds are working.

Related

docker buildx not copying files when in production

I am having an issue where the docker buildx tool doesn't properly copy files to the production container. For example:
FROM --platform=$BUILDPLATFORM node:16.14.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY yarn.lock ./
RUN apk update && apk add python3 g++ make && rm -rf /var/cache/apk/*
RUN yarn install
COPY . ./
RUN yarn run build
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html/
COPY ./nginx/nginx.conf /etc/nginx/conf.d/default.conf
# Default port exposure
EXPOSE 80
# Copy .env file and shell script to container
COPY ./env.sh /usr/share/nginx/html/env.sh
# Start Nginx server
CMD ["/bin/sh", "-c", "/usr/share/nginx/html/env.sh && nginx -g \"daemon off;\""]
All of the files from build will copy properly. However, the nginx.conf and env.sh will report as not found. Any ideas?
P.S: This seems to be an issue with nginx:alpine. No clue

Unable to use Arg values in commands in dockerfile

I am trying to allow passing build args to a dockerfile during build process but I cannot figure out how to get it to work.
This is my dockerfile
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
RUN apt-get update && apt-get install openssh-server -y \
&& echo "root:Docker!" | chpasswd
COPY sshd_config /etc/ssh/
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 2222
ARG node_build=production
ENV node_build_env=$node_build
ARG net_build=Release
ENV net_build_env=$net_build
FROM node:12.18.3 AS node-build
RUN echo $build_command_env
WORKDIR /root
COPY ["MyProject/package.json", "."]
COPY ["MyProject/package-lock.json", "."]
RUN npm i --ignore-scripts
COPY ["MyProject/angular.json", "."]
COPY ["MyProject/tsconfig.json", "."]
COPY ["MyProject/tslint.json", "."]
COPY ["MyProject/src", "./src"]
RUN npx ng build -c $node_build_env
FROM microsoft/dotnet:2.2-sdk AS build
RUN echo $net_build_env
WORKDIR /src
COPY ["MyProject/MyProject.csproj", "MyProject/"]
COPY ["MyProject.ServiceModel/MyProject.ServiceModel.csproj", "MyProject.ServiceModel/"]
COPY ["MyProject.ServiceInterface/MyProject.ServiceInterface.csproj", "MyProject.ServiceInterface/"]
COPY ["NuGet.config", "NuGet.config"]
RUN dotnet restore "MyProject/MyProject.csproj"
COPY . .
WORKDIR "/src/MyProject"
RUN dotnet build "MyProject.csproj" -c $net_build_env -o /app
FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c $net_build_env -o /app
FROM base AS final
WORKDIR /app
COPY --chown=www-data:www-data --from=publish /app .
COPY --chown=www-data:www-data --from=node-build /root/wwwroot ./wwwroot
ENTRYPOINT service ssh start && dotnet MyProject.dll
I have tried many different ways. I tried just using ARG and declaring after every FROM but that didn't work. This version I try copying ARG to ENV but that also didn't work.
How do I do this?
Issue was that variable had to be in double quote:
RUN dotnet build "MyProject.csproj" -c "$net_build_env" -o /app
You have to add --build-arg <arg>=<value> in your docker build command in order to use ARG arguments in your containerfile.
There's no need for ENV if you're only going to use the args in container build process

Why am I getting 404 with Go in docker

This is my Dockerfile
FROM golang:alpine AS build
RUN apk --no-cache add gcc g++ make git
WORKDIR /go/src/app
COPY . .
RUN go get ./...
RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/web-app ./main.go
FROM alpine:3.9
RUN apk --no-cache add ca-certificates
WORKDIR /usr/bin
COPY --from=build /go/src/app/bin /go/bin
EXPOSE 80
ENTRYPOINT /go/bin/web-app --port 80
And this is a simple main.go:
package main
import (
"fmt"
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("./public")))
log.Fatal(http.ListenAndServe(":80", nil))
}
The public directory is in the same folder with the main.go file. There is an index.html in the public directory.
When I run go run main.go my website is served properly. But with Docker, I get the 404 page. I suspect it has to do with the placement of the files inside the docker container. Any help is appreciated.
I think you need to create the folder in your alpine container:
RUN mkdir -p /go/bin/public
and make sure to have something in that folder.
or you need to copy the folder and files from the first go container.
and edit your dokcerfile :
WORKDIR /go/bin
ENTRYPOINT web-app --port 80
As LinPy has mentioned you should copy the public folder from build to alpine
And you have to set the WORKDIR to /go in order for the relative path to work
eg.
FROM golang:alpine AS build
RUN apk --no-cache add gcc g++ make git
WORKDIR /go/src/app
COPY . .
RUN go get ./...
RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/web-app ./main.go
FROM alpine:3.9
RUN apk --no-cache add ca-certificates
WORKDIR /go
COPY --from=build /go/src/app/bin /go/bin
COPY --from=build /go/src/app/public /go/public
EXPOSE 80
ENTRYPOINT /go/bin/web-app --port 80

Trouble copying a config file in a multi-stage build with a wild card

I have the following Dockerfile:
FROM golang:alpine AS build
ARG stage
RUN apk update && apk upgrade && \
apk add --no-cache bash git openssh build-base
ADD . /src
WORKDIR /src
RUN go get -u golang.org/x/vgo
RUN vgo mod init && vgo mod vendor && vgo build -o service
FROM alpine
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
WORKDIR /app
COPY --from=build /src/${stage}-env.yml /app/
COPY --from=build /src/service /app/
RUN ls -la
ENTRYPOINT ./service
I'm passing in the stage argument in my docker-compose file, such as:
build:
context: ./run-query
args:
stage: latest
But I'm not getting the correct output, the ${stage} variable is blank.
Ref https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
FROM instructions support variables that are declared by any ARG
instructions that occur before the first FROM.
An ARG declared before a FROM is outside of a build stage, so it can’t
be used in any instruction after a FROM. To use the default value of
an ARG declared before the first FROM use an ARG instruction without a
value inside of a build stage
You need to declare ARG stage again in the second stage
FROM alpine
ARG stage

Docker for golang application

i've golang application which I want to build docker image for it
the application folder called cloud-native-go and the dockerfile is under the root project
Any idea what is wrong here ?
FROM golang:alpine3.7
WORKDIR /go/src/app
COPY . .
RUN apk add --no-cache git
RUN go-wrapper download # "go get -d -v ./..."
RUN go-wrapper install # "go install -v ./..."
#final stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /go/bin/app /app
ENTRYPOINT ./app
LABEL Name=cloud-native-go Version=0.0.1
EXPOSE 3000
The error is :
Step 5/12 : RUN go-wrapper download # "go get -d -v ./..."
---> Running in 70c2e00f332d
/bin/sh: go-wrapper: not found
i Build it with
docker build -t cloud-native-go:1.0.0 .
go-wrapper has been deprecated and removed from the images using go version 10 and above. See here.
If you are fine using go v1.9 you can use the following image: golang:1.9.6-alpine3.7.
So your Dockerfile will be:
FROM golang:1.9.6-alpine3.7
WORKDIR /go/src/app
COPY . .
RUN apk add --no-cache git
RUN go-wrapper download # "go get -d -v ./..."
RUN go-wrapper install # "go install -v ./..."
#final stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /go/bin/app /app
ENTRYPOINT ./app
LABEL Name=cloud-native-go Version=0.0.1
EXPOSE 3000
FROM golang:alpine
# important!
ENV GO111MODULE=on
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
ENV GOFLAGS=-mod=vendor
ENV APP_USER app
ENV APP_HOME /go/src/microservices
RUN mkdir /nameApp
ADD . /nameApp
WORKDIR /nameApp
//compile your project
RUN go mod vendor
RUN go build
//open the port 8000
EXPOSE 8000
CMD [ "/nameApp/nameApp" ]

Resources