• Containers,  Microsoft

    Standing up Portainer using Docker Desktop on Windows.

    So as I find useful Docker tools… I’m finding that Portainer is a very useful for my running Docker Desktop…

    The thing of it is… like a lot of images/containers… depending on what type of images you are set to run (Windows vs. Linux), the actual running of the Portainer varies.

    If one is on windows images…

    #
    #First time running Portainer
    #
    #Now make sure that the directory C:\ProgramData\Portainer exist or change the second volume property (-v) below 
    #
    docker run -d -p 9000:9000 --name portainer --restart always -v "\\.\pipe\docker_engine:\\.\pipe\docker_engine" -v C:\ProgramData\Portainer:C:\data portainer/portainer
    #
    #
    

    This gives one access to Portainer on Localhost:9000. In the first go around you will need set an admin user and password.

    Now onto the Linux version…

    #
    # Do volume if one does not exist
    #
    docker volume create portainer_data
    #
    #Now start the image
    #
    docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

    The key to doing this is to choose the type of containers before executing the RUN or PULL of the portainer image.

    Because you got it, if you are running Windows containers – The RUN or PULL will get you that type of image for the OS… And one must Run the container based on the type. Indeed- the volume property is different between Windows and Linux….

    Be Happy with your Containers….

    ~SG

  • Containers,  Microsoft

    Docker Desktop WSL 2 Ports Access Denied

    As I’ve been trying to work with Linux containers and images, I ran into a problem with assigning ports to Linux containers. The Linux distro is running under WSL 2 on my Windows 10 2004… and when I set the -P x:y, Docker would fail to start the container will an error Access denied. 

    So after lots of internet looking… and port mangling… noon of which work… I find that the Linux distro (Ubuntu 18 something) seems to require root… so here we go…

    I open a bash terminal under the distro that docker is using… and do the following:

    sudo groupadd docker
    
    sudo usermod -aG docker $USER
    
    sudo chown root:docker /var/run/docker.sock

    Now the first groupadd should report that the docker group already exist… not a problem. This only means you are in the right distro…

    The next two commands put the docker socks code under the ownership of root.

    And there you go, one can assign ports in the run.

    ~SG

  • Containers,  Microsoft

    Docker Desktop and Windows 10 2004

    Ok as I previously talked about getting Docker up and going on a PC that really does not support the level of Hyper-V that is needed by Docker Desktop… there is a another solution. Windows 2004 update…

    Now I’ve been putting off the move to version 2004 because it was known to have had problems… But I finally made the move… no real problems yet. So why do this… with Windows 10 2004 one get’s WSL (the Windows Subsystem Linux). This is key to getting Docker Desktop to work without using Hyper-V!

    So lets do some stepping through this:

    First move one’s Windows to version 2004 (hours and hours and hours later) – make sure you enable – Windows Subsystem for Linux- it may or may not be turned on.
    Second install Docker Desktop – if WSL is installed and ready the opening installer for Docker will have a WSL 2 enable selection. Make sure you select that.
     **One might also have to update a default distro to WSL 2 if you have linux distros already on your PC. One will get a warning and where to go to do that.

    Now when Docker Desktop finally gets loaded or running… go into Powershell and do a wsl -l -v:

    PS C:\ps_Home> wsl -l -v
      NAME                   STATE           VERSION
    * Ubuntu                 Stopped         2
      SLES-15                Stopped         2
      Ubuntu-20.04           Stopped         2
      Debian                 Stopped         2
      kali-linux             Stopped         1
      docker-desktop-data    Running         2
      docker-desktop         Running         2
    PS C:\ps_Home>

    If, again, everything is ok… you should see a similar list to the one above… these are the Linux Distros. As one can see I have several.
    ** You can select which Distro is used in Docker, but it must be a WSL 2 version… Now one can convert version 1 (in my list that would be kali-linux) by doing a wsl command-

    wsl --set-version kali-linux 2

    You can Enable the other Distros for Docker within the Docker Desktop app. Settings => Resources => WSL Integration.

    And now you are good to go.

    ~SG

  • Containers,  Microsoft

    Docker Oh Docker

    The  dark world of Containers and Images…oh my.  As I step my feet back into the Container World… and bring back the horror that is Hyper-V… I am reminded that my personally built Mage Dev PC does not really fully support the whole of Hyper-V- as least not how Docker Desktop wants to use it. Ya, it work fine on my ThinkPads (including my mini- Yoga X1)… but alas not the main desktop dev.  Oh woe!

    But wait… there is a way…. I ran across this blog entry Docker without Hyper-V … and it really works… The long and short of it…. two methods to the madness…

    Option 1 script:

    # Install Windows feature containers
    $restartNeeded = $false
    if (!(Get-WindowsOptionalFeature -FeatureName containers -Online).State -eq 'Enabled') {
        $restartNeeded = (Enable-WindowsOptionalFeature -FeatureName containers -Online).RestartNeeded
    }
    
    if (Get-Service docker -ErrorAction SilentlyContinue)
    {
        Stop-Service docker
    }
    
    # Download the zip file.
    $json = Invoke-WebRequest https://download.docker.com/components/engine/windows-server/index.json | ConvertFrom-Json
    $stableversion = $json.channels.stable.alias
    $version = $json.channels.$stableversion.version
    $url = $json.versions.$version.url
    $zipfile = Join-Path "$env:USERPROFILE\Downloads\" $json.versions.$version.url.Split('/')[-1]
    Invoke-WebRequest -UseBasicparsing -Outfile $zipfile -Uri $url
    
    # Extract the archive.
    Expand-Archive $zipfile -DestinationPath $Env:ProgramFiles -Force
    
    # Modify PATH to persist across sessions.
    $newPath = [Environment]::GetEnvironmentVariable("PATH",[EnvironmentVariableTarget]::Machine) + ";$env:ProgramFiles\docker"
    $splittedPath = $newPath -split ';'
    $cleanedPath = $splittedPath | Sort-Object -Unique
    $newPath = $cleanedPath -join ';'
    [Environment]::SetEnvironmentVariable("PATH", $newPath, [EnvironmentVariableTarget]::Machine)
    $env:path = $newPath
    
    # Register the Docker daemon as a service.
    if (!(Get-Service docker -ErrorAction SilentlyContinue)) {
      dockerd --exec-opt isolation=process --register-service
    }
    
    # Start the Docker service.
    if ($restartNeeded) {
        Write-Host 'A restart is needed to finish the installation' -ForegroundColor Green
        If ((Read-Host 'Do you want to restart now? [Y/N]') -eq 'Y') {
          Restart-Computer
        }
    } else {
        Start-Service docker
    }

    This works just fine… and Option 2 (use DockerMsftProvider)

     

    $paths = $env:psmodulePath.Split(';')
    $modulePath = Join-Path $paths[0] "DockerMsftProvider"
    if (!(Test-Path $modulePath)) {
      New-Item -Path $modulePath -ItemType Directory
    }
    $outfile = Join-Path $modulePath 'DockerMsftProvider.psm1'
    Invoke-WebRequest -UseBasicParsing -OutFile $outfile -Uri https://raw.githubusercontent.com/ajkauffmann/MicrosoftDockerProvider/master/DockerMsftProvider.psm1
    
    $outfile = Join-Path $modulePath 'DockerMsftProvider.psd1'
    Invoke-WebRequest -UseBasicParsing -OutFile $outfile https://raw.githubusercontent.com/ajkauffmann/MicrosoftDockerProvider/master/DockerMsftProvider.psd1
    
    Install-Package Docker -ProviderName DockerMsftProvider -Force

    Now Option 2 – don’t forget to do a Start-Service docker … or things will complain…

    Now I did change up the module path a bit to push docker up to my system module area instead of to my user’s doc path… and I did notice that Option 2 got a newer version of docker… Oh well you choose.

    And yes docker commands work… Kitematic works… and Portainer works…

    Btw if you want Portainer… 

    docker pull portainer/portainer
    docker run -d --restart always --name portainer --isolation process -h portainer -p 9000:9000 -v //./pipe/docker_engine://./pipe/docker_engine portainer/portainer

    There you go!

    ~ScottGeek….

     

  • Microsoft

    C# Full Timestamp

    Because I’m always having to look this up… a full (useful) timestamp should always look like this…

    YYYYMMDD HH:MM:SS.fff   => 20200730 14:58:00.000   

    string timeStamp = DateTime.Now.ToString("yyyyMMdd hh:mm:ss.fff tt");  //Example 20200730 03:02:39.591 PM
    string fileTimeStamp = DateTime.Now.ToString("yyyyMMdd_HHmmssfff");    //20200730_150535040
    string fileTimeStamp2 = DateTime.Now.ToString("yyyyMMdd_hhmmssffftt");// 20200730_030707929PM

     

    ~SG

     

  • ASP.NET Core,  Blazor,  Microsoft

    The Server Side Blazor and SignalR Timeout

    So in my Blazor travels I ran across one (or another) annoying thing. In this one we will talk about that Server -Timeout? Disconnect? Retry? Not really sure which one it is.
    This affects Blazor Server Side where SinalR is being used between the browser and server side code.image

     

     

    I came across some Javescript that can go into the _Host.cshtml file.

    <script>
        // Wait until a 'reload' button appears
        new MutationObserver((mutations, observer) => {
            if (document.querySelector('#components-reconnect-modal h5 a')) {
                // Now every 10 seconds, see if the server appears to be back, and if so, reload
                async function attemptReload() {
                    await fetch(''); // Check the server really is back
                    location.reload();
                }
                observer.disconnect();
                attemptReload();
                setInterval(attemptReload, 10000);
            }
        }).observe(document.body, { childList: true, subtree: true });
    </script>

    Not really a solution but let’s see. The script is basic and checks the connection and reloads the page as needed.

    There’s a full run down here ASP Core Issues. Another good resource is this docs page ASP.NET Core SignalR configuration.

    Happy Blazor-ing!

    ~ScottGeek

     

  • Blazor,  Microsoft

    Blazor: And the Identity Scaffolding Mess

    Ok, back around to the annoying bin. Let’s talk adding Identity to a Blazor Web Assembly app…

    Out of the box when you start with a Blazor WebAss project using Identity and of course ASP Core hosted (I’m using preview 2). You then decide that all of the hidden razor pages really need to be customized (don’t even get me started on Hidden razor pages). Well there is a way to do just that.

    You Add Scaffolded Item to the Server project and select Identity (nope not going to show you that- there’s plenty of how-to on the internet). I wait while you go figure out how-to do that……   Wait  wait wait wait….

    All right, now you have those missing identity pages  up in Areas/Identity/Pages/Account – and you have an app that compiles and run, right? Well…. NO you don’t. Because now your app is broken… And that’s where we start… Let’s fix it.

    The Fix –

      RegisterConfirmation.chtml.cs  (if during your scaffold you selected the RegisterConfirmation page to include in the Areas/Identity/Pages/Account)
        You will need to add the reference using Microsoft.AspNetCore.Identity; – this is missing from the code behind.

      The Scaffold also creates an another wwwroot folder in the .Server project – The app runs into conflicts with css etc… 
        All you need to do here is delete the wwwroot folder from the .Server project. The Blazor will come up normal.

    Now, there maybe other compile errors depending on the mix of .dot core you have, etc. You will just need to work through those.

    Another annoying thing that happens when you mix Blazor and these older razor identity pages… is how the identity system works when you logout. Normally one likes to have the app navigate back to the home page when one logs out. This is doable but not in the box on the template.

    This is easy fix….

    In your client project in the Pages folder, you have a Authentication.razor file:

    @page "/authentication/{action}"
    @using Microsoft.AspNetCore.Components.WebAssembly.Authentication
    <RemoteAuthenticatorView Action="@Action" />
    
    @code{
        [Parameter] public string Action { get; set; }
    }

    This is the default page… Let’s make a change…

    @page "/authentication/{action}"
    @using Microsoft.AspNetCore.Components.WebAssembly.Authentication
    @inject NavigationManager navMGR
    <RemoteAuthenticatorView Action="@Action">
        <LogOutSucceeded>
          @{navMGR.NavigateTo("/");}
        </LogOutSucceeded>
    </RemoteAuthenticatorView>
    
    @code{
        [Parameter] public string Action { get; set; }
    }

    We injected the NavigationManager, because we want to navigate to the home page. 
     One see that in the RemoteAuthenticationView we have some options… LogOutSucceeded is a component option that allows us to do something, when the user has logged out with no errors. 
     This is good place to put a NavigateTo Blazor command… and as we see we can force the app (from the box) to go to the home page.

    Neat… 

    Now yes, the errors and problems are annoying… they have been for the scaffold for awhile now… but hopefully as Blazor moves out of preview, these things will be fixed.

    ~ScottGeek   Happy Blazoring….

     

     

     

     

     

  • SQL Server

    Powershell Create of the SSISDB Catalog

    So when management gets this [insert explicative] idea to strip away my MSDN enterprise access, and I need to create an SSISDB catalog on my dev server- what the hell am I to do? Well, maybe not simple… I put on my PowerShell hack through hat. Shall we?

    In your favorite SQL instance (we’ll just use localhost for my examples) start with making sure you have CLR ENABLED first:

    EXEC sp_configure 'clr enabled', 1;  
    RECONFIGURE;  
    GO

    Do this in a query window in SSMS of course.

    Now the PowerShell:
     

    # Load the IntegrationServices Assembly  
    [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices")  
    
    # Store the IntegrationServices Assembly namespace to avoid typing it every time  
    $ISNamespace = "Microsoft.SqlServer.Management.IntegrationServices"  
    
    Write-Host "Connecting to server ..."  
    
    # Create a connection to the server  
    $sqlConnectionString = "Data Source=localhost;Initial Catalog=master;Integrated Security=SSPI;"  
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString  
    
    # Create the Integration Services object  
    $integrationServices = New-Object $ISNamespace".IntegrationServices" $sqlConnection  
    
    # Provision a new SSIS Catalog  
    $catalog = New-Object $ISNamespace".Catalog" ($integrationServices, "SSISDB", "P@assword1")  
    $catalog.Create()

    The last part in “Provision a new SSIS Catalog” make sure you do a good password.

    And that’s it…. So why am I doing this with PowerShell? No “DIS” on PowerShell, but it seems that the version I install SQL Server 2016 has this thing about connecting to Azure SSIS with creating a SSISDB Catalog, and since I no longer have access to MSDN (you knew MSDN was in this somewhere) I had to hack my way around getting a catalog created… Now yes, I could have done the Azure SQL SSISDB connect bah bah (I do have an enterprise Azure accounts), but you what? This same management does not want to spend money on Azure… YA! An Azure SQL SSISDB has a cost. 

    So there you go… Got to love this jumping around not having the tools to get stuff done.

    ~ScottGeek