Create an Azure Container Registry

The Azure Container Registry hosts container images for deployment in any of the container hosting services.

Create a new Azure Container Registry

  • Log into the Azure Portal at http://portal.azure.com
  • In the search bar search for container registry and select Container registries
  • Click the Create button to create a new Azure container registry
  • Set the values and click the Next: Networking button
  • You need a Premium subscription to set up private access for better security. Click the Next: Encryption button
  • Encryption is also only available for Premium subscriptions. Click the Next: Tags button
  • Set up tags for better cost reporting
  • If you want to automate the registry creation in the future, click the Download a template for automation link. Click the Create button to create the registry.

To change the Azure Resource Group name

If you have created an Azure Resource Group, and want to change the name, unfortunately you cannot rename it. To change the name create a new resource group and move all resources from the old group to the new one.

Create a new resource group

  • In the main Azure page search for resource groups and select Resource groups from the list
  • Click the Create button and select Create new resource group
  • Enter the name of the resource group and click the Review + cerate button
  • Click the Automation link to download the creation script
  • Click the Cerate button to create the resource group

Move the resources from the old resource group to the new one

  • Open the old resource group, and click the first resource
  • Click the move link next to the old resource group name
  • Select the new resource group from the list
  • The validation status displays the current activity
  • Some resources cannot be moved
    • Restore points
  • If the resource can be moved, click the Next button at the bottom of the page
  • Select the checkbox and click the Move button
  • To monitor the progress of the move click the Notifications icon. The source and destination resource groups are locked during the move, so only one move can be processed at a time.
  • As the resource has been moved, the refresh button cannot display the new parent information. Go back to the Resource Group list and select the old resource group again top move the rest of the resources.

Deploy a web application in Azure Container Apps (ACA)

To deploy an application to Azure Container Apps

  • Log into the Azure Portal at http://portal.azure.com
  • In the top search bar search for container apps and select Container Apps in the list
  • Click the arrow next to Create and select Container App
  • Create a new Resource Group if needed, enter the app name (all lower case characters), select the Region. Select the environment, or click the Create new environment link. The West US 3 is the newest region in the west, located in Phoenix, Arizona, and provides Availability Zone support. Although West US is located in California, but does not provide availability zone support. Availability zone support offers very important redundancy within the same region in case of network and power outage, and natural disasters. The data transfer between availability zones within the same region is free, and many services can utilize the redundancy.
  • Enter the environment name, and select the zone redundancy, and click the Create button. For non mission critical apps the zone redundancy is usually not necessary, as it doubles the infrastructure cost.
  • Click the Next: Container button
  • Container
    • If there is no available container image to deploy, select Use quickstart image. This will deploy a temporary Hello World web application.
    • If you already have a container image to deploy, select the image location and resource requirements. Click the Next: Ingress button


  • For web applications enable ingress and traffic from anywhere, set the port to 80. Click the Next: Tags button
  • Add a name tag to the application for cost tracking, and click the Next: Review + create button
  • When the validation Passed

    Click the Download a template for automation link at the bottom of the page
  • On the next page click the Download button
  • In the upper right corner click the X to close the Template page
  • At the bottom of the page click the Create button
  • When the deployment is complete, click the Go to resource button
  • In the upper right of the page click the application URL link to open it in the browser.

Manage GitHub Copilot budget

The GitHub Copilot budget allows us to make sure we get the necessary premium assistance with a predictable price.

AI agent usage is charged by the complexity of the request and response, so the charges are very unpredictable

The $10 GitHub Copilot Pro subscription includes the free tier usage, that is may not enough if we use premium features, like Anthropic’s Claude Sonnet (for rapid drafts), and Claude Opus (for polishing the final, most complex sections).

When you have reached the limits of the free tier, you can update the budget to responsibly request more help to finish the project. To update the GitHub Copilot Coding Agent budget

  • Navigate to Budgets and alerts
  • In the All Premium Request SKUs line click the ellipses and select Edit
  • Enter the amount you are planning to spend on the AI Coding Agent and click the Update budget button

Creating Tailwind theme collections

Tailwind is a rapid web development tool to style user interfaces using English like expressions. It has advantages and disadvantages.

Advantages

Instead of complex CSS, use English like style class names to control all aspects of the web interface

Disadvantages

When we use CSS, we create classes to style similar elements, like submitButton, searchField. Tailwind classes define a specific visual property, like background, border, text color. There is no room to create styles for similar objects. Using Tailwind it can be tedious to keep the visuals consistent in a large web application. If we want to update the style of all buttons on multiple pages, we have to visit all of them to change the class names.

In this tutorial we will develop a system that merges the advantages of the CSS thematic classes and the friendliness of Tailwind.

We will create a class collection, a middle layer between the Tailwind classes and the elements to specify the look of all controls with the same purpose. You still can override the values at the individual control level with the ! (important) postfix.

Class collection

Create the styles/classes.ts file in the same directory where the style sheets are located for consistency. In this example we will create separate themes for the panel header, and the panel body. All contains light and dark mode Tailwind classes for background, border, button text, hover styling.

// Define color themes for different panel types
// Each theme includes classes for borders, backgrounds, text, inputs, buttons, and drag states
export const ColorThemes = {
  panelHeader: {
    bg: "bg-slate-200 dark:bg-slate-700",
    text: "text-black dark:text-white",
    input: "bg-white dark:bg-slate-600 text-black dark:text-white placeholder:text-slate-500 dark:placeholder:text-slate-400",
    button: "bg-black/50 dark:bg-white/20 text-white/80 dark:text-white hover:bg-black/40 dark:hover:bg-white/50",
  },
  panelBody: {
    border: "border-blue-200 dark:border-slate-600",
    bg: "bg-slate-100 dark:bg-slate-700",
    text: "text-blue-200 dark:text-blue-800",
    hover: "hover:bg-blue-100 dark:hover:bg-slate-700",
    button: "bg-blue-600 dark:bg-blue-800 hover:bg-blue-500 dark:hover:bg-blue-700",
  },
};

Usage

In the .tsx file import the class collection and create constant references.

// Import color themes to standardize appearance for light and dark modes
import { ColorThemes } from "~/styles/classes";

Style the controls. Enclose the entire className definition in curly braces, and use backtick to allow variable usage in the string. You can add additional Tailwind classes to the element to set specific visual features.

    <div className={`${ColorThemes.panelBody.bg} ${ColorThemes.panelBody.border} rounded-xl`} >

To override the background color for this element, use the ! (important) postfix

<div className={`${ColorThemes.panelBody.bg} bg-black! rounded-xl`} >

Using React Router (Remix) with Material Tailwind components

Material UI is a great Google React UI component library. It looks great, provides consistent look for web applications, but it has two disadvantages:

  • The icon library has more than 9000 icons, it takes a long time to load all of them, as there is no tree shaking to ignore the unused items.
  • The Tailwind styling classes don’t always work, because the Material UI built-in themes of colors and other settings take precedent.

Material Tailwind is an opensource library recreating the consistent look of Material UI, but allowing Tailwind themes to control the look.

To set a React Router (Remix) web application to use Material Tailwind

Install Tailwind CSS with React Router (Remix)

Install Tailwind CSS

pnpm install tailwindcss @tailwindcss/vite

Configure the Vite plugin. Add the bold lines to the vite.config.js file

import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
  plugins: [
    tailwindcss(),
    reactRouter(),
    tsconfigPaths(),
  ],
});

Add to the app.css file

@import "tailwindcss";

See Install Tailwind CSS with React Router

Install @material-tailwind/react as a dependency

Execute the command

pnpm i @material-tailwind/react

Create the tailwind.config.js file in the root of the web application directory

const withMT = require("@material-tailwind/react/utils/withMT");
module.exports = withMT({
  content: ["./app/**/*.{js,jsx,ts,tsx}"], // Add your template paths here
  theme: {
    extend: {},
  },
  plugins: [],
});

If you are using a monorepo, to host multiple applications in the same repository, and the node_modules directory is not in the application directory, use this tailwind.config.js file in the root of the web application

import type { Config } from "tailwindcss";
 
import withMT from "@material-tailwind/react/utils/withMT";
 
export default withMT({
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "path-to-your-node_modules/@material-tailwind/react/components/**/*.{js,ts,jsx,tsx}",
    "path-to-your-node_modules/@material-tailwind/react/theme/components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
} satisfies Config);

Theme Provider

Wrap the entire application with the ThemeProvider. Create the app/entry.client file

import { RemixBrowser } from "@remix-run/react";
import { startTransition } from "react";
import { hydrateRoot } from "react-dom/client";
import { ThemeProvider } from "@material-tailwind/react";
 
startTransition(() => {
  hydrateRoot(
    document,
    <ThemeProvider>
      <RemixBrowser />
    </ThemeProvider>
  );
});

Web page example

This example displays a button using the Material Tailwind library

import MaterialTailwind from "@material-tailwind/react";
const { Button } = MaterialTailwind;
 
export default function Example() {
  return <Button>Button</Button>;
}

See Material Tailwind with Remix

React web application first page load is very slow

The React web application’s first page can load very slowly in development mode when SSR (Server Side Rendering) is enabled. There can be many causes, but there is one that can be eliminated easily. If the application uses Google’s Material UI library the loading of the more than 9000 icons can take a long time.

The main issue

The main issue was @mui/icons-material being imported in the NavigationMenu.tsx and Drawer.tsx components. This package contains thousands of icons (~9000 modules) and loads synchronously, causing Vite to do expensive on-demand optimization on first page load.

Changes Made

  1. NavigationMenu.tsx – Replaced @mui/icons-material imports with lucide-react:
    • ChevronRight → ChevronRight from lucide-react
    • ExpandMore → ChevronDown from lucide-react
    • Menu → Menu from lucide-react
  2. Drawer.tsx – Replaced Close icon from @mui/icons-material with X (aliased as Close) from lucide-react
  3. vite.config.ts – Optimized the configuration:
    • Removed workspace packages from optimizeDeps.include (they link directly to source)
    • Added more MUI submodules to pre-bundling (Collapse, Divider, Fade, Grow, List components, etc.)
    • Removed @mui/icons-material from SSR noExternal since it’s no longer used

Performance Impact

  • Before: Loading @mui/icons-material would trigger parsing/transforming thousands of modules
  • Afterlucide-react is much smaller (~400 icons, tree-shakeable) and already pre-bundled

The first page load in dev mode should now be significantly faster.

Disable the Caps Lock key in Windows 11

To disable the Caps Lock key in Windows 11 you can edit the registry.

DISCLAIMER: THIS CAN ALTER HOW YOUR KEYBOARD WORKS, DO IT AT YOUR OWN RISK!!!!

For the original full instructions see

Short of physically removing the caps-lock key from the keyboard, is there a way to disable CAPS LOCK?

The details are

  • Open the registry editor, regedit
  • BACK UP THE ENTIRE REGISTRY BEFORE YOU MAKE ANY CHANGES
    • Right-click the Computer element and select Export
    • Save the file in a location where you will find it
  • Add the Scancode Map binary value to the  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout key with the value

00 00 00 00 00 00 00 00 02 00 00 00 00 00 3A 00 00 00 00 00

  • Check, and double check, and triple check the value before saving it. A wrong value can disable certain keys on your keyboard until you are able to reverse the change. If you disable the wrong key that is necessary to log into Windows, use the on-screen keyboard with the mouse to log in and use the mouse to open Regedit and correct the error.
  • Restart the computer for the changes to take effect

Using GitHub Copilot Coding Agent in the GitHub web UI

Copilot Coding Agent can work entirely online without you knowing anything about software development. To use it

  • Open the repository in GitHub
  • Create an Issue
  • Write the instructions in the descriptions field
  • Assign it to Copilot

The agent will create a new branch and based on your description it will make code modifications.

  • To see the progress click the View session button

Once the agent completed the task, it will request a review

  • On the top of the screen you will see the message:
    Copilot requested your review on this pull request.
    Click the Add your review button
  • To enter line specific comments or instructions, hover above the plus sign and select the blue plus sign to open the Write panel.
  • You can type any message into the review field to share your thoughts with other humans, Copilot will ignore those. To give additional instructions to Copilot, start the message with @copilot
  • To start the review, click the Start a review button
  • To finish the review click the Finish your review button
  • You can write additional instructions if necessary and click the Submit review button
  • While the agent is working, you can give additional instructions in the bottom chat window
  • To go back from the session to the pull request, click the View pull request button at the top of the page
  • At the top of the screen click the Add your review button
  • Click the Review changes button
  • If you are satisfied with the result scroll down to the bottom of the page and click the Merge pull request button
  • Click the Confirm merge button
  • Click the Delete branch button

Preparing the GitHub Copilot Coding Agent environment

To make sure the GitHub Copilot Coding Agent understands your application you give instructions with

  • Project overview, including it’s purpose, goals, and any relevant background information.
  • Program architecture, standards and conventions that should be followed,
  • Useful commands or scripts for common tasks

To save the instructions

Create a new branch

  • On the code tab click the branches icon
  • In the upper right corner click the New branch button
  • Name the branch
    prepare-environment
  • Go back to the Code tab and click the down arrow on the current branch field and select the new branch
  • Navigate to the .github directory
  • If the copilot-instructions.md file does not exist in the upper right corner click the Add file button
  • Click the copilot-instructions.md file to open it
  • In the upper right corner of the edit window click the Edit button
  • You can add links to refer to other documents
  • And other instructions
  • When finished click the Commit changes button in the upper right corner
  • Click the Commit changes button on the new panel
  • The copilot-instructions-ext.md file contains more recommendations with much more details.

Prepare the GitHub Copilot Coding Agent environment

Specify the required tools in the copilot-setup-steps.yml file

  • Stay in the prepare-environment branch
  • Navigate to the .github/workflows/ directory
  • In the upper right corner click the Add file button
  • Select Create new file
  • The following example pre-installs Python and MongoDB in the Copilot environment
name: "Copilot Setup Steps"

on: workflow_dispatch
jobs:
  # This is the required job name. If different, Copilot will ignore it.
  copilot-setup-steps:
    runs-on: ubuntu-latest
 
  # Starts a MongoDB service for Copilot to use during its session.
    services:
     mongo:
       image: mongo:7
       ports:
         - 27017:27017

    # Grant Copilot early access to read the repository content.
    permissions:
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.13"
          cache: "pip"

      - name: Install Python dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r src/requirements.txt
  • Enter the file name copilot-setup-steps.yml and click the Commit changes button
  • On the next window click the Commit changes button again
  • On the Pull requests tab click the Compare & pull request button
  • Click the Create pull request button
  • Wait, and let the agent check the changes before you stat the merge
  • Click the Merge pull request button
  • Click the Confirm merge button
  • Click the Delete branch button

Manage multiple tasks with the Agents Panel

  • To open the Agents Panel, in the upper right corner of the page click the Open agents panel button
  • Make sure the current repository is selected
  • When you press enter the task is submitted. The window stays open to monitor the progress and to enter for more instructions.
  • Click the task to see the session logs

To open the Agents panel in full screen mode navigate to https://github.com/copilot/agents

If you assign multiple parallel tasks to the agent, make sure the code changes don’t overlap, otherwise merge conflicts will appear.

Working with Bitbucket

Install Atlassian SourceTree

Install Atlassian SourceTree, the free Bitbucket UI from https://www.sourcetreeapp.com/

Configure Visual Studio Code Git extension

The Git extension is a part of Visual Studio Code. If there is no Git executable installed on the system, set the portable Git executable installed by SourceTree.

Open the C:\Users\YOUR_USER_NAME\AppData\Roaming\Code\User\settings.json and set

"git.path": "%USERPROFILE%\AppData\Local\Atlassian\SourceTree\git_local\bin\git.exe"
Add Git to the Path

Add the directory path of the git.exe file to the System path environment variable:
%USERPROFILE%\AppData\Local\Atlassian\SourceTree\git_local\bin

Restart any open PowerShell or Terminal for the change to take effect.