I'm using docker multistage build and am trying to add a live reload feature to my dockerized go application. I have an entrypoint.sh with its own configurations in the second image.
Now, the problem is that the command CMD ["air", "-c", ".air.toml"]
from the first image gets overwritten by the ENTRYPOINT ["/entrypoint.sh"]
scripts from the second image, so it is only the ENTRYPOINT
that is started and CMD
doesn't run.
I can't combine them into the only command like so
ENTRYPOINT ["/entrypoint.sh", "air", "-c", ".air.toml"]
because the second Image doesn't have Golang language installed with the respective libraries.
Is it possible somehow to run CMD
and ENTRYPOINT
side by side? Thank you.
Dockerfile
FROM golang:1.17.2
COPY . /go/src/sample
WORKDIR /go/src/sample
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go install github.com/cosmtrek/air@latest
CMD ["air", "-c", ".air.toml"]
FROM eclipse-temurin:17-focal
COPY entrypoint.sh /entrypoint.sh
RUN chmod x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
docker-compose.yml
version: '3'
services:
go:
build:
context: ./backend
dockerfile: Dockerfile
volumes:
- ./backend:/go/src/backend
working_dir: /go/src/backend
ports:
- 8080:8080
CodePudding user response:
Read the arguments passed to the entrypoint which is the CMD.
For example, below is your entrypoint script. You can access the args and do something with them, i.e. execute them.
#!/bin/bash
# dome something in your entrypoint
# execute the original command
# substituting the current process id
# so that command is run with pid 1
exec "$@"
In your docker image, make sure you have the desired command, i.e.
ENTRYPOINT ["/entryppoint.sh"]
CMD ["echo", "command"]
Apart from this technical aspect, you seem to imply that you want to run the CMD that relies on go being available without go being available. That is not possible. You need to ensure the thing you are trying to execute and its dependencies are available.
You can probably copy the air binary from the first stage. Something like this.
COPY --from=0 /go/bin/air /usr/local/bin/air
Potentially, you want to compile air
this with CGO_ENABLED=0
.
However, I would assume that you need the go compiler to be present in your image for any hot reload to work, since your app needs to be recompiled on code change. So perhaps you should not even use multi staging here.
That, said. Doing hot reload in a container seems a bit like an anti pattern. Containers are usually a mean to distribute your artifacts.