Starting Powershell Script on Container Startup in Azure App Service - docker

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"]

Related

Create a Docker image with DockerFile to run two windows services

So I'm trying to build a Docker Image based on windows that will run two windows services.
This builds an image as expected but when I run the image I don't see the two windows services present and I don't see the services file with my edit in it.
I've searched and searched and have not found much help with Docker and Windows mostly everything is linux based help. I will need to expose tcp/ip ports as well for the 2 services.
Here is what I have in my DockerFile so far
FROM mcr.microsoft.com/windows/servercore:ltsc2019
COPY bin C:\Company\App\bin
COPY Installers C:\Company\Installers
WORKDIR "C:\Company\Installers"
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
RUN Start-Process 'C:\Company\Installers\msodbcsql.msi' '/qn' -PassThru | Wait-Process;
RUN echo "apprecv 22804/tcp #Company AppRecv service" >> c:\windows\system32\drivers\etc\services
WORKDIR "C:\Company\App\bin"
RUN Start-Process 'SC.exe' -Wait -ArgumentList 'CREATE "App Poll" binpath="C:\Company\App\bin\apppoll.exe" start=disabled';
RUN Start-Process 'SC.exe' -Wait -ArgumentList 'DESCRIPTION "App Poll" "Pulls Data"';
RUN Start-Process 'SC.exe' -Wait -ArgumentList 'CREATE "App Receive" binpath="C:\Company\App\bin\apprecv.exe" start=disabled';
RUN Start-Process 'SC.exe' -Wait -ArgumentList 'DESCRIPTION "App Receive" "Receives Data"';
I first run this to build the image
docker build -t app .
Then when I run
docker run -it app:latest powershell.exe
I first check the services file and don't see it changed and then when I call Get-Services I don't see the windows services installed.
What am I missing here? Eventually, I plan to run this in Azure.

How to install .Net Framework 4.8 into mcr.microsoft.com/windows container

I need to use mcr.microsoft.com/windows:10.0.17763.2928 docker image. How to install .net framework v4.8 into this container? I use following docker file. I upload ndp48-x86-x64-allos-enu.exe (.net framework v4.8 installer) into container, and then install it by command line, but it doesn't work. I got the "404 - File or directory not found."
FROM mcr.microsoft.com/windows:10.0.17763.2928
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
RUN Enable-WindowsOptionalFeature -Online -FeatureName IIS-ASPNET45 -All
WORKDIR c:/
COPY ndp48-x86-x64-allos-enu.exe .
RUN Start-Process -FilePath 'C:/ndp48-x86-x64-allos-enu.exe' -ArgumentList '/quiet', '/NoRestart', '/L*V C:/net48log.log' -Wait
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .

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

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

Invoke-WebRequest in docker Entrypoint

Docker file -
FROM microsoft/aspnet:4.6.2-windowsservercore-ltsc2016
WORKDIR /src
COPY ./install /src/install
ENTRYPOINT ["powershell.exe -ExecutionPolicy Bypass -NoProfile c:\\src\\install\\UpdateWindowsService.ps1;"]
CMD ["C:\\ServiceMonitor.exe", "w3svc"]
Powershell file
#Invoke-WebRequest -Uri $zipPath -OutFile $destFile
Write-Host "Downloaded File from $zipPath !" -ForegroundColor Yellow;
I need powershell file to run on startup so that it will download the latest zip file and further script will proceed with buisness logic But I am getting error while running the docker in container instance.
Error
Unable to connect remote server
Strangely When I access Docker using docker exec -it <container-id> powershell it downloads the zip successfully. Not able to understand where actual problem is.

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