Microsoft navcontainerhelper

repository·main·Indexed 19 days ago

https://github.com/microsoft/navcontainerhelper

A collection of PowerShell modules, including BcContainerHelper and NavContainerHelper, designed to simplify the management, configuration, and deployment of Business Central and Dynamics NAV containers on Docker across Windows 10, 11, and Windows Server.

Tokens
13.4K
Snippets
29
Records
43
Agent score
16%

What's inside navcontainerhelper

  1. Extend container lifecycle with AdditionalSetup.ps1 and AdditionalOutput.ps1

    main

    These scripts allow for custom logic at specific stages of the container lifecycle.

    AdditionalSetup.ps1

    • Purpose: Allows you to run additional setup tasks after all other setup scripts have completed.
    • Execution Timing: This is the last script executed before the output section and the main loop.
    • Default Behavior: Does nothing (empty script). If you override it, you do not need to call the default behavior.
    • Use Case: Any custom configuration required after the standard NAV setup is finished.

    AdditionalOutput.ps1

    • Purpose: Allows you to output custom information to the user running the container.
    • Default Behavior: Does nothing (empty script). If you override it, you do not need to call the default behavior.
    • Use Case: Writing messages to the host that should be visible to the user managing the container.
  2. How to invoke default script behavior when overriding

    main

    When you override a script in c:\run\my, you must decide if you want to replace the default behavior entirely or augment it. To execute the original default script logic within your custom override, insert the following line into your script:

    . (Join-Path $runPath $MyInvocation.MyCommand.Name)

    Note on $restartingInstance: When writing overrides, check the $restartingInstance variable. It is true if the script is running due to a container restart. You should avoid repeating heavy setup tasks (like database restoration) if the container is simply restarting.

    . (Join-Path $runPath $MyInvocation.MyCommand.Name)
  3. Customize database setup via SetupDatabase.ps1

    main

    The SetupDatabase.ps1 script ensures a database is ready for the NAV Service Tier.

    Default Behavior:

    1. If $restartingInstance is true, it does nothing.
    2. If the bakfile environment variable is provided (path or URL), it restores that backup as the NAV Database.
    3. If appBacpac or tenantBacpac environment variables are provided (path or URL), they are restored as the NAV Database.
    4. If database credentials are provided, it connects to an external SQL Server and sets up encryption keys.
    5. If the multitenant switch is enabled, it switches the container to multi-tenancy mode.

    When to override:

    • To place your database file on a specific file share on the Docker host.
    • To connect to an Azure SQL Database or a different external SQL Server instance.
  4. Understand Business Central Generic Images

    main

    BcContainerHelper uses generic images named mcr.microsoft.com/businesscentral:osversion. The function Get-BestGenericImage automatically selects the best match for your OS from the following LTSC images:

    • mcr.microsoft.com/businesscentral:ltsc2016
    • mcr.microsoft.com/businesscentral:ltsc2019
    • mcr.microsoft.com/businesscentral:ltsc2022

    OS Compatibility Mapping:

    • Windows 10: Receives ltsc2019 (requires Hyper-V isolation).
    • Windows 11: Receives ltsc2022 (supports process isolation).
    • Windows Server 2019: Supports process isolation with a matching image.
    • Windows Server 2022: Supports process isolation with the latest image.
  5. Compare Hyper-V vs Process isolation for Docker

    main

    When setting up your environment, choose between two isolation levels:

    FeatureHyper-V IsolationProcess Isolation
    Isolation LevelHigh (separate VM)Moderate (namespace/resource control)
    PerformanceLower (VM overhead)Higher (runs on host kernel)
    CompatibilityCan run different OS versionsLimited to host OS/kernel version
    ResourcesHigher CPU/MemoryLower CPU/Memory
    StartupSlowerFaster
    Host Req.Windows with Hyper-V enabledWindows with Container support enabled

    Recommendation: Use Process isolation if possible for better performance. Use Hyper-V only if you encounter compatibility issues (e.g., running specific containers on Windows 10).

  6. Use a custom license file in a container

    main

    By default, containers use the CRONUS demo license. To use your own license file, use the -licenseFile parameter with New-NavContainer. You have three primary methods:

    1. Secure URL: Provide a URL starting with http or https. The script will download and import it.
    2. Local Path: Provide a path to a file on the host. To make this work, you must first share the host folder with the container using -additionalParameters (e.g., -v c:\temp:c:\temp).
    3. Override SetupLicense: Add a custom SetupLicense.ps1 to the -myScripts parameter to manually handle the import logic.

    To import a license into an already running container, use the Import-NavContainerLicense function.

    # Example: Using a secure URL
    New-NavContainer -accept_eula `
                     -containerName "test" `
                     -auth NavUserPassword `
                     -imageName "microsoft/dynamics-nav" `
                     -Credential $credential `
                     -licensefile "https://www.dropbox.com/s/abcdefghijkl/mylicense.flf?dl=1"
    
    # Example: Importing to a running container
    Import-NavContainerLicense -containerName test -licenseFile "https://www.dropbox.com/s/abcdefghijkl/mylicense.flf?dl=1"
  7. Extract CRONUS database from a NAV container image

    main

    You can extract the SQL Express CRONUS Demo Database files from a standard NAV container image by overriding the navstart.ps1 script. This process starts the SQL Server inside the container, takes the database offline, and copies the .mdf and .ldf files to a shared host folder.

    To perform this, use New-NavContainer with the -myScripts parameter to provide a custom navstart.ps1 script and the -additionalParameters parameter to map a host folder to the container's database destination.

    $navstartScript = @'
    Write-Host "Extracting databases..."
    # ... (script logic to start SQL, take DB offline, and copy files) ...
    '@
    
    $hostFolder = "c:\temp\navdbfiles"
    $imageName = "microsoft/dynamics-nav"
    $additionalParameters = @("-v ${hostFolder}:c:\navdbfiles")
    $tempcredential = New-Object System.Management.Automation.PSCredential -argumentList "admin", (ConvertTo-SecureString -String "<YourPassword>" -AsPlainText -Force)
    
    New-NavContainer -accept_eula `
                     -containerName "temp" `
                     -imageName $imageName `
                     -Credential $tempcredential `
                     -memoryLimit "1g" `
                     -shortcuts None `
                     -additionalParameters $additionalParameters `
                     -myScripts @{"navstart.ps1" = $navstartScript}
    
    Remove-NavContainer -containerName "temp"
  8. Create a SQL Server container and restore a .bak file

    main

    To use an existing database backup, you can create a standalone SQL Server container and restore a .bak file into it.

    1. Define the host folder containing your .bak file.
    2. Run a docker run command to start a SQL Server container (e.g., microsoft/mssql-server-windows-express), mounting your host folder to the container.
    3. Use Restore-SqlDatabase with RelocateFile to ensure the database files are placed in the correct container paths.
    $hostFolder = "c:\temp\navdbfiles"
    $databaseCredential = New-Object System.Management.Automation.PSCredential -argumentList "sa", (ConvertTo-SecureString -String "<YourPassword>" -AsPlainText -Force)
    $dbPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($databaseCredential.Password))
    
    # Start SQL Server container
    $dbserverid = docker run -d -e sa_password="$dbPassword" -e ACCEPT_EULA=Y -v "${hostFolder}:C:/temp" microsoft/mssql-server-windows-express
    $databaseServer = $dbserverid.SubString(0,12)
    $databaseInstance = ""
    
    $databaseName = "Demo Database NAV (11-0)"
    $databaseServerInstance = @{ $true = "$databaseServer\$databaseInstance"; $false = "$databaseServer"}["$databaseInstance" -ne ""]
    
    # Relocate files during restore
    $RelocateData = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("${databaseName}_Data", "c:\temp\${databaseName}_Data.mdf")
    $RelocateLog = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("${databaseName}_Log", "c:\temp\${databaseName}_Log.ldf")
    
    Restore-SqlDatabase -ServerInstance $databaseServerInstance -Database $databaseName -BackupFile "C:\temp\$databaseName.bak" -Credential $databaseCredential -RelocateFile @($RelocateData,$RelocateLog)
  9. Use a custom Database backup (.bak) file with a NAV container

    main

    When creating a new container with New-NavContainer, you can specify a custom .bak file using the bakfile environment variable passed via -additionalParameters. There are three ways to provide the file:

    1. Secure URL: Provide a direct URL to the .bak file.
    2. Shared Host Folder: Map a host folder to the container using --volume and point bakfile to the path inside the container.
    3. myScripts: Include the .bak file in the -myScripts parameter. The file will be copied to c:\run\my inside the container, and you can then point bakfile to that location.

    Note: Container initialization and Super user creation still occur when using a .bak file. If using Windows Authentication, only the username is compared (domain is ignored).

    # Option 1: Secure URL
    New-NavContainer -accept_eula -containerName "test" -Auth NavUserPassword -imageName $imageName -Credential $navcredential -licenseFile "https://url.to/license.flf" -additionalParameters @('--env bakfile="https://url.to/database.bak?dl=1"')
    
    # Option 2: Shared Host Folder
    New-NavContainer -accept_eula -containerName "test" -Auth NavUserPassword -imageName $imageName -Credential $navcredential -licenseFile "https://url.to/license.flf" -additionalParameters @('--volume c:\temp\navdbfiles:c:\temp', '--env bakfile="c:\temp\Demo Database NAV (11-0).bak"')
    
    # Option 3: Using myScripts
    New-NavContainer -accept_eula -containerName "test" -Auth NavUserPassword -imageName $imageName -Credential $navcredential -licenseFile "https://url.to/license.flf" -myScripts @("c:\temp\navdbfiles\Demo Database NAV (11-0).bak") -additionalParameters @('--env bakfile="c:\run\my\Demo Database NAV (11-0).bak"')
  10. Make CSIDE and Windows Client available on the host

    main

    Use the -includeCSIDE parameter with New-NavContainer to share the Classic Development Environment (CSIDE) and the Windows Client from the container to the host computer.

    This process:

    1. Shares C:\ProgramData\NavContainerHelper\Extensions\<containername>\Program Files with the container.
    2. Copies files from the Windows Client folder to the shared folder via a script.
    3. Places a ClientUserSettings.config file in the folder.
    4. Creates desktop shortcuts for CSIDE and the Windows Client.
    5. Exports baseline objects to a folder (unless -doNotExportObjectsToText is specified).

    Prerequisites for host CSIDE: You must install vcredist_x86 and sqlncli on the host machine.

    Note: When using CSIDE, you cannot modify or compile table schemas unless you are using Windows Authentication.

    New-NavContainer -accept_eula `
                     -containerName "test" `
                     -auth NavUserPassword `
                     -imageName "microsoft/dynamics-nav" `
                     -includeCSIDE `
                     -doNotExportObjectsToText
  11. Install Docker for NavContainerHelper

    main

    To run a NAV container, you must have a Docker host. Supported operating systems include:

    • Windows Server 2016 (or later): You can choose between Hyper-V isolation or Process isolation.
    • Windows 10 Pro: Containers always use Hyper-V isolation with Windows Server Core.

    Deployment Options:

    • Azure: You can deploy a pre-configured Windows Server 2016 with Docker from the Azure Gallery. It is recommended to use at least Standard_D2 or Standard_D3 instances (avoid Standard_D1).
    • Local Windows Server: Follow the official Microsoft quick-start guide for Windows Server containers.
    • Local Windows 10: Follow the official Microsoft quick-start guide for Windows 10 containers.
  12. Install the NavContainerHelper PowerShell module

    main

    NavContainerHelper is a PowerShell module available in the PowerShell Gallery. It provides functions to run and interact with NAV containers.

    To install the module on your Docker host, run the following command in PowerShell ISE:

    install-module navcontainerhelper -force

    After installation, you can use these commands to explore the module:

    • get-command -Module navcontainerhelper: Lists all available functions.
    • Write-NavContainerHelperWelcomeText: Lists functions grouped by functional areas.
    install-module navcontainerhelper -force