Recently I've been investing some time to dive from Docker on Linux with bash (usually using "eux" options) into Windows container with Powershell to gain the same experience in Windows.
However, I have a lot of trouble getting there. Let's begin with the troubling Dockerfile (which will likely be the base for most Windows containers using PowerShell):
FROM mcr.microsoft.com/windows/servercore:20H2-amd64
SHELL ["powershell.exe", "-NoLogo", "-NoProfile"]
# Set ExecutionPolicy = Bypass permanently
RUN Invoke-Command -ErrorAction Stop -ScriptBlock { `
Get-ExecutionPolicy -List ; `
Set-ExecutionPolicy -ExecutionPolicy Bypass ; `
Get-ExecutionPolicy -List `
}
# Install chocolatey
RUN Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
# Enable global confirmation and install general build tools
RUN Invoke-Command -ErrorAction Stop -ScriptBlock { `
$ErrorActionPreference='Stop' ; `
choco feature enable -n=allowGlobalConfirmation ; `
choco install --no-progress --no-color -y cmake --installargs 'ADD_CMAKE_TO_PATH=System' ; `
choco install --no-progress --no-color -y mingw ; `
choco install --no-progress --no-color -y make `
}
What I personally miss the most is the possibility to chain multiple commands, so I can avoid the creation of superfluous image layers and container restarts.
However, if one of the commands fails, the command won't stop even that I told Invoke-Command to stop on errors and within the script block I set the ErrorActionPreference variable.
Hope the main problem here is not mainly linked to the missing knowledge in PowerShell, but how PowerShell works in Windows containers.
Thanks!
Related
I want to change the shell to bash.exefrom git-for-windows:
I have the docker file:
FROM mcr.microsoft.com/windows/servercore:1809
# $ProgressPreference: https://github.com/PowerShell/PowerShell/issues/2138#issuecomment-251261324
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
RUN iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
RUN choco install -y git
RUN & 'C:/Program Files/Git/bin/sh.exe' -c "ls -al" #### << Passes
SHELL ["\"C:\\Program Files\\Git\\bash.exe\"", "-c"] #### << Passes
RUN ls -al #### << Crashes
Results in the third statement:
/usr/bin/bash: Files/Git/bin/sh.exe: No such file or directory
When I try to quote like the following
SHELL ["\"C:\\Program Files\\Git\\bash.exe\"", "-c"]
RUN ls -al
the build works, but I dont see any output from ls -al and I dont know if it really works?
How can I use bash.exe successfully? I am using docker for windows through WSL2 engine.
I ran into a similar issue using base image mcr.microsoft.com/windows:2004.
I am not very familiar with windows command prompt or powershell.
After you install git with chocolatey, update the system PATH environment variable. I used cmd for this because it was the first way I found on stack overflow and it has worked.
I have not tested the run command with a path containing a space so the below command might not work out of the box for you.
SHELL ["cmd", "/S", "/C"]
RUN setx path "C:\\Program Files\\Git\\bin;%path%"
With the system path environment variable updated, bash.exe is available at the command line.
SHELL ["bash.exe", "-c"]
RUN "ls -la"
ENTRYPOINT ["bash.exe"]
I am trying to update the path inside my container. I have been everywhere and checked out several threads on this and nothing works. So, that's the trick?
# escape=`
ARG SDK_VERSION=4.8
FROM mcr.microsoft.com/dotnet/framework/sdk:${SDK_VERSION}
ENV NODE_VERSION=8.11.2
HEALTHCHECK NONE
RUN Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object
System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
USER ContainerAdministrator
RUN setx /M PATH "%PATH%;C:/Foo/bin"
USER ContainerUser
SHELL ["cmd", "/S", "/C"]
CMD ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
This is the error:
PS C:\users\cbongiorno\source> docker build -t mercury:latest -m 4GB -f Dockerfile i18n-tools
Sending build context to Docker daemon 2.057MB
Step 1/10 : ARG SDK_VERSION=4.8
Step 2/10 : FROM mcr.microsoft.com/dotnet/framework/sdk:${SDK_VERSION}
---> 4a9d58026a2d
Step 7/10 : RUN setx /M PATH "%PATH%;C:/Foo/bin"
---> Running in 1caf9e758af2
SUCCESS: Specified value was saved.
C:/Foo/bin : The term 'C:/Foo/bin' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At line:1 char:96
+ ... ogressPreference = 'SilentlyContinue'; setx /M PATH %PATH%;C:/Foo/bin
+ ~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:/Foo/bin:String) [], ParentCo
ntainsErrorRecordException
+ FullyQualifiedErrorId : CommandNotFoundException
The command 'powershell -Command $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; setx /M PATH "%PATH%;C:/Foo/bin"' returned a non-zero code: 1
There are at least two ways to update the PATH:
Using setx as the earlier answer suggests and as is displayed in the golang's nanoserver-1809/Dockerfile. Notice the use of the USER instruction. The ContainerAdministrator must be used in order to set the system PATH:
# PATH isn't actually set in the Docker image, so we have to set it from within the container
USER ContainerAdministrator
RUN setx /m PATH "%GOPATH%\bin;C:\go\bin;%PATH%"
USER ContainerUser
# doing this first to share cache across versions more aggressively
Using Powershell as displayed in the golang's windowsservercore-ltsc2016/Dockerfile
RUN $newPath = ('{0}\bin;C:\go\bin;{1}' -f $env:GOPATH, $env:PATH); \
Write-Host ('Updating PATH: {0}' -f $newPath); \
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine);
# doing this first to share cache across versions more aggressively
Both ways do work with recent Docker Desktop.
The ENV instruction is not going to work on Windows.
This is what I got working, but it doesn't seem ideal:
RUN setx /M PATH $($Env:PATH + ';C:\Foo\bin')
I am running on Windows 2019 server.
I am getting an error whenever I invoke powershell from a dockerfile on docker build
Error is..
---> Running in 6efa29aa8a4a
The command 'powershell -Command DIR' returned a non-zero code: 3221226505
Dockerfile..
# escape=` (backtick)
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN DIR
RUN ["powershell", "-Command", "DIR"]
COPY ./ app/
WORKDIR app
CMD [ "someapp", "somearg" ]
I have tried replacing cmd with powershell via
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
RUN DIR
and the results are the same.
Thanks
Try running a dockerfile more like
FROM mcr.microsoft.com/windows/servercore/iis
RUN powershell -NoProfile -Command Remove-Item -Recurse
C:\inetpub\wwwroot*
WORKDIR /inetpub/wwwroot
COPY . /inetpub/wwwroot
maybe you gotta move your COPY command after the WORKDIR ?
Try different things out
Check to make sure you have update KB4532691 installed on your build machine (and host). The newest image of ltsc2019 (20/2020) has issues without it.
See https://hub.docker.com/_/microsoft-windows-servercore and https://support.microsoft.com/en-us/help/4542617/you-might-encounter-issues-when-using-windows-server-containers-with-t for more info
Previously our application ran on .net framework and we used powershell to install our certificate into the certificate store by running the following command:
RUN powershell -NoProfile -Command \
$Secure_String_Pwd = ConvertTo-SecureString "ourverysecretpassword" -AsPlainText -Force ; \
Import-PfxCertificate -FilePath /cert.pfx -CertStoreLocation Cert:\LocalMachine\Root -Exportable -Password $Secure_String_Pwd
but now we have transferred our code to .netcore, the above command wont work in the dockerfile anymore.
Any idea on how to install an existing .pfx certificate via the dockerfile into the docker container?
[EDIT]
Im trying to run my container on windows, here is the complete dockerfile, maybe its just that i use the wrong image:
This is the entire docker file:
FROM microsoft/dotnet
COPY ./Web /app/
COPY cert.pfx /cert.pfx
RUN powershell -NoProfile -Command \
$Secure_String_Pwd = ConvertTo-SecureString "againourverysecretpassword" -
AsPlainText -Force ; \
Import-PfxCertificate -FilePath /cert.pfx -CertStoreLocation
Cert:\LocalMachine\Root -Exportable -Password $Secure_String_Pwd
WORKDIR /app
EXPOSE 5000
ENTRYPOINT ["dotnet", "myhost.dll"]
Anyhow it fails on the run powershell command, saying:
'powershell' is not recognized as an internal or external command,
operable program or batch file.
Is your Docker container running on Linux?
I assume that it is. Then your base image should be microsoft/aspnetcore, which is based on Ubuntu.
You should add this in your DOCKERFILE:
COPY ca_bundle.crt /usr/local/share/ca-certificates/your_ca.crt
RUN update-ca-certificates
First line copies your CA bundle into the image, the second line updates the CA list.
The CA bundle (the list of authorities that signed your certificate) can be extracted from PFX, just Google for it. This is the first link I found.
If your container is running on Windows, then Powershell command should work as-is (I'm not sure about that)
Closed. This question is not about programming or software development. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 6 months ago.
The community reviewed whether to reopen this question 6 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I installed Chocolatey as per the instructions on the website (https://chocolatey.org/install).
The 'choco' command works fine when I run it normally on cmd but returns the following error when run as administrator:
C:\WINDOWS\system32>choco install -y wget 7zip.commandline
'choco' is not recognized as an internal or external command,
operable program or batch file.
The install choco install -y wget 7zip.commandline fails if not run as administrator.
How do I fix 'not recognized' error in admin cmd?
First, ensure that you are using an administrative shell of command prompt(https://www.howtogeek.com/194041/how-to-open-the-command-prompt-as-administrator-in-windows-8.1/).
Copy the below text into the command prompt.
#"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
Then press enter key from the keyboard. After few seconds you get complete info about current installation.
If you don't see any errors. Type choco or choco -? now.
Reference
The choco environment variable has been altered. I ran into a similar problem when I tried setting env variable for Java SDK, but I was quick to recognize it when I ran the commands presented to me in the documentation which completely overwrites my env Path variable.
If you are sure you've choco installed. Check your System variables and look for Path variable if it has some values like C:\ProgramData\chocolatey\choco.exe;C:\ProgramData\chocolatey\bin if not add it.
And you can save you time by installing it. Installing via cmd line
Powershell:
Copy and Paste the code below to your PowerShell
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
OR Window CMD.exe:
#"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
After installation: run choco you see the version of chocolatey installed. Mine
Chocolatey v0.10.14
Please run 'choco -?' or 'choco <command> -?' for help menu.
hopefully this help read more
First Open the Command prompt as administrator and then run -
#powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
And then restart the Command prompt, now choco is successfully installed
Open command prompt in administrator mode and run this command:
#"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command " [System.Net.ServicePointManager]::SecurityProtocol = 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
Just correcting what #Krishnarjun Banoth has given in the answer:
powershell -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"
You don't have to add the PATH variable because choco will automatically add itself to PATH.
Changing the Path entry from 'C:\ProgramData\chocolatey\bin' to 'C:\ProgramData\chocolatey' and rebooting Windows did the trick for me.
Run Powershell as administrator
Run Get-ExecutionPolicy. If it returns Restricted, then run Set-ExecutionPolicy AllSigned or Set-ExecutionPolicy Bypass -Scope Process.
Now run the following command:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
I was able to get the installation to work using C:\ProgramData\chocolatey\bin\choco.exe install -y wget 7zip.commandline. I'm still wondering why the choco command isn't working when cmd is run as administrator. I would appreciate any help. Cheers!
Hi for installing choco on your windows system, follow these steps:
First open cmd as admistrator.
copy this command in the cmd (as administrator):
#"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe"
-NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object
System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"
&& SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
This will download the required dependency for choco and install it in your windows system.
For cross check run the choco command, for ex:
choco install -y nodejs.install python2 jdk8
To install chocolatey yarn:
First of all
Download the installer
This will give you a .msi file that when run will walk you through installing Yarn on Windows.
If you use the installer you will first need to install Node.js.
https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable
And, then go for choco install
Powershell:
Copy and Paste the code below to your PowerShell
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
OR Window CMD.exe:
#"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
After installation: run choco you see the version of chocolatey installed.
choco -v
After that just do one more thing
in PowerShell or cmd just copy-paste the following command to install chocolatey yarn in your system
choco install yarn
Here your yarn has been installed, check your yarn version using the following command.
yarn -v
That's it!! :)
This will definitely work :)