How to create simple Docker container with Go utilities installed - docker

I'm kinda stuck exploring Docker features in order to create simple container with some Go utilities installed. I need to create image that has gosec and govulncheck utilities installed so I can run them on code in container. My petty attempt produced the following:
# syntax=docker/dockerfile:1
FROM golang:1.19-alpine
WORKDIR /app
ENV GO111MODULE=on
# copying my code to check
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
RUN go build -o /docker-gs-ping
RUN apk add --no-cache git
RUN go install github.com/securego/gosec/v2/cmd/gosec#latest
RUN go install golang.org/x/vuln/cmd/govulncheck#latest
EXPOSE 8080
CMD [ "gosec ./..." ]
Running the container results in error:
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "gosec ./...": stat gosec ./...: no such file or directory: unknown.
ERRO[0000] error waiting for container: context canceled
It looks like I need to specify paths to installed utilities, but I couldn't make it work

This isn't a path issue; the problem is the syntax you've used in the CMD statement in your Dockerfile. You're using the JSON-format of the CMD statement; the first argument in the JSON list is the name of the command to run. You've asked Docker to run a command named gosec ./..., which of course doesn't exist.
You need to split that into multiple list items:
CMD [ "gosec", "./..." ]
Alternatively, you can use the shell form of the CMD directive:
CMD gosec ./...
Either of those will run gosec when you start the container.

Related

How to run golang server in docker

I setup a simple server with golang:
package main
import (
"golang-server/database"
"golang-server/helper"
"log"
"net/http"
)
func main() {
database.Connect()
port := helper.GetPort()
SetupRoutes()
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
log.Fatal(http.ListenAndServe(":"+port, router))
}
Here is what my folder structure look like:
Here is what my dockerfile look like:
FROM golang:1.18
WORKDIR $GOPATH/src
COPY . .
RUN go mod download
RUN go build -o /golang-server
EXPOSE 8080
CMD ["golang-server"]
I am running these docker commands in the main directory:
docker build . -t golang-server
docker run --network=golang-server --name=golang-server golang-server
However I am getting this error when I run:
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "golang-server": executable file not found in $PATH: unknown.
What should I set the dockerfile so I can successfully deploy to docker?
The problem is related with your last line in Dockerfile CMD ["golang-server"]. When you put it there, the system (inside of the container) are trying to find an executable file inside of your $PATH variable called golang-server.
To solve this issue, you can just edit your last line from your Dockerfile to CMD ["/golang-server"], once you are building your application in / (RUN go build -o /golang-server). The final Dockerfile should be something like:
FROM golang:1.18
WORKDIR $GOPATH/src
COPY . .
RUN go mod download
RUN go build -o /golang-server
EXPOSE 8080
CMD ["/golang-server"]

Docker: How to access files from another container from a given container?

Basically I have a main directory and Books Directory (General file structure, there's more but these are the important pieces). So when I fire a request from main to booksServer, it doesn't work because the node modules are missing.
That's because the node modules are inside the docker container at a specific path: '/usr/src/app'
How can I have main.js see that books (service/container) does have the proper node packages inside this specific path?
I think I can use docker-compose, but I wanted to test it individually without docker-compose first.
**-Main Directory (Individual Service, has its own container)**
-Initiator (Fires commands)
-DockerFile
**-Books Directory (Individual Service, has its own container)**
-Stubs
-BooksStub.js (NEED THIS!, but it won't work because needs npm modules which is located in its container #/usr/src/app. How can I access the nodemodules that it's using?)
-booksServer.js
-Package*.json (lock and package.json)
-DockerFile
Inside the
Error:
internal/modules/cjs/loader.js:800
throw err;
^
Error: Cannot find module 'grpc'
Books Dockerfile
FROM node:12.14.0
WORKDIR /usr/src/app
COPY package*.json ./
COPY . /usr/src/app
RUN npm install
EXPOSE 30043
CMD ["node", "booksServer.js"]
Main DockerFile
FROM node:12.14.0
WORKDIR /usr/src/app
COPY package*.json ./
COPY . /usr/src/app
RUN npm install
EXPOSE 4555
CMD ["node", "main.js"]
You can create one common datavolume and attached your containers with the datavolume
Here is the step to create a datavolume,
Step 1 : docker volume create --name storageOne You can give any name instead of storageOne
Step 2 : Now you need to attach that volume with the container using docker run -ti --name=myContainer -v storageOne:/storageOne ubuntu command
Step 3 : Copy or create your required file in that datavolume
Step 4 : Now Create an another Container using docker run -ti --name=myContainer2 --volumes-from MyContainer ubuntu command
Step 5 : Restart your myStorage container
So whatever files are available in myStorage will be shareable between attached container.
May be this will help you

How to handle make missing from alpine docker image?

i have Makefiles on my app , and all my commands on Makefile
i put this on Dockerfile:
# start from the latest golang base image
FROM golang:alpine
RUN apk update && apk add --no-cache gcc && apk add --no-cache libc-dev
# Set the current working Directory inside the container
WORKDIR /app
# Copy go mod and sum files
COPY go.mod go.sum ./
# Download all dependencies. they will be cached of the go.mod and go.sum files are not changed
RUN go mod download
# Copy the source from the current directory to the WORKDIR inisde the container
COPY . .
# Build the Go app
RUN go build .
# Exporse port 3000 or 8000 to the outisde world
EXPOSE 3000
# Command to run the executable
CMD ["make", "-C", "scripts", "test" ]
CMD ["make", "-C", "scripts", "prod" ]
and got
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:349: starting container process caused "exec:
\"make\": executable file not found in $PATH": unknown.
is it possible to run make -c scripts test in Docker? how to correct way to use this command in Docker?
in dockerfile i run golang:alpine
if you wish to avoid adding all dependencies of make to your alpine image and keep the shipping container small in size:
build your binary outside ur container and copy only the shippable binary to ur alpine container
build your binary in a normal golang container then copy the binary to a small shippable alpine container
you could give https://github.com/go-task/task a try, does not require too many dependencies compared to installing make in ur alpine container and replace ur make file with task file.

starting container process caused "exec: \"go\": executable file not found in $PATH": unknown

I am trying to containerize and as well as start my Go lang application using Docker-compose,
The image is built successfully according to the logs but my container does not for docker-compose up and it throws the following error to my console.
Cannot start service app: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"go\": executable file not found in $PATH": unknown
Here is what my Docker file looks like.
ARG GO_VERSION=1.13
FROM golang:${GO_VERSION}-alpine AS builder
# We create an /app directory within our
# image that will hold our application source
# files
RUN mkdir /raedar
# Create the user and group files that will be used in the running container to
# run the process as an unprivileged user.
RUN mkdir /user && \
echo 'nobody:x:65534:65534:nobody:/:' > /user/passwd && \
echo 'nobody:x:65534:' > /user/group
# Install git.
# Git is required for fetching the dependencies.
# Allow Go to retrieve the dependencies for the buld
RUN apk update && apk add --no-cache ca-certificates git
RUN apk add --no-cache libc6-compat
# Force the go compiler to use modules
ENV GO111MODULE=on
ADD . /raedar/
WORKDIR /raedar/
RUN go get -d -v golang.org/x/net/html
COPY go.mod go.sum ./
COPY . .
# Compile the binary, we don't want to run the cgo
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/main cmd/app/main.go
# Final stage: the running container.
FROM scratch AS final
WORKDIR /root/
# Import the user and group files from the first stage.
COPY --from=builder /user/group /user/passwd /etc/
# Import the Certificate-Authority certificates for enabling HTTPS.
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Import the compiled executable from the first stage.
COPY --from=builder /raedar/bin/main .
EXPOSE 8080
# Perform any further action as an unprivileged user.
USER nobody:nobody
# Run the compiled binary.
CMD ["./main"]
The error shows you're trying to run go, not ./main:
exec: \"go\": executable file not found in $PATH
A matching Dockerfile would have the line CMD ["go", "./main"] rather than CMD ["./main"].
So either you're unexpectedly building a different Dockerfile, or you're changing the command when you run a container with that image. In particular, if you're using docker-compose, make sure you're not setting command: go ./main or entrypoint: go, either of which could cause this behavior.

Dockerfile cannot find copied folder

This is quite strange.
I have a structure like this
app/
CLI/
someOtherFolder/
thingIwantToRun.py
tests.Dockerfile
Dockerfile
README.md
gunicorn.conf
This is what my Dockerfile looks like
FROM python:3.6
WORKDIR /app
COPY ./requirements.txt /.requirements.txt
# Install any needed packages specified in requirements.txt
RUN pip install -r /.requirements.txt
COPY gunicorn.conf /gunicorn.conf
COPY . /app
EXPOSE 8000
RUN ls
ENV FLASK_ENV=development
CMD ["python ./someOtherFolder/thingIwantToRun.py"]
This gives me this error when I start the container -
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"ls ./someOtherFolder\": stat ls ./someOtherFolder: no such file or directory": unknown.
When I change the CMD command into something else which doesn't fail and I jump into the container I see that my folder is indeed there.
When I add a RUN ls into my Dockerfile, I can still see my folder.
If it exists, why can't I run it?
UPDATE -
If I move thingIWantToRun.py into the top level folder and change my Docker CMD to
CMD [python thingIWantToRun.py]
I see the same issue. However, I can ssh into the container and verify that the file is there.
The problem is how you are running the CMD command. It is something like this:
CMD ["executable", "param1", "param2"]
ref: https://docs.docker.com/engine/reference/builder/#cmd
In that sense actual command should be
CMD ["python", "./someOtherFolder/thingIwantToRun.py"]
Docker tries to find the executable part (first item of the array) and run it, and passes rest of the array items (param1, param2) to it. If you look closer to the error is prints
... process caused "exec: \"ls ./someOtherFolder\": stat ls ./someOtherFolder: no such file or directory"
It says that ls ./someOtherFolder is not a file or directory and it can't exec it! Which is the first item of the array, the executable!
Here ls should be first item and ./someOtherFolder should be second item of array for CMD command.
You need to use the CMD command something like this:
CMD ["python", "./someOtherFolder/thingIwantToRun.py"]

Resources