How can I run `powershell` command on mcr.microsoft.com/powershell container - docker

My docker image is from mcr.microsoft.com/powershell:latest which has powershell installed. Why do I get this error when build docker image: /bin/sh: 1: Install-Module: not found
Below is my dockerfile:
FROM mcr.microsoft.com/powershell:latest
RUN Install-Module dbatools -Force
I can run the command Install-Module dbatools -Force when I manually launch a container from mcr.microsoft.com/powershell:latest. Why can't I run it from building the image? Does it have a different context? If it uses my localhost context, does it mean I need to install powershell on my Mac OS?
If I want to run a powershell script as ENTRYPOINT, how can I specify it?

you can use SHELL directive in Dockerfile:
escape=`
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
see more here

Related

Starting Powershell Script on Container Startup in Azure App Service

I'm trying to use Azure App Service Containers to host Azure DevOps Pipeline agents. I've got everything working in the sense that my agent runs great locally using Docker Desktop, but when I publish the image to the App Service, the startup command is never executed. I'm forced to get a console in the container and manually run the powershell script, which then works as expected.
Here is my docker file:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell Install-PackageProvider -Name NuGet -Force
RUN powershell Install-Module PowershellGet -Force
RUN powershell Install-Module -Name Az -Repository PSGallery -Force
RUN powershell Install-Module -Name Az.Tools.Migration -Repository PSGallery -Force
RUN powershell Enable-AzureRMAlias
WORKDIR /azp
COPY start.ps1 .
CMD powershell "c:\azp\start.ps1"
The deployment center logs show no errors. It's as if the CMD is never run.
please replace powershell CMD line as below -
CMD ["powershell.exe", "-File", "c:\azp\start.ps1"]
also its always good to use the full path for the exe if its not exist in PATH.
also use workdir as below -
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell Install-PackageProvider -Name NuGet -Force
RUN powershell Install-Module PowershellGet -Force
RUN powershell Install-Module -Name Az -Repository PSGallery -Force
RUN powershell Install-Module -Name Az.Tools.Migration -Repository PSGallery -Force
RUN powershell Enable-AzureRMAlias
WORKDIR c:\azp
COPY start.ps1 .
CMD ["powershell.exe", "-File", "c:\azp\start.ps1"]
I did not try building your docker image, but you should investigated on how ENTRYPOINT is defined, and so how it interacts with CMD.
Look at the Official Guide.
According to docker documentation, if you want a command to be always executed you must pass it in ENTRYPOINT and not in CMD.
When you pass your command in CMD, it can be overridden by an argument when the container is executed.
CMD will be overridden when running the container with alternative arguments.
So I don't know how you run your container but I advise you to try to pass your script in ENTRYPOINT.
Something like that:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell Install-PackageProvider -Name NuGet -Force
RUN powershell Install-Module PowershellGet -Force
RUN powershell Install-Module -Name Az -Repository PSGallery -Force
RUN powershell Install-Module -Name Az.Tools.Migration -Repository PSGallery -Force
RUN powershell Enable-AzureRMAlias
WORKDIR c:\azp
COPY start.ps1 .
ENTRYPOINT ["powershell.exe", "c:\\azp\\start.ps1"]

I am a newbie to docker. How can we find which .net framework is installed in a docker image?

I have copied .NET framework from my local directory and build an image by using the below Dockerfile
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019
ADD setup C:\setup
RUN cmd.exe /c start /wait C:\setup\NDP471DevPack.exe /q
RUN powershell -Command rm C:\setup -r -Force
WORKDIR C:\\Project
ENTRYPOINT ["C:\\Program Files (x86)\\MSBuild\\14.0\\Bin\\msbuild.exe"]
Now I want verify that the .NET framework is whether installed or not in the image that was build?
You can run dotnet --version to see if there's a .NET runtime installed and which version it is. Something like this
docker run --rm --entrypoint=dotnet <image name> --version
You should be able to use:
reg query "HKLM\SOFTWARE\Microsoft\Net Framework Setup\NDP" /s
In Visual Studio I can select my container and click "Open Terminal Window" and paste the above command.

Docker JBoss SVN automation script? RPM v. YUM?

As it stands, my Dockerfile works as written below, but currently I have to run the two commented lines in order to pull, compile, and deploy my application to the server. I tried creating a shell script to run those commands using ADD and ENTRYPOINT, but when I run (using the docker commands below) the shell script runs and then the container exits.
What/How do I modify (I'm assuming, the docker run command) to fix this?
Is there an easier way to import libraries than the multiple URLS for RPM? I tried using YUM, but I wasn't sure how to set up my repo for installing anything.
Dockerfile
FROM registry.access.redhat.com/jboss-eap-7/eap71-openshift
USER root
RUN rpm -i [the URLS of the 40 libraries I need for SVN]
ADD subversion_installer_1.14.1.sh /home/svn_installer.sh
RUN yes | /home/svn_installer.sh
USER jboss
ARG REPO_USER
ARG REPO_PW
ARG REPO_URL
ENV REPO_USER=$REPO_USER
ENV REPO_PW=$REPO_PW
ENV REPO_URL=$REPO_URL
#RUN svn export --username="$REPO_USER" --password="$REPO_PW" "$REPO_URL" /usr/svn/myapp
#RUN /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/bin/jar -cvf $JBOSS_HOME/standalone/deployments/myapp.war /usr/svn/myapp
Docker commands
docker build . -t myapp:latest
docker run -d -p 8080:8080 -p 9990:9990 --env-file=svnvars.cfg myapp:latest
Found out what I was doing wrong. I was trying to use
/opt/eap/bin/standalone.sh
as the last command in my entrypoint script.
I discovered this was wrong by calling
docker images inspect myapp:latest
where I found
"Cmd": [
"/opt/eap/bin/openshift-launch.sh"
],
I was calling the wrong command. So I fixed this by replacing the command in my shell script and changing my ENTRYPOINT to CMD.
Here are the corrected files:
Dockerfile
FROM registry.access.redhat.com/jboss-eap-7/eap71-openshift
USER root
RUN rpm -i [too many libraries]
ADD subversion_installer_1.14.1.sh /home/svn_installer.sh
ADD svnvars.cfg /var/svn/svnvars.cfg
RUN yes | /home/svn_installer.sh
USER jboss
ARG REPO_USER
ARG REPO_PW
ARG REPO_URL
ENV REPO_USER=$REPO_USER
ENV REPO_PW=$REPO_PW
ENV REPO_URL=$REPO_URL
ADD entrypoint.sh /home/entrypoint.sh
CMD /home/entrypoint.sh
entrypoint.sh
#!/bin/bash
svn export --username="$REPO_USER" --password="$REPO_PW" "$REPO_URL" /usr/svn/myapp
cd /usr/svn/myapp
ant war
/opt/eap/bin/openshift-launch.sh

Docker not copying files specified in Dockerfile

I'm currently running a Windows Server 2019 host, and I'm trying to get Visual Studio Build Tools and SSDT installed on a windowsservercore:lts2019 image. I am able to do successful quiet installs of both if I mount the directory when I run the container with docker run -it -v <src>:<dst> image:tag powershell and run the .exes with quiet flags, however I need the installed files to be available within the container so I am trying to do this install within the Dockerfile. Here's what I have:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
SHELL ["powershell.exe", "-ExecutionPolicy", "Bypass", "-Command"]
RUN (New-Object System.Net.WebClient).Downloadfile('http://javadl.oracle.com/webapps/download/AutoDL?BundleId=210285', 'C:\\jre-8u91-windows-x64.exe')
RUN Start-Process -filepath 'C:\\jre-8u91-windows-x64.exe' -passthru -wait -argumentlist "/s,INSTALLDIR=$env:JAVA_HOME,/L,install64.log"
RUN del 'C:\\jre-8u91-windows-x64.exe'
RUN $env:PATH = $env.JAVA_HOME + '\\bin;' + $env:PATH; \
[Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine);
COPY ./vs_setup.exe .
COPY ./SSDT-Setup-ENU.exe .
RUN vs_setup.exe -q --norestart --add Microsoft.VisualStudio.Product.Professional
RUN SSDT-Setup-ENU.exe /install installvssql:ssdt /quiet /wait /norestart
RUN SSDT-Setup-ENU.exe /install INSTALLALL /quiet /wait /norestart
CMD ["powershell.exe", "-nologo"]
That reports that the COPY commands ran successfully, however once the step to run the .exes that I'd tried copying over is run, I get the error that 'vs_setup.exe' is not a recognized cmdlet, function, etc.
I do a docker run -it image:tag powershell, I can see that C:\installs exists but it's empty. The .exes that I'm trying to copy are in the same directory level as the Dockerfile being ran. Is there anyway to get these copied and installed in the Dockerfile?
Edit:
I've updated the Dockerfile to show that the Java stuff isn't changing directories, or at least shouldn't be. The folder structure is:
Directory: C:\projects
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/25/2019 3:13 PM 4291 Dockerfile
-a---- 6/27/2019 10:54 AM 1608400 SSDT-Setup-ENU.exe
-a---- 5/16/2019 3:20 PM 1286728 vs_setup.exe
As much as I would like this to work I think that I'll need to mount a volume and install these manually, then use multi-stage builds and docker commit to create a new image off of the post-install container. I'll keep this updated with what works.

Starting a Windows service in a Docker container

I am using Docker for Windows and am trying to convert a Asp.NET MVC 5 to a container. The one remaining roadblock is that I need the ASPNET State server running. I can start up the service through the interactive terminal and it works just fine, but am unable to get the container to start the service automatically. I've tried using CMD, ENTRYPOINT, and RUN, but from what I gather some of these will only execute the command while the image is building, not when the container starts.
My DOCKERFILE is as follows
FROM microsoft/aspnet:4.7.1-windowsservercore-1709
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .
CMD powershell -Command \
Set-Service aspnet_state automatic; \
Start-Service -name "aspnet_state"; \
EXPOSE 1433
Instead of using CMD, I used RUN to commit the command to the image, and used multiple RUN commands:
# Enable Session State Server
RUN powershell -Command Set-Service aspnet_state -startuptype automatic
RUN powershell -Command Stop-Service aspnet_state
RUN powershell -Command Start-Service aspnet_state
RUN powershell -Command Set-ItemProperty Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters -Name AllowRemoteConnection -Value 1
You simply need the following code after you have properly installed the service into the image.
ENTRYPOINT ["powershell"]
CMD Start-Service \""MyWindowsServiceName\"";
NOTE: The name of a windows service may be different to its executable name. You need the windows service name here, not the executable name.

Resources