Dockerfile 无法执行 CMD 命令(docker for windows)
Dockerfile unable to execute CMD command (docker for windows)
无法在 docker 文件中对 windows 执行 CMD 命令。docker。
我想 运行 使用 CMD 的几个命令,但是,无法 运行 甚至一个命令。
我已经尝试了以下方法,但没有任何效果...
1.
CMD "sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"
2.
RUN ["powershell", "-NoProfile", "-Command", "c:\db\db_scripts\script.ps1"]
3.
CMD ["cmd", "sqlcmd", "-S", "database", "-i", "C:\db\db_scripts\upgradescript.sql", "-U", "sa", "-P", "mypassword"]
4.
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.
RUN powershell.exe c:\db\db_scripts\script.ps1
6.
ENTRYPOINT ["powershell", "-NoProfile", "-Command", "sqlcmd"]
CMD ["-S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"]
支持文件:
一个。 Script.ps1(由 2 和 5 使用)
cmd /c "sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"
乙。 Dockerfile
# 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"
请注意,因为转义字符,我不需要使用“\\”。
观察结果
容器启动并在几秒后消失。
如果我删除 CMD 部分,容器工作正常。我可以进入容器并且可以 运行 在 cmd
shell.
中执行上述 sqlcmd
命令
我做错了什么,遗漏了什么,有什么更好的方法等等。有人能给我一些指导吗?谢谢!
编辑:
根据 Josh 的回答,这个 ENTRYPOINT 命令对我有用的唯一方法是(分享以便其他人可以受益,甚至 post 更好的方法)...
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 与 运行 指令的性质。 CMD 和 ENTRYPOINT 都在容器 startup/runtime 生效,而 运行 是构建时命令。有点令人困惑的是,您在 docker 构建过程中使用 运行 准备容器映像,而 CMD 是在容器中获取 运行 的东西。
通过 documentation、
The main purpose of a CMD is to provide defaults for an executing container...
任何给定的容器镜像都只会有一条 CMD 指令。
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.
运行 命令是一个构建时指令,您可以使用它来准备包含必要文件、配置等的容器映像。
有关 ENTRYPOINT 与 CMD 的更多信息,请参阅 this SO question。
ED:您正在查看的情况是,运行在容器中设置一个 SQL 脚本,这是一个棘手的问题,因为脚本不能 运行 在数据库引擎之前准备接受命令。作为第一步,您可以 运行 ENTRYPOINT 指令中的升级脚本。您还可以考虑通过 docker exec
命令 运行ning SQL 升级脚本 post-容器配置。
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:
通过组合这两个语句并向 ENTRYPOINT 添加语句终止符 (;
),您可以允许标准 SQL 容器 .\Start.ps1 脚本到 运行,它进入一个无限循环,阻止容器立即停止(容器 运行 只有在其中执行的进程是 运行ning 时)。这保证了你的启动脚本被执行,即使用户在 运行time:
覆盖了 CMD 指令
ENTRYPOINT powershell "sqlcmd -S database -U sa -P mypassword -i 'C:\db\db_scripts\upgradescript.sql';"
CMD .\Start.ps1
无法在 docker 文件中对 windows 执行 CMD 命令。docker。
我想 运行 使用 CMD 的几个命令,但是,无法 运行 甚至一个命令。
我已经尝试了以下方法,但没有任何效果...
1.
CMD "sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"
2.
RUN ["powershell", "-NoProfile", "-Command", "c:\db\db_scripts\script.ps1"]
3.
CMD ["cmd", "sqlcmd", "-S", "database", "-i", "C:\db\db_scripts\upgradescript.sql", "-U", "sa", "-P", "mypassword"]
4.
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.
RUN powershell.exe c:\db\db_scripts\script.ps1
6.
ENTRYPOINT ["powershell", "-NoProfile", "-Command", "sqlcmd"]
CMD ["-S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"]
支持文件:
一个。 Script.ps1(由 2 和 5 使用)
cmd /c "sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"
乙。 Dockerfile
# 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"
请注意,因为转义字符,我不需要使用“\\”。
观察结果
容器启动并在几秒后消失。
如果我删除 CMD 部分,容器工作正常。我可以进入容器并且可以 运行 在 cmd
shell.
sqlcmd
命令
我做错了什么,遗漏了什么,有什么更好的方法等等。有人能给我一些指导吗?谢谢!
编辑:
根据 Josh 的回答,这个 ENTRYPOINT 命令对我有用的唯一方法是(分享以便其他人可以受益,甚至 post 更好的方法)...
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 与 运行 指令的性质。 CMD 和 ENTRYPOINT 都在容器 startup/runtime 生效,而 运行 是构建时命令。有点令人困惑的是,您在 docker 构建过程中使用 运行 准备容器映像,而 CMD 是在容器中获取 运行 的东西。
通过 documentation、
The main purpose of a CMD is to provide defaults for an executing container...
任何给定的容器镜像都只会有一条 CMD 指令。
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.
运行 命令是一个构建时指令,您可以使用它来准备包含必要文件、配置等的容器映像。
有关 ENTRYPOINT 与 CMD 的更多信息,请参阅 this SO question。
ED:您正在查看的情况是,运行在容器中设置一个 SQL 脚本,这是一个棘手的问题,因为脚本不能 运行 在数据库引擎之前准备接受命令。作为第一步,您可以 运行 ENTRYPOINT 指令中的升级脚本。您还可以考虑通过 docker exec
命令 运行ning SQL 升级脚本 post-容器配置。
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:
通过组合这两个语句并向 ENTRYPOINT 添加语句终止符 (;
),您可以允许标准 SQL 容器 .\Start.ps1 脚本到 运行,它进入一个无限循环,阻止容器立即停止(容器 运行 只有在其中执行的进程是 运行ning 时)。这保证了你的启动脚本被执行,即使用户在 运行time:
ENTRYPOINT powershell "sqlcmd -S database -U sa -P mypassword -i 'C:\db\db_scripts\upgradescript.sql';"
CMD .\Start.ps1