关于容器:Dockerfile无法执行CMD命令(docker for windows)

Dockerfile unable to execute CMD command (docker for windows)

无法在dockerfile中的docker for windows上执行cmd命令。

但是,我想使用cmd运行两个命令,甚至不能运行一个命令。

我试过以下的方法,但没用…

1。

1
CMD"sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"

2。

1
RUN ["powershell","-NoProfile","-Command","c:\db\db_scripts\script.ps1"]

三。

1
CMD ["cmd","sqlcmd","-S","database","-i","C:\db\db_scripts\upgradescript.sql","-U","sa","-P","mypassword"]

4。

1
2
3
4
5
6
ARG arg1=database
ARG arg2=C:\db\db_scripts\upgradescript.sql
ARG arg3=sa
ARG arg4=mypassword!

RUN ["cmd","-NoProfile","-Command","sqlcmd -S $env:arg1 -i $env:arg2 -U $env:arg3 -P $env:arg4"]

5。

1
RUN powershell.exe  c:\db\db_scripts\script.ps1

6。

1
2
ENTRYPOINT ["powershell","-NoProfile","-Command","sqlcmd"]
CMD ["-S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"]

支持文件:

a.script.ps1(由2和5使用)

1
cmd /c"sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"

Doc文件

1
2
3
4
5
6
7
# escape=`

FROM microsoft/mssql-server-windows-developer
COPY db\* c:\db\
COPY db_scripts\* c:\db\db_scripts\
ENV attach_dbs="[{'dbName':'ABC','dbFiles':['C:\db\ABC.mdf','C:\db\ABC_Log.ldf']},{'dbName':'XYZ','dbFiles':['C:\db\XYZ.mdf','C:\db\XYZ_Log.ldf']}]"
CMD"sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"

请注意,由于转义符的原因,我不需要使用""。

观察

容器在几秒钟后开始并消失。

如果我移除命令部分,容器就可以正常工作。我可以进入容器,在cmdshell中运行上面的sqlcmd命令。

我做错了什么,遗漏了什么,还有更好的方法等等。有人能给我一些指导吗?谢谢!

编辑:

根据乔希的回答,这个entrypoint命令对我来说唯一有效的方法就是(分享,这样其他人就可以受益,甚至发布更好的方法来做这件事)。

1
2
3
4
5
6
ENV arg1 database
ENV arg2 C:\db\db_scripts\upgradescript.sql
ENV arg3 sa
ENV arg4 mypassword
ENTRYPOINT ["powershell sleep(60); sqlcmd"]
CMD ["-S $env:arg1 -i $env:arg2 -U $env:arg3 -P $env:arg4"]

我认为您可能误解了命令、入口点和运行指令的性质。cmd和entrypoint都在容器启动/运行时生效,而run是一个构建时命令。有些令人困惑的是,在Docker构建过程中,您使用run准备容器映像,而cmd是在容器中运行的。

通过文件,

The main purpose of a CMD is to provide defaults for an executing container...

任何给定的容器映像都只能有一条命令。

There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect.

如果要确保可执行文件在容器启动时运行,则可以考虑使用entrypoint指令;将entrypoint视为提供默认值给cmd指令的命令。来自文档:

Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
ENTRYPOINT should be defined when using the container as an executable.
CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
CMD will be overridden when running the container with alternative arguments.

run命令是一个构建时指令,用于用必要的文件、配置等准备容器映像。

有关entrypoint与cmd的更多信息,请参见本问题。

埃德:在容器中运行SQL脚本是一个棘手的问题,因为在数据库引擎准备接受命令之前,脚本不能运行。您可以作为第一步运行entrypoint指令中的升级脚本。您还可以考虑通过docker exec命令运行SQL升级脚本后容器设置。

ed2:提供的示例:

ENTRYPOINT ["powershell","-NoProfile","-Command","sqlcmd"]
CMD ["sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"]

不起作用,因为它会导致可能是无意义的命令行指令。请记住,cmd向entrypoint指令提供参数,因此您只能在entrypoint中指定powershell sqlcmd,让cmd提供参数(这是未测试的,otomh):

ENTRYPOINT powershell sqlcmd -S database -U sa -P mypassword -i

CMD C:\db\db_scripts\upgradescript.sql

ED 3:通过组合这两个语句并向入口点添加一个语句终止符(;),您可以允许运行标准的SQL容器。start.ps1脚本,该脚本将进入一个无限循环,以防止容器立即停止(容器仅在其中执行的进程运行时运行)。这样可以确保启动脚本被执行,即使用户在运行时重写了cmd指令:

ENTRYPOINT powershell"sqlcmd -S database -U sa -P mypassword -i 'C:\db\db_scripts\upgradescript.sql';"

CMD .\Start.ps1