1+ <#
2+ . SYNOPSIS
3+ Initializes a container during build.
4+ . DESCRIPTION
5+ Initializes the container image with the necessary modules and packages.
6+
7+ This script should be called from the Dockerfile, during the creation of the container image.
8+
9+ ~~~Dockerfile
10+ # Thank you Microsoft! Thank you PowerShell! Thank you Docker!
11+ FROM mcr.microsoft.com/powershell
12+ # Set the shell to PowerShell (thanks again, Docker!)
13+ SHELL ["/bin/pwsh", "-nologo", "-command"]
14+ # Run the initialization script. This will do all remaining initialization in a single layer.
15+ RUN --mount=type=bind,src=./,target=/Initialize ./Initialize/Container.init.ps1
16+ ~~~
17+
18+ The scripts arguments can be provided with either an `ARG` or `ENV` instruction in the Dockerfile.
19+ . NOTES
20+ Did you know that in PowerShell you can 'use' namespaces that do not really exist?
21+ This seems like a nice way to describe a relationship to a container image.
22+ That is why this file is using the namespace 'mcr.microsoft.com/powershell'.
23+ (this does nothing, but most likely will be used in the future)
24+ #>
25+ using namespace ' mcr.microsoft.com/powershell AS powershell'
26+
27+ param (
28+ # The name of the module to be installed.
29+ [string ]$ModuleName = $ (
30+ if ($env: ModuleName ) { $env: ModuleName }
31+ else {
32+ (Get-ChildItem - Path $PSScriptRoot |
33+ Where-Object Extension -eq ' .psd1' |
34+ Select-String ' ModuleVersion\s=' |
35+ Select-Object - ExpandProperty Path - First 1 ) -replace ' \.psd1$'
36+ }
37+ ),
38+ # The packages to be installed.
39+ [string []]$InstallAptGet = @ ($env: InstallAptGet -split ' ,' ),
40+ # The modules to be installed.
41+ [string []]$InstallModule = @ ($env: InstallModule -split ' ,' ),
42+ # The Ruby gems to be installed.
43+ [string []]$InstallRubyGem = @ ($env: InstallRubyGem -split ' ,' ),
44+
45+ # If set, will keep the .git directories.
46+ [switch ]$KeepGit = $ ($env: KeepGit -match $true )
47+ )
48+
49+ # Copy all container-related scripts to the root of the container.
50+ Get-ChildItem - Path $PSScriptRoot |
51+ Where-Object Name -Match ' ^Container\..+?\.ps1$' |
52+ Copy-Item - Destination /
53+
54+ # Create a profile
55+ New-Item - Path $Profile - ItemType File - Force | Out-Null
56+
57+ if ($ModuleName ) {
58+ # Get the root module directory
59+ $rootModuleDirectory = @ ($env: PSModulePath -split ' [;:]' )[0 ]
60+
61+ # Determine the path to the module destination.
62+ $moduleDestination = " $rootModuleDirectory /$ModuleName "
63+ # Copy the module to the destination
64+ # (this is being used instead of the COPY statement in Docker, to avoid additional layers).
65+ Copy-Item - Path " $psScriptRoot " - Destination $moduleDestination - Recurse - Force
66+
67+ # and import this module in the profile
68+ Add-Content - Path $profile - Value " Import-Module $ModuleName " - Force
69+ }
70+
71+ # If we have modules to install
72+ if ($InstallModule ) {
73+ # Install the modules
74+ Install-Module - Name $InstallModule - Force - AcceptLicense - Scope CurrentUser
75+ # and import them in the profile
76+ Add-Content - Path $Profile - Value " Import-Module '$ ( $InstallModule -join " ','" ) '" - Force
77+ }
78+
79+ # If we have packages to install
80+ if ($InstallAptGet ) {
81+ # install the packages
82+ apt- get update &&
83+ apt- get install - y @InstallAptGet ' --no-install-recommends' &&
84+ apt- get clean |
85+ Out-Host
86+ }
87+
88+ if ($InstallRubyGem ) {
89+ # Install the Ruby gems
90+ gem install @InstallRubyGem
91+ }
92+
93+ if ($ModuleName ) {
94+ # In our profile, push into the module's directory
95+ Add-Content - Path $Profile - Value " Get-Module $ModuleName | Split-Path | Push-Location" - Force
96+ }
97+
98+ if (-not $KeepGit ) {
99+ # Remove the .git directories from any modules
100+ Get-ChildItem - Path $rootModuleDirectory - Directory - Force - Recurse |
101+ Where-Object Name -eq ' .git' |
102+ Remove-Item - Recurse - Force
103+ }
104+
105+ # Congratulations! You have successfully initialized the container image.
106+ # This script should work in about any module, with minor adjustments.
107+ # If you have any adjustments, please put them below here, in the `#region Custom`
108+
109+ # region Custom
110+
111+ # endregion Custom
0 commit comments