docker run的命令行参数将添加到exec形式的ENTRYPOINT的所有元素之后,并覆盖使用CMD指定的所有元素。这允许我们将参数传递给入口(entry point),即docker run -d将-d参数传递给入口(entry point)。我们可以使用docker run --entrypoint覆盖ENTRYPOINT指令。
Demon1:
main.go:
package main
import (
"flag"
"fmt"
)
type Usage struct {
Name string
Age string
Address string
Sex string
}
const (
name = `
The name flag is used to set a new name.
The default value is TonyYang.
`
age = `
The age flag is used to set a new age.
The default value is 31.
`
address = `
The address flag is used to set a new address.
The default value is ChangZhou.
`
sex = `
The sex flag is used to set a new sex.
The default value is TonyYang.
`
)
var usage = Usage{
Name: name,
Age: age,
Address: address,
Sex: sex,
}
func main() {
var (
fName = flag.String("name", "TonyYang", usage.Name)
fAge = flag.String("age", "31", usage.Age)
fAddress = flag.String("address", "ChangZhou", usage.Address)
fSex = flag.String("sex", "male", usage.Sex)
)
flag.Parse()
infos := map[string]*string{
"name": fName,
"age": fAge,
"address": fAddress,
"sex": fSex,
}
for k, v := range infos {
fmt.Printf("The %s is %s\n", k, *v)
}
}
Dockerfile:
FROM golang:1.16 AS go
WORKDIR /my_executable/
COPY . .
RUN go build main.go && rm main.go
FROM alpine:latest
WORKDIR /tmp/executable/
COPY --from=go /my_executable/main .
ENTRYPOINT ["./main"]
CMD ["--name=Mae", "--age=30", "--address=ShangHai", "--sex=female"]
上面定义了一个测试ENTRYPOINT的Dockerfile,通过go语言编写。
$ docker run camelgem/entrypoint_demo:v1
默认不为run指定运行的参数,输出结果如下所示:
The name is Mae
The age is 30
The address is ShangHai
The sex is female
输出的结果符合我们CMD中设置的参数默认值。
$ docker run camelgem/entrypoint_demo:v1 --name="camelgem"
The address is ChangZhou
The sex is male
The name is CamelGem
The age is 31
#!/usr/bin/env bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too
# USE the trap if you need to also do manual cleanup after the service is stopped,
# or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM
# start service in background here
/usr/sbin/apachectl start
echo "[hit enter key to exit] or run 'docker stop <container>'"
read
# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stop
echo "exited $0"
如果我们通过docker run -it --rm -p 80:80 --name test apache,我们可以通过docker exec或docker top来查看容器的进程,然后让脚本停止Apache进程。
$ docker exec -it test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 4448 692 ? Ss+ 00:42 0:00 /bin/sh /run.sh 123 cmd cmd2
root 19 0.0 0.2 71304 4440 ? Ss 00:42 0:00 /usr/sbin/apache2 -k start
www-data 20 0.2 0.2 360468 6004 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
www-data 21 0.2 0.2 360468 6000 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
root 81 0.0 0.1 15572 2140 ? R+ 00:44 0:00 ps aux
$ docker top test
PID USER COMMAND
10035 root {run.sh} /bin/sh /run.sh 123 cmd cmd2
10054 root /usr/sbin/apache2 -k start
10055 33 /usr/sbin/apache2 -k start
10056 33 /usr/sbin/apache2 -k start
$ /usr/bin/time docker stop test
test
real 0m 0.27s
user 0m 0.03s
sys 0m 0.03s