Container.init.ps1
<# .SYNOPSIS Initializes a container during build. .DESCRIPTION Initializes the container image with the necessary modules and packages. This script should be called from the Dockerfile, during the creation of the container image. ~~~Dockerfile # Thank you Microsoft! Thank you PowerShell! Thank you Docker! FROM mcr.microsoft.com/powershell # Set the shell to PowerShell (thanks again, Docker!) SHELL ["/bin/pwsh", "-nologo", "-command"] # Run the initialization script. This will do all remaining initialization in a single layer. RUN --mount=type=bind,src=./,target=/Initialize ./Initialize/Container.init.ps1 ~~~ The scripts arguments can be provided with either an `ARG` or `ENV` instruction in the Dockerfile. .NOTES Did you know that in PowerShell you can 'use' namespaces that do not really exist? This seems like a nice way to describe a relationship to a container image. That is why this file is using the namespace 'mcr.microsoft.com/powershell'. (this does nothing, but most likely will be used in the future) #> using namespace 'mcr.microsoft.com/powershell AS powerShell' param( # The name of the module to be installed. [string]$ModuleName = $( if ($env:ModuleName) { $env:ModuleName } else { (Get-ChildItem -Path $PSScriptRoot | Where-Object Extension -eq '.psd1' | Select-String 'ModuleVersion\s=' | Select-Object -ExpandProperty Path -First 1) -replace '\.psd1$' } ), # The packages to be installed. [string[]]$InstallAptGet = @($env:InstallAptGet -split ','), # The modules to be installed. [string[]]$InstallModule = @($env:InstallModule -split ','), # The Ruby gems to be installed. [string[]]$InstallRubyGem = @($env:InstallRubyGem -split ','), # If set, will keep the .git directories. [switch]$KeepGit = $($env:KeepGit -match $true) ) # Copy all container-related scripts to the root of the container. Get-ChildItem -Path $PSScriptRoot | Where-Object Name -Match '^Container\..+?\.ps1$' | Copy-Item -Destination / # Create a profile New-Item -Path $Profile -ItemType File -Force | Out-Null if ($ModuleName) { # Get the root module directory $rootModuleDirectory = @($env:PSModulePath -split '[;:]')[0] # Determine the path to the module destination. $moduleDestination = "$rootModuleDirectory/$ModuleName" # Copy the module to the destination # (this is being used instead of the COPY statement in Docker, to avoid additional layers). Copy-Item -Path "$psScriptRoot" -Destination $moduleDestination -Recurse -Force # and import this module in the profile Add-Content -Path $profile -Value "Import-Module $ModuleName" -Force } # If we have modules to install if ($InstallModule) { # Install the modules Install-Module -Name $InstallModule -Force -AcceptLicense -Scope CurrentUser # and import them in the profile Add-Content -Path $Profile -Value "Import-Module '$($InstallModule -join "','")'" -Force } # If we have packages to install if ($InstallAptGet) { # install the packages apt-get update && apt-get install -y @InstallAptGet '--no-install-recommends' && apt-get clean | Out-Host } if ($InstallRubyGem) { # Install the Ruby gems gem install @InstallRubyGem } if ($ModuleName) { # In our profile, push into the module's directory Add-Content -Path $Profile -Value "Get-Module $ModuleName | Split-Path | Push-Location" -Force } if (-not $KeepGit) { # Remove the .git directories from any modules Get-ChildItem -Path $rootModuleDirectory -Directory -Force -Recurse | Where-Object Name -eq '.git' | Remove-Item -Recurse -Force } # Congratulations! You have successfully initialized the container image. # This script should work in about any module, with minor adjustments. # If you have any adjustments, please put them below here, in the `#region Custom` #region Custom bundle config --global silence_root_warning true #endregion Custom |