Dockerfile не может выполнить команду CMD (Docker для Windows) - PullRequest
0 голосов
/ 09 октября 2018

Невозможно выполнить команду CMD в Docker для окон в файле 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"]

ФАЙЛЫ ПОДДЕРЖКИ:

A.Script.ps1 (используется 2 и 5)

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

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"

Обратите внимание, мне не нужно использовать «\\» из-за escape-символа.

НАБЛЮДЕНИЯ

Контейнерзапускается и исчезает через несколько секунд.

Если я удаляю часть CMD, контейнеры работают нормально.Я могу попасть в контейнер и выполнить указанную выше команду sqlcmd в cmd shell.

Что я делаю не так, что отсутствует, какой-то лучший подход и т. Д. Может ли кто-нибудь дать какое-нибудь руководство, пожалуйста?Спасибо!

Редактировать:

Судя по ответу Джоша, эта команда 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"]

1 Ответ

0 голосов
/ 09 октября 2018

Я думаю, что вы, возможно, неправильно понимаете природу CMD и ENTRYPOINT против команды RUN.И CMD, и ENTRYPOINT вступают в силу при запуске / запуске контейнера, тогда как RUN - это команда времени сборки.Несколько запутанно, вы используете RUN для подготовки образа вашего контейнера во время процесса сборки докера, тогда как CMD - это то, что запускается в контейнере.

через документацию ,

Основная цель CMD - предоставить значения по умолчанию для исполняющего контейнера ...

Любое заданное изображение контейнера будет иметь только одну инструкцию CMD.

В Dockerfile может быть только одна инструкция CMD.Если вы укажете более одного CMD, то вступит в силу только последний CMD.

Если вы хотите убедиться, что исполняемый файл запускается при запуске контейнера, вы можете подумать об использовании инструкции ENTRYPOINT;Думайте о ENTRYPOINT как о команде, которая предоставляет значения по умолчанию для инструкции CMD.Из документов:

Dockerfile должен указывать хотя бы одну из команд CMD или ENTRYPOINT.ENTRYPOINT должен быть определен при использовании контейнера в качестве исполняемого файла.CMD следует использовать как способ определения аргументов по умолчанию для команды ENTRYPOINT или для выполнения специальной команды в контейнере.CMD будет переопределен при запуске контейнера с альтернативными аргументами.

Команда RUN - это инструкция времени сборки, которую вы используете для подготовки образа контейнера с необходимыми файлами, конфигурацией и т. Д.

См. этот вопрос SO для получения дополнительной информации о ENTRYPOINT vs CMD.

ED: Рассматриваемый вами случай запуска сценария SQL в контейнере является сложным, поскольку сценарий не должен запускаться, пока механизм базы данных не будет готов к приему команд.Вы можете запустить скрипт обновления в инструкции ENTRYPOINT в качестве первого шага.Вы можете также рассмотреть возможность запуска постконтейнерной подготовки сценария обновления SQL с помощью команды docker exec.

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 сценарий для запуска, который входит в бесконечный цикл, который предотвращает немедленную остановку контейнера (контейнеры работают только до тех пор, пока выполняется выполняемый в них процесс).Это гарантирует, что ваш сценарий запуска выполняется, даже если пользователь переопределяет инструкцию CMD во время выполнения:

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

CMD .\Start.ps1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...