waf*_*ers 2 containers docker dockerfile docker-container docker-for-windows
无法在 dockerfile 中的 docker for windows 上执行 CMD 命令。
我想使用 CMD 运行几个命令,但是,甚至无法运行单个命令。
我已经尝试了以下方法,但没有任何效果......
1.
CMD "sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"
Run Code Online (Sandbox Code Playgroud)
2.
RUN ["powershell", "-NoProfile", "-Command", "c:\db\db_scripts\script.ps1"]
Run Code Online (Sandbox Code Playgroud)
3.
CMD ["cmd", "sqlcmd", "-S", "database", "-i", "C:\db\db_scripts\upgradescript.sql", "-U", "sa", "-P", "mypassword"]
Run Code Online (Sandbox Code Playgroud)
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"]
Run Code Online (Sandbox Code Playgroud)
5.
RUN powershell.exe c:\db\db_scripts\script.ps1
Run Code Online (Sandbox Code Playgroud)
6.
ENTRYPOINT ["powershell", "-NoProfile", "-Command", "sqlcmd"]
CMD ["-S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"]
Run Code Online (Sandbox Code Playgroud)
支持文件:
A. Script.ps1(2 和 5 使用)
cmd /c "sqlcmd -S database -i C:\db\db_scripts\upgradescript.sql -U sa -P mypassword"
Run Code Online (Sandbox Code Playgroud)
B. 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"
Run Code Online (Sandbox Code Playgroud)
请注意,由于转义字符,我不需要使用“\\”。
观察
容器启动并在几秒钟后消失。
如果我删除 CMD 部分,容器就可以正常工作。我可以进入容器并可以sqlcmd在cmdshell中运行上述命令。
我做错了什么,缺少什么,有什么更好的方法等等。有人可以提供一些指导吗?谢谢!
编辑:
根据 Josh 的回答,这个 ENTRYPOINT 命令对我有用的唯一方法是(共享以便其他人可以受益,甚至发布更好的方法)...
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"]
Run Code Online (Sandbox Code Playgroud)
我认为您可能误解了 CMD 与 ENTRYPOINT 与 RUN 指令的性质。CMD 和 ENTRYPOINT 在容器启动/运行时生效,而 RUN 是构建时命令。有点令人困惑的是,您在 docker 构建过程中使用 RUN 来准备容器映像,而 CMD 是在容器中运行的内容。
通过文档,
CMD 的主要目的是为正在执行的容器提供默认值...
任何给定的容器镜像都只有一个 CMD 指令。
一个 Dockerfile 中只能有一个 CMD 指令。如果你列出了多个 CMD,那么只有最后一个 CMD 会生效。
如果你想确保一个可执行文件在容器启动时运行,那么你可以考虑使用 ENTRYPOINT 指令;将 ENTRYPOINT 视为为 CMD 指令提供默认值的命令。从文档:
Dockerfile 应至少指定 CMD 或 ENTRYPOINT 命令之一。将容器用作可执行文件时,应定义 ENTRYPOINT。CMD 应该用作定义 ENTRYPOINT 命令或在容器中执行 ad-hoc 命令的默认参数的一种方式。使用替代参数运行容器时,CMD 将被覆盖。
RUN 命令是一条构建时指令,用于准备容器映像以及必要的文件、配置等。
有关ENTRYPOINT 与 CMD 的更多信息,请参阅此 SO 问题。
ED:您所看到的在容器中运行 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:通过组合这两个语句并;在 ENTRYPOINT 中添加一个语句终止符 (仅在其中执行的进程正在运行时运行)。这保证了你的启动脚本被执行,即使用户在运行时覆盖了 CMD 指令:
ENTRYPOINT powershell "sqlcmd -S database -U sa -P mypassword -i 'C:\db\db_scripts\upgradescript.sql';"
CMD .\Start.ps1
| 归档时间: |
|
| 查看次数: |
3971 次 |
| 最近记录: |