Wednesday, June 21, 2023

Markdown Editor Developed with VUE

Markdown Editor Developed with VUE

Markdown Editor Developed with VUE

Utilizing Vue3, Vuetify, and marked to develop a simple Markdown editor that can instantly display the results of editing.

Setting Up a Dev Container for Vue3 Development

  • In VS Code, press F1
  • Choose ‘Dev Containers: Open Folder in Container…’
  • Select: ‘Vue community’ (Develop an application with Vue.js, includes everything you need to get up and running.)
  • Choose Node.js version: 18
  • Select additional features to install: (skip)
  • Then waiting “Adding Dev Container Configuration Files…” for couple menutes.

Create Project with Vuetify

The simplest way to set up a Vue3 + Vuetify3 project is to execute the ‘create vuetify’ command:

yarn create vuetify
# Project name: vue-md-preview
# ✔ Which present would you like ti inatll?
# ✔ > Default (Vuetify)
#     Base (Vuetify, VueRouter)
#     Essentials (Vuetify, VueRouter, Pinia)
#     Custom (Choose your features)
# ✔ Use TypeScript? Yes
# ✔ Would you like to install dependencies with yarn, npm, or pnpm? yarn

cd vue-md-preview
yarn dev

If you encounter a vite version error, you can adjust it with the following command:

yarn add @vitejs/plugin-vue@latest

Create Project with Vue3

You can also add Vuetify3 after setting up the Vue3 project. The steps are as follows:

  • Create Vue3 project:
    npm init vue@3.6.4
    # Need to install the following packages:
    #   create-vue@3.6.4
    # Ok to proceed? (y) y
    # ✔ Project name: vue-md-preview
    # ✔ Add TypeScript? › Yes
    # ✔ Add JSX Support? › No
    # ✔ Add Vue Router for Single Page Application development? › No
    # ✔ Add Pinia for state management? › No
    # ✔ Add Vitest for Unit Testing? › No
    # ✔ Add an End-to-End Testing Solution? › No
    # ✔ Add ESLint for code quality? › No
    #
    # Scaffolding project in /workspaces/vue-editor/vue-md-preview...
    #
    # Done. Now run:
    #
    cd vue-md-preview
    npm install
    npm install vuetify@^3.3.0
    npm run dev
    

Modify main.ts to Include Vuetify Packages

Modify the main.ts program to import relevant Vuetify packages. Here’s an example:

import { createApp } from 'vue'
import App from './App.vue'

// Vuetify 
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'

const vuetify = createVuetify({
  components,
  directives,
})

createApp(App).use(vuetify).mount('#app')

Project Folder/Files Structure

The folder and file structure of the vue-md-preview project created by Vuetify is generally as follows. In this project, we modified the content in /src/index.ts and /src/App.vue, adjusted the function registerPlugins in /plugins/index.ts to the function chaining form, and added two components, MarkdownEditor.vue and MarkdownSample.vue.

/vue-md-preview
├── node_modules/
├── public/
│   ├── favicon.ico
│   └── index.html
├── src/
│   ├── assets/
│   ├── components/
│   │   ├── MarkdownEditor.vue (add)
│   │   └── MarkdownSample.vue (add)
│   ├── plugins/
│   │   ├── index.ts (modify)
│   │   ├── vuetify.ts
│   │   └── webfontloader.ts
│   ├── App.vue (modify)
│   ├── main.js (modify)
│   └── index.css
├── .gitignore
├── package.json
├── package-lock.json
├── README.md
└── ...

Using marked to Convert markdown Text to HTML

markedjs/marked can convert markdown text into HTML for display. The steps are as follows:

yarn add marked
yarn add @types/marked --dev
or 
npm install marked
npm install @types/marked --save-dev # For TypeScript projects

Simple Markdown Editor and Preview Component

The following MarkdownEditor.vue uses the Vue3’s computed() function to instantly convert the text entered in the textarea into HTML for display. It also utilizes packages such as vuetify3 and marked.

<template>
  <v-container fluid>
    <v-row>
      <v-col cols="6">
        <v-card 
          title="Markdown Editor"  
          subtitle="Please edit Markdown syntax:">
          <v-divider></v-divider>
          <v-card-item>
            <v-textarea 
              outlined
              variant="outlined" 
              auto-grow
              no-resize
              v-model="inputMarkdown" />
          </v-card-item>
        </v-card>
      </v-col>
      <v-col cols="6">
        <v-card 
          title="Markdown Preview"
          subtitle="Below is the Markdown preview:">
          <v-divider></v-divider>
          <v-card-item>
            <div v-html="compiledMarkdown"></div>
          </v-card-item>          
        </v-card>        
      </v-col>
    </v-row>
  </v-container>
</template>

<style scoped>
</style>

<script setup lang="ts">

import { ref, computed } from "vue";
import { marked } from "marked";
import MarkdownSample from "./MarkdownSample.vue";

const inputMarkdown = ref(MarkdownSample.sampleText);
const compiledMarkdown = computed(() => marked.parse(inputMarkdown.value));

</script>

Reference

Friday, April 14, 2023

Spring Boot Beginning

Spring Boot Beginning

Using VSCode Dev Containers for Java Development

  1. Open VSCode, press F1 or Ctrl+Shift+P, type Dev Containers: Open Folder in containers..., and select your project directory.
  2. Choose Java as the Dev Container image and wait for the container to start.
  3. Open TERMINAL, and verify Java installation with the following commands:
Copy code
$ java -version
$ javac -version

In the Linux-based Dev Container, check the OS version and Java installation path:

Copy code
# Check OS
cat /etc/os-release

# Find Java installation
which javac

Set up GitLab Repository

  1. Create a new blank project on GitLab.
  2. Execute these commands to push your local data to GitLab:
Copy code
git init
git remote add origin https://gitlab.com/<group>/<project>.git
git add .
git commit -m "Initial commit"
git push -u origin master

Create a Java Spring Boot Project

  1. Install the “Spring Initializr Java Support” extension in VS Code.
  2. Press Ctrl+Shift+X, search for the extension, and click Install in Dev Container: Java.
  3. Open Command Palette (Ctrl+Shift+P or F1) and type “spring”. Choose Maven or Gradle to create the project.

This tutorial uses a Spring Boot API project managed by Maven. Select Spring Web, Spring Boot DevTools, and Spring Data as dependencies. Check Maven installation with mvn -v.

Create a package with Maven:

mvn package

Run the generated JAR file (e.g., backend-api-0.0.1-SNAPSHOT.jar):

java -jar ./target/backend-api-0.0.1-SNAPSHOT.jar

During development, use this command to compile and restart automatically after code changes:

mvn spring-boot:run

Implement OpenAPI and Swagger UI

To display Swagger UI with Spring Boot 3.0.0, use springdoc-openapi v2.1.0. Refer to the official springdoc-openapi v2.1.0 documentation. Add the following text to pom.xml:

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
  <version>2.1.0</version>
</dependency>

The Swagger UI page can be accessed at http://server:port/context-path/swagger-ui.html, and the OpenAPI Spec (JSON) is located at http://server:port/context-path/v3/api-docs.

To generate only the OpenAPI document (JSON) without the UI, include this dependency:

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
  <version>2.1.0</version>
</dependency>

For Spring Boot 2.x versions, use the following package:

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-ui</artifactId>
  <version>1.7.0</version>
</dependency>

The paths for Swagger UI and OpenAPI Spec remain the same.

Spring Boot Layerd Architecture

Recommended source code directory structure:

src/
├── main/
│   ├── java/
│   │   ├── beginning/
│   │   │   ├── example/
|   │   │   │   ├── backendapi/
|   │   │   │   │   ├── filters/
|   │   │   │   │   ├── configs/
|   │   │   │   │   ├── controllers/
|   │   │   │   │   ├── services/
|   │   │   │   │   ├── repositories/
|   │   │   │   │   └── models/
|   │   │   │   └── BackendApiApplication.java
|   │   │   └── resources/
|   │   │       └── application.properties
|   │   └── ...
│   └── ...
└── ...
  • controllers: Receive HTTP requests and respond with HTTP responses.
  • models: Define data structures for transfer and processing.
  • services: Handle data processing and business logic.
  • repositories: Connect to backend databases for data access.
  • filters: Middleware with OncePerRequestFilter as the base class, enabling tasks such as logging or security checks on HTTP requests and responses.
  • configs: Implement WebMvcConfigurer to add filters to the appropriate locations.

Controllers

Controllers simplify the development of RESTful web services. By using the @RestController annotation on a class, it can handle various HTTP requests such as GET, POST, and others.

Services

Services handle business logic and act as intermediaries for other layers (e.g., controllers). By annotating a class with @Service, Spring framework automatically creates an instance at startup. Controllers can declare a service variable using @Autowired to automatically obtain its instance. If multiple services exist, use @Qualifier to specify one.

For example, if the program contains userService1 and userService2:

@Service("userService1")
public class UserService1Impl implements UserService {
    // ...
}

@Service("userService2")
public class UserService2Impl implements UserService {
    // ...
}

If the controller selects one of the services, use the following pattern:

@RestController
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(@Qualifier("userService1") UserService userService) {
        this.userService = userService;
    }

    // ...
}

// You can also set @Qualifier directly on the service variable without using a constructor for more concise code.
@RestController
public class UserController {
    @Autowired
    @Qualifier("userService1")
    private UserService userService;

    // ...
}

If you want to use both services, use the following pattern:

@RestController
public class UserController {
    private final UserService userService1;
    private final UserService userService2;

    @Autowired
    public UserController(@Qualifier("userService1") UserService userService1, @Qualifier("userService2") UserService userService2) {
        this.userService1 = userService1;
        this.userService2 = userService2;
    }

    // ...
}

Repositories

Repositories are responsible for handling data access, such as connecting to databases and performing read and write operations.

Models

Models define the object form of data, such as the data required for HTTP requests and responses, or the data formats needed for internal conversions. To map a model directly to an SQL type database using JPA, annotate with @Entity, @Table, and @Column as shown below:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "email")
    private String email;

    // getter and setter methods...
}

Filters

Filters in Spring Boot act as middleware for HTTP requests, intercepting HTTP request and response information for processing, such as adding logs, performing security checks, and handling encryption/decryption tasks.

To create a filter, simply extend OncePerRequestFilter and override the doFilterInternal method.

After completing the filter code, it needs to be registered with Spring using the configure method.

@Configuration

Use @Configuration to define the filter as a @Bean for injection into the Dependency Injection Container. Spring Boot searches for the Filter interface in the DI Container and calls it when receiving an HTTP request. The Filter interface is defined as follows:

package javax.servlet;
import java.io.IOException;

public interface Filter {
    void init(FilterConfig filterConfig) throws ServletException;
    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;
    void destroy();
}

Configure File: application.properties

After executing mvn package, the application.properties file is copied to the target/classes directory. application.properties can be used to store data that varies depending on the installation environment, such as database connection locations.

Dockerfile

Create a Docker Image:

docker build -t try-spring-boot .

When executed repeatedly, the old try-spring-boot image is not deleted but is renamed to <none>. Use the following commands to delete these unused <none> images:

docker image prune -f
# Or chain with the previous build command
docker build -t try-spring-boot . && docker image prune -f

Run the container:

docker run -d --name try-spring-boot -p 8080:8080 try-spring-boot

To view the logs of a running container, use the following commands:

docker logs try-spring-boot

# Or continuously output logs until Ctrl-C is pressed
docker logs try-spring-boot -f

Stop the container:

docker stop try-spring-boot

Open the web pages:

Connecting to MongoDB

First, we can try running two containers, one for MongoDB and the other for mongosh. We can connect and access data through the assigned Docker network. The following example will create and enter the test database using the mongo shell.

docker network create try-spring-boot-network
docker run --name try-spring-boot-mongo --rm --network try-spring-boot-network -v ${pwd}/temp-db-storage:/data/db -d mongo
docker run --name try-spring-boot-mongo-sh --rm --network try-spring-boot-network -it mongo mongosh --host try-spring-boot-mongo test

In the above commands, the second command sets the host name to the container name by default when the --hostname parameter is not specified. Therefore, the shell can connect to MongoDB through this host name. However, to connect to the container from the local machine, you still need to use localhost. To exit the mongo shell, enter .exit.

If you want to set the username and password through environment variables, you can use the following commands:

docker network create try-spring-boot-network

docker run --name try-spring-boot-mongo --rm --network try-spring-boot-network -v ${pwd}/temp-db-storage:/data/db -d -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=example mongo

docker run --name try-spring-boot-mongo-sh --rm --network try-spring-boot-network -it mongo /bin/bash

# After entering try-spring-boot-mongo-sh, enter the following command to start mongosh
mongosh --host try-spring-boot-mongo --username root --password example --authenticationDatabase admin

To connect to the above-created mongo in the dev container, you need to specify the same network in ./devcontainer/devcontainer.json.

{
	"name": "Java",
	"image": "mcr.microsoft.com/devcontainers/java:0-17",
  // Add the dev container to the try-spring-boot-network
	"runArgs": [
		"--network=try-spring-boot-network"
	],

	"features": {
		"ghcr.io/devcontainers/features/java:1": {
			"version": "none",
			"installMaven": "true",
			"installGradle": "false"
		}
	}
}

Also, modify application.properties and vscode launch.json to configure the connection.

spring.data.mongodb.uri=mongodb://${MONGO_USERNAME:root}:${MONGO_PASSWORD:example}@${MONGO_HOST:mongo}:${MONGO_PORT:27017}/${MONGO_DATABASE:test}?authSource=${MONGO_AUTH_SOURCE:admin}&authMechanism=${MONGO_AUTHMECHANISM:SCRAM-SHA-1}
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "BackendApiApplication",
            "request": "launch",
            "mainClass": "beginning.example.backendapi.BackendApiApplication",
            "projectName": "backend-api",
            "env": {
                "MONGO_USERNAME": "root",
                "MONGO_PASSWORD": "example",
                "MONGO_HOST": "try-spring-boot-mongo",
                "MONGO_PORT": "27017",
                "MONGO_DATABASE": "test",
                "MONGO_AUTH_SOURCE": "admin",
                "MONGO_AUTHMECHANISM": "SCRAM-SHA-1"
            }
        }
    ]
}

Using docker-compose is a more convenient choice for running multiple containers simultaneously. The following method can be used to start the Java program as well.

version: '3.1'

services:

  mongo:
    image: mongo
    container_name: try-spring-boot-mongo
    restart: always
    volumes:
      - ${PWD}/temp-db-storage:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example
    networks:
      - try-spring-boot-network

  mongo-express:
    image: mongo-express
    container_name: try-spring-boot-mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: example
      ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/
    networks:
      - try-spring-boot-network

  try-spring-boot:
    image: try-spring-boot
    container_name: try-spring-boot
    ports:
      - "8080:8080"
    environment:
      MONGO_USERNAME: root,
      MONGO_PASSWORD": example,
      MONGO_HOST: try-spring-boot-mongo,
      MONGO_PORT: 27017,
      MONGO_DATABASE: test,
      MONGO_AUTH_SOURCE: admin,
      MONGO_AUTHMECHANISM: SCRAM-SHA-1
    networks:
      - try-spring-boot-network      

networks:
  try-spring-boot-network:
    driver: bridge

The above yaml can be started or stopped using the following commands:

docker-compose up -d
docker-compose down

By using the provided docker-compose.yml, you can run MongoDB, Mongo Express, and your Spring Boot application simultaneously. This setup simplifies managing and connecting multiple containers, making development and testing more efficient.

Remember to modify your Spring Boot application.properties and your VSCode launch.json accordingly to ensure proper connection to the MongoDB instance.

Once everything is set up, you can test your Spring Boot application’s connection to MongoDB, perform database operations, and build your application as needed.

Setting Up a DevContainer Debug Environment

To set up a DevContainer testing environment for debugging within DevContainer, you can refer to the PowerShell script setup-mongo-container.ps1 located in the root directory of the project. Also, make sure to configure the env information in the .vscode launch.json file accordingly.

The contents of setup-mongo-container.ps1 are as follows:

# 1. Check if the directory does not exist, then create it
if (!(Test-Path -Path .\temp-db-storage)) {
    New-Item -ItemType Directory -Path .\temp-db-storage
}

# 2. Check if the try-spring-boot-network does not exist, then create it
$networkExists = docker network ls --filter name=try-spring-boot-network --format "{{.Name}}" -q
if (!$networkExists) {
    docker network create try-spring-boot-network
}

# 3. Check if the container exists, stop and remove it if it does, then run the new container
$containerExists = docker container ls -a --filter name=try-spring-boot-mongo --format "{{.Names}}" -q
if ($containerExists) {
    docker container stop try-spring-boot-mongo
    docker container rm try-spring-boot-mongo
}

docker run --name try-spring-boot-mongo --rm --network try-spring-boot-network -v ${pwd}/temp-db-storage:/data/db -d -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=example mongo

This PowerShell script performs the following steps:

  1. Creates a temp-db-storage directory if it doesn’t already exist.
  2. Creates a try-spring-boot-network Docker network if it doesn’t already exist.
  3. Checks for the existence of a try-spring-boot-mongo container. If it exists, the script stops and removes it before running a new container with the same name.

By executing this script, you can easily set up the testing environment for debugging within DevContainer. This will allow you to create and manage the necessary resources (such as the Docker network and container) for your Spring Boot and MongoDB integration.

Once you’ve set up the testing environment, you can proceed with debugging and developing your application inside the DevContainer environment.

Friday, January 27, 2023

Install JDK

Install JDK

Establishing a JDK development environment is often confusing for those new to Java.
OpenJDK is only the open source code, and many distributions release its binary. When installing JDK on Windows, you must consider three points: JDK version, distribution, and setting environment variables.

JDK Version

Detailed information on each version of the JDK can be found on Wikipedia: Java version history . But usually, we only focus on the LTS (Long-term support) version. The following lists the three main LTS version numbers:

Ver. Date Brief
8 2014-03 Lambdas
Spring 5.3.x & Spring Boot 2.x
11 2018-09 New HTTP Client
Spring 5.3.x & Spring Boot 2.x
17 2021-09 Sealed Classes
Spring Framework 6 & Spring Boot 3

Distributions

Install BellSoft Liberica JDK version 17

In Spring Quickstart Guide official website, it is recommended to use BellSoft Liberica JDK version 17. When entering the BellSoft website to download the SDK, you will find that various versions of JDK are provided. The following examples will use JDK 17 LTS to demonstrate. The downloaded file is in .msi format, so it is easy to follow the steps to complete the installation.

Set windows Environment Variables

If you have not installed other versions of JDK in your Windows environment, the BellSoft installer will automatically add the JAVA_HOME variable and Path to the Windows environment variables. The default information is as follows:

Var. Value
JAVA_HOME C:\Program Files\BellSoft\LibericaJDK-17\
Path C:\Program Files\BellSoft\LibericaJDK-17\bin\

After the installation is complete, open PowerShell and enter the following commands to check the output to make sure whether the installation was successful:

> java --version
openjdk 17.0.6 2023-01-17 LTS
OpenJDK Runtime Environment (build 17.0.6+10-LTS)
OpenJDK 64-Bit Server VM (build 17.0.6+10-LTS, mixed mode, sharing)
> javac --version
javac 17.0.6

Create a “Hello World!” Program

Use spring initializr to create a project quickly. You can set the options through the UI provided by spring initializr and download the project, or directly in the command line of vscode (Ctrl+Shift+P), search for “spring initializr”. Follow the steps to create a project.

In the src\main\java\com\example\demo directory of the project, open DemoApplication.java, and refer to the following example to modify the content:

package  com.example.demo;

import  org.springframework.boot.SpringApplication;
import  org.springframework.boot.autoconfigure.SpringBootApplication;
import  org.springframework.web.bind.annotation.GetMapping;
import  org.springframework.web.bind.annotation.RequestParam;
import  org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public  class  DemoApplication {
	public  static  void  main(String[] args) {
	SpringApplication.run(DemoApplication.class, args);
	}
	
	@GetMapping("/hello")
	public  String  hello(@RequestParam(value = "name", defaultValue = "World") String  name) {
		return  String.format("Hello %s!", name);
	}
}

Using terminal (Ctrl+`) and enter:

./mvnw spring-boot:run

Open http://localhost:8080/hello with a browser you will see the Hello World! webpage.


參考資料:


Create Your Docker Image

Create Your Docker Image

The article is described in the following scenarios:

  1. Get the Nginx Image from Docker Registry (Container Registry)
  2. Execute the Container and add/change files
  3. Return to the background process and check the status
  4. Build the new Image, and
  5. Finally, upload to the Docker Registry

Use Nginx as a Web Server

  1. Get nginx image from Docker Hub

    docker pull nginx
    
  2. Run nginx as a container with the name webserver

    docker run -d -p 8080:80 --name webserver nginx

    Options Description
    -d --detch, Run container in background
    -p Publish all exposed ports to the port,
    format host-port:container-port
    --name Assign a name to the container
    nginx Docker image or ID

    After execution, enter localhost:8080 in your host browser and see the “Welcome to nginx!” web page.

  3. Stop, start and restart the container

    docker stop webserver
    docker start webserver
    docker restart webserver
    
  4. Make sure that the container is in the execution, then type the following command to enter the shell environment

    docker exec -it webserver sh
    
    Options Description
    -i --interactive, Keep STDIN open even if not attached
    -t --tty, Allocate a pseudo-TTY

    The default home page of Nginx is located at /usr/share/nginx/html/index.html; you can use the following command to confirm it.

    # cat /usr/share/nginx/html/index.html

    Enter exit to leave the terminal and return to PowerShell.

  5. Copy the file to replace the default web page with a simple Hello World.

    <!DOCTYPE  html>
    <html>
    <head>
    	<title>Hello World Sample</title>
    </head>
    <body>
    	Hello World!
    </body>
    </html>
    

    Overwrite the container’s homepage with the cp command.

    docker cp ./index.html \
      webserver:/usr/share/nginx/html
    

    Enter localhost:8080 in the browser, and you can see that the homepage has been updated.

  6. Create a new image
    Use docker commit to save the container as a new image.

    docker commit webserver \
      <docker_hub_account> \
      /hello_world_nginx:1.0
    
  7. Stop the container and remove it.

    docker stop webserver
    docker rm webserver
    
  8. Run the newly docker image, and test in the browser.

    docker run -d -p 8080:80 \
      --name webserver \
      <docker_hub_account>\
      /hello_world_nginx:1.0
    
  9. Login to docker hub and upload the new docker image.

    docker login
    
    docker push \
      <docker_hub_account>\
      /hello_world_nginx:1.0
    

    After completion, you can see the new docker image on the docker hub web page.


Reference:
How to Create a Docker Image From a Container


GCP Artifact Registry

With a simple example, step by step, push Docker Image to GCP Artifact Registry.

Artifact Registry improves and extends upon the existing capabilities of Container Registry, such as customer-managed encryption keys, VPC-SC support, Pub/Sub notifications, and more, providing a foundation for major upgrades in security, scalability, and control.

The sample is running in Windows 11 PowerShell 7.3.1.

GCP Push and pull images

Pre-work

  1. Create a GCP project (ex. artifact-registry-microsystem).
  2. Docker installed on the local machine.

Google Cloud CLI Installer

You can refer to the following webpage if you have not installed gcloud CLI: Install the gcloud CLI.

After installation, you will be asked to log in and choose a default project name. Once done, you can enter the gcloud command in PowerShell.

Create Repository

Select the GCP Project you want to join, and add Artifact Registry. The relevant setting options are as follows:

  • Name: quickstart-docker-repo (Repository name, you can set it yourself)
  • Format: Docker
  • Location Type: Region
  • Region: us-central1

Setting Auth

Executing the following commands will modify the contents of the docker configuration:

gcloud auth configure-docker \
  us-central1-docker.pkg.dev

Check the docker configuration, and you will find that the credHelpers block has been added. Execute the following commands:

cat $env:UserProfile\.docker\config.json

The results are as follows:

{
"credsStore": "desktop",
"credHelpers": {
  "us-central1-docker.pkg.dev": "gcloud"
  }
}

Pull Docker Image

Next, you can create your own or get a Docker Image from Docker Hub:

docker pull nginx

Tag Docker Image

Before pushing the docker image, add a tag to the docker image with the hostname and repository name.

The tag format is: <hostname>/<project-name>/<repository-name>/<image-name>:<tag>

docker tag nginx \
  us-central1-docker.pkg.dev \
  /artifact-registry-microsystex \
  /quickstart-docker-repo \
  /nginx-image:tag1
  • us-central1: the region of the repository host
  • docker.pkg.dev: adding this suffix after the region will be the hostname
  • artifact-registry-microsystex: GCP Project ID, this is the project name you can create by yourself
  • nginx-image: Docker image name

Push Docker Image

Finally, Docker can be pushed to a private registry:

docker push 
  us-central1-docker.pkg.dev \
  /artifact-registry-microsystex \
  /quickstart-docker-repo \
  /nginx-image:tag1

References:
Artifact Registry: the next generation of Container Registry


Publish Blogger From StackEdit With Markdown

You can publish your Google Blogger from StackEdit with Markdown Language. It is more convenient than writing an article in the Blogger editor.

Selects Styled HTML for the Template when publishing; otherwise, the content of the Code Block will exceed the screen.

Remember to set those in file properties if you do want a specific date or add tags in this Blogger.

Deploying Vue & .NET with Google OAuth on GCP Cloud Run

Deploying Vue & .NET with Google OAuth on GCP Cloud Run Deploying Vue & .NET with Google OAuth on GCP Cloud Run...