i'am trying to running my Go Apps in Docker container, but it fail and give error exit code 1. The application works well in my local machine but not in Docker.
Below is my Dockerfile.
FROM golang:1.8 as goimage
RUN go get -u github.com/golang/dep/cmd/dep
COPY . src/github.com/aditmayapada/tryout
WORKDIR src/github.com/aditmayapada/tryout
ENV PORT 9090
RUN dep ensure
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/main
FROM alpine:3.6 as baseimagealp
RUN apk add --no-cache bash
ENV WORK_DIR=/docker/bin
WORKDIR $WORK_DIR
# RUN mkdir src/github.com/aditmayapada/tryout/bin
# WORKDIR src/github.com/aditmayapada/tryout/bin
COPY --from=goimage /go/src/github.com/aditmayapada/tryout/bin ./
ENTRYPOINT /docker/bin/main
EXPOSE 9090
And below is my apps repository that i want to deploy in Docker
https://github.com/aditmayapada/tryout
I have tried to get logs using docker events, and i only get this
Logs
Then i tried to use --logs in docker but its not showing anything.
Am i missing something here? because my apps run well in my local machine... Thank you.
I have briefly looked at your code and found that app could be finished in a case when connection.Ping() return err
https://github.com/aditmayapada/tryout/blob/master/main.go#L44
I recommend adding some logging in this space to identify a point of exit. It seems something is wrong with connection to DB in docker.
Related
I've been trying to figure this out in the last hours but I'm stuck.
I have a very simple Dockerfile which looks like this:
FROM alpine:3.6
COPY gempbotgo /
COPY configs /configs
CMD ["/gempbotgo"]
EXPOSE 8025
gempbotgo is just an go binary which runs a webserver and some other stuff.
The webserver is running on 8025 and should answer with an hello world.
My issue is with exposing ports. I ran my container like this (after building it)
docker run --rm -it -p 8025:8025 asd
Everything seems fine but when I try to open 127.0.0.1:8025 in the browser or try a wget i just get an empty response.
Chrome: ERR_EMPTY_RESPONSE
The port is used and not restricted by the firewall on my Windows 10 system.
Running the go binary without container just on my "Bash on Ubuntu on Windows" terminal and then browsing to 127.0.0.1:8025 works without a hitch.
Other addresses returned a "ERR_CONNECTION_REFUSED" like 127.0.0.1:8030 so there definetly is something active on the port.
I then went into the conatiner with
docker exec -it e1cc6daae4cf /bin/sh
and checked in there with a wget what happens. Also there no issues. index.html file gets downloaded with a "Hello World"
Any ideas why docker is not sending any data? I've also ran my container with docker-compose but no difference there.
I also ran the container on my VPS hosted externally. Same issue there... (Debian)
My code: (note the Makefile)
https://github.com/gempir/gempbotgo/tree/docker
Edit:
After getting some comments I changed my Dockerfile to a multi-stage build. This is my Dockerfile now:
FROM golang:latest
WORKDIR /go/src/github.com/gempir/gempbotgo
RUN go get github.com/gempir/go-twitch-irc \
&& go get github.com/stretchr/testify/assert \
&& go get github.com/labstack/echo \
&& go get github.com/op/go-logging
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY configs ./configs
COPY --from=0 /go/src/github.com/gempir/gempbotgo/app .
CMD ["./app"]
EXPOSE 8025
Sadly this did not change anything, I kept everything as close as possbile to the guide here: https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
I have also tried the minimalist Dockerfile from golang.org which looks like this:
FROM golang:onbuild
EXPOSE 8025
But no success either with that.
Your issue is that you are binding to the 127.0.0.1:8025 inside your code. This makes the code work from inside the container but not outside.
You need to bind to 0.0.0.0:8025 to bind to all interfaces inside the container. So traffic coming from outside of the container is also accepted by your Go app
Adding to the accepted answer: I had the same error message trying to run docker/getting-started.
The problem was that "getting-started" is using port 80 and this was
"occupied" (netsh http show urlacl) on my machine.
I had to use docker run -d -p 8888:80 docker/getting-started where
8888 was an unused port. And then open "http://localhost:8888/tutorial/".
I have the same problem using Dockerize GatsbyJS. As Tarun Lalwani's comment above, I resolved the problem by binding or using 0.0.0.0 as hostname
yarn develop -P 0.0.0.0 -p 8000
For me this was a problem with the docker swarm mode ingress network. I had to recreate it. https://docs.docker.com/network/overlay/#customize-the-default-ingress-network
Another possibility why you are getting that error is that the docker run command is run through a normal cmd prompt and not the admin command prompt. Make sure you run as an admin!
I'm a bit new to docker and it's the first time I'm trying to add healthcheck.
The docker application I'm using is the example from here:
https://docs.docker.com/get-started/02_our_app/
I simply followed the steps to get a container with a service that runs locally on port 3000. I browsed to http://localhost:3000 and it does work.
The Dockerfile before any changes I've made:
# syntax=docker/dockerfile:1
FROM node:12-alpine
RUN apk add --no-cache python g++ make
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
And the original command to run the docker:
docker run -dp 3000:3000 getting-started
Then, I tried to add a healthcheck in a few ways.
First way: I changed the Dockerfile as follows, then re-build and re-ran:
# syntax=docker/dockerfile:1
FROM node:12-alpine
HEALTHCHECK --interval=3s --timeout=1s CMD curl --fail http://localhost:3000 || exit 1
RUN apk add --no-cache python g++ make
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
Second way: I changed the run command as follows:
docker run -dp 3000:3000 --health-cmd "curl --fail http://localhost:3000 || exit 1" getting-started
In both cases, I checked the health status using docker ps, and after it ended the "health: starting" phase, it always entered the "unhealthy" phase. Never "healthy".
In both cases, I made sure that http://localhost:3000 works and returns HTTP status 200.
While experimenting in all sorts of ways, I tried to remove the || exit 1 part but it did not help. I tried to replace it with || exit 0, and then indeed it displayed "healthy", but that doesn't really mean anything.
Does anyone have any idea what am I doing wrong? I need to do something more complex with healthcheck, but for starters I want to succeed in making it work for a simple thing.
More details:
I'm using Windows 10 Enterprise Version 20H2, Docker version 20.10.7, build f0df350. I'm running the commands from Git Bash.
Straight to the point. I've been trying to move some microservices inside docker containers. For simplicity, suppose you have two microservices on the same machine, call it A and B. Both microservices use gRPC. The microservice A wants to call a procedure inside B. B is inside a docker container and it is on the same machine where A is running but not in a container. When A calls a procedure, I get rpcerror: code = Unavailable desc = connection closed.
I've launched B with:
docker run -it -p 51001:51001 B
This is the Dockerfile
FROM golang as builder
WORKDIR /go/src/b
RUN \
git clone bla bla bla bla /go/src/b \
&& GOOS=linux GOARCH=amd64 \
go get && CGO_ENABLED=0 go build -a -ldflags '-extldflags "-static"' -o main .
FROM alpine:latest
RUN apk --no-cache add ca-certificates && apk add --update bash
WORKDIR /root/
COPY --from=builder /go/src/b/main .
COPY --from=builder /go/src/b/.env .
EXPOSE 51001
CMD ["./main"]
I've checked the ports and everything looks fine, both inside the container and on the host machine.
My host machine ships MacOS.
When launched without containers, everything works fine. So it has something to do with docker, grpc with docker, some network stuff, or it may be even 42... dunno. Someone?
If you need some other info, just ask.
I ran into this as well, for me I could fix it using
docker run -it --network host [...]
this is of course not an actual fix, just that docker network controller is throwing connections.
Maybe a fix is to update your docker installation.
Ran into a similar issue. Not sure how you set up your gRPC server, but changing the listener's address from localhost:51001 to :51001 fixed it for me.
Better explained here.
I'm trying to run a Go app using Docker on Google Cloud Run but I'm getting this error:
Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.
I fixed my port to be 8080 as stated in the docs but I think my Dockerfile is incorrect. Does anyone know what I'm missing?
FROM golang:1.12-alpine
RUN apk upgrade -U \
&& apk add \
ca-certificates \
git \
libva-intel-driver \
make \
&& rm -rf /var/cache/*
ENV GOOS linux
ENV GOARCH amd64
ENV CGO_ENABLED=0
ENV GOFLAGS "-ldflags=-w -ldflags=-s"
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
RUN echo $PATH
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
RUN go get -u github.com/cespare/reflex
# RUN reflex -h
# Setup modules after reflex install
ENV GO111MODULE=on \
GOFLAGS="$GOFLAGS -mod=vendor"
WORKDIR /go/src/bitbucket.org/team/app/
COPY . .
CMD [ "go", "run", "cmd/main.go" ]
Dockerfiles don't make your application listen on a specific port number.
The EXPOSE directive in Dockerfile is purely a documentation and doesn't do anything functional.
You have 2 options for a Go app:
Just refactor your code to read the PORT env variable: os.Getenv("PORT") and use it on the HTTP server address you’re starting:
port := os.Getenv("PORT")
http.ListenAndServe(":"+port)
Create a -port flag and read it during the entrypoint of your app in the Dockerfile:
e.g. if you can make go run main.go -port=8080 work, change your dockerfile to:
exec go run main.go -port=$PORT
These will get you what you want.
Ideally you should not use go run inside a container. Just do:
RUN go build -o /bin/my-app ./my/pkg
ENTRYPOINT /bin/my-app
to compile a Go program and use it directly. Otherwise, every time Cloud Run starts your container, you would be re-compiling it from scratch, which is not fast, this will increase your cold start times.
Aside from these you seem to have a lot of inconsistencies in your dockerfile. You set a lot of Go env vars like GOOS GOARCH but you don't actually go build your app (go run is an on-the-fly compilation and doesn't take the linker flags in GOFLAGS into account I believe). Look at sample Go dockerfiles to have a better idea on how to write idiomatic Go dockerfiles.
It seems that you are missing the EXPOSE in your Dockerfile. See https://docs.docker.com/engine/reference/builder/#expose
I have a web app that uses go language as it's back end. When I run my website I just do go build; ./projectName then it will run on local server port 8000. How do I run this web app on a container? I can run sample images like nginx on a container, but how do I create my own images for my projects. I created a Dockerfile inside my project folder with the following codes:
FROM nginx:latest
WORKDIR static/html/
COPY . /usr/src/app
Then made an image using the Dockerfile, but when I run it on a container and go to localhost:myPort/static/html/page.html it says 404 page not found. My other question is, does docker can only run static pages on a container? cause my site can receive and send data. Thanks
this is my docker file (./todo is my project name and folder name)
this is my terminal ( as you can see the the container exits emmediately)
I guess you are not exposing the Docker Port outside the container.
That's why you are not able to see any output rather than just being specific to GO Program.
Try adding the below lines to your docker compose File
EXPOSE 80(whichever port you want it to be)
EXPOSE 443
EXPOSE 3306
This will make the container be accessed from outside
Here is what i did for my GOlang web app use Gin-gonic framework -
my Dockerfile:
FROM golang:latest
# Author
MAINTAINER dangminhtruong
# Create working folder
RUN mkdir /app
COPY . /app
RUN apt -y update && apt -y install git
RUN go get github.com/go-sql-driver/mysql
RUN go get github.com/gosimple/slug
RUN go get github.com/gin-gonic/gin
RUN go get gopkg.in/russross/blackfriday.v2
RUN go get github.com/gin-gonic/contrib/sessions
WORKDIR /app
Then build docker image
docker build -t web-app:latest .
Finally, start my web-app
docker run -it -p 80:8080 -d web-app:latest go run main.go //My webapp start at 8080 port
Hope this helpfull
You don't need Nginx to run a server in Go
It's better to build a binary in Dockerfile
Here is how your Dockerfile may look like:
FROM golang:latest
RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN go build -o main .
EXPOSE 8000
CMD ["/app/main"]