diff --git a/cmd/gotk/bootstrap.go b/cmd/gotk/bootstrap.go
index 33b2d18069e76a5b90e14c85d13aabd536dd79dc..c68261aa805f0d499b9dc8ec6e7b39628f375f8a 100644
--- a/cmd/gotk/bootstrap.go
+++ b/cmd/gotk/bootstrap.go
@@ -23,7 +23,6 @@ import (
 	"os"
 	"path"
 	"path/filepath"
-	"sigs.k8s.io/yaml"
 	"strings"
 	"time"
 
@@ -33,6 +32,7 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/wait"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/yaml"
 
 	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
 	sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
@@ -49,6 +49,7 @@ var (
 	bootstrapComponents      []string
 	bootstrapRegistry        string
 	bootstrapImagePullSecret string
+	bootstrapArch            string
 )
 
 const (
@@ -67,6 +68,8 @@ func init() {
 		"container registry where the toolkit images are published")
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapImagePullSecret, "image-pull-secret", "",
 		"Kubernetes secret name used for pulling the toolkit images from a private registry")
+	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArch, "arch", "amd64",
+		"arch can be amd64 or arm64")
 	rootCmd.AddCommand(bootstrapCmd)
 }
 
@@ -78,7 +81,7 @@ func generateInstallManifests(targetPath, namespace, tmpDir string) (string, err
 		return "", fmt.Errorf("generating manifests failed: %w", err)
 	}
 
-	if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, bootstrapRegistry, bootstrapImagePullSecret, gotkDir); err != nil {
+	if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, bootstrapRegistry, bootstrapImagePullSecret, bootstrapArch, gotkDir); err != nil {
 		return "", fmt.Errorf("generating manifests failed: %w", err)
 	}
 
diff --git a/cmd/gotk/bootstrap_github.go b/cmd/gotk/bootstrap_github.go
index cba98cde8dda7c84b9a5e15859d82dd5c59a4bc1..bd8b83ee2214cbe844ce22b36cc2356999eeea2e 100644
--- a/cmd/gotk/bootstrap_github.go
+++ b/cmd/gotk/bootstrap_github.go
@@ -93,6 +93,10 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
 		return fmt.Errorf("%s environment variable not found", git.GitHubTokenName)
 	}
 
+	if !utils.containsItemString(supportedArch, bootstrapArch) {
+		return fmt.Errorf("arch %s is not supported, can be %v", bootstrapArch, supportedArch)
+	}
+
 	repository, err := git.NewRepository(ghRepository, ghOwner, ghHostname, ghToken, "gotk", ghOwner+"@users.noreply.github.com")
 	if err != nil {
 		return err
diff --git a/cmd/gotk/bootstrap_gitlab.go b/cmd/gotk/bootstrap_gitlab.go
index 7043c786e1a13865d403827c6cafeb090ddde575..cf2c8c4ff868b1687513166bc77c390979b81e8c 100644
--- a/cmd/gotk/bootstrap_gitlab.go
+++ b/cmd/gotk/bootstrap_gitlab.go
@@ -86,6 +86,10 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
 		return fmt.Errorf("%s environment variable not found", git.GitLabTokenName)
 	}
 
+	if !utils.containsItemString(supportedArch, bootstrapArch) {
+		return fmt.Errorf("arch %s is not supported, can be %v", bootstrapArch, supportedArch)
+	}
+
 	repository, err := git.NewRepository(glRepository, glOwner, glHostname, glToken, "gotk", glOwner+"@users.noreply.gitlab.com")
 	if err != nil {
 		return err
diff --git a/cmd/gotk/install.go b/cmd/gotk/install.go
index fe1761158a00118d2b241fd390d690c6b92c74d4..2069609d61f35af96cab1ded0cd964669a8762b9 100644
--- a/cmd/gotk/install.go
+++ b/cmd/gotk/install.go
@@ -19,7 +19,6 @@ package main
 import (
 	"context"
 	"fmt"
-	"github.com/fluxcd/pkg/untar"
 	"io/ioutil"
 	"net/http"
 	"os"
@@ -31,6 +30,8 @@ import (
 	"github.com/spf13/cobra"
 	"sigs.k8s.io/kustomize/api/filesys"
 	"sigs.k8s.io/kustomize/api/krusty"
+
+	"github.com/fluxcd/pkg/untar"
 )
 
 var installCmd = &cobra.Command{
@@ -61,6 +62,7 @@ var (
 	installComponents      []string
 	installRegistry        string
 	installImagePullSecret string
+	installArch            string
 )
 
 func init() {
@@ -78,10 +80,16 @@ func init() {
 		"container registry where the toolkit images are published")
 	installCmd.Flags().StringVar(&installImagePullSecret, "image-pull-secret", "",
 		"Kubernetes secret name used for pulling the toolkit images from a private registry")
+	installCmd.Flags().StringVar(&installArch, "arch", "amd64",
+		"arch can be amd64 or arm64")
 	rootCmd.AddCommand(installCmd)
 }
 
 func installCmdRun(cmd *cobra.Command, args []string) error {
+	if !utils.containsItemString(supportedArch, installArch) {
+		return fmt.Errorf("arch %s is not supported, can be %v", installArch, supportedArch)
+	}
+
 	ctx, cancel := context.WithTimeout(context.Background(), timeout)
 	defer cancel()
 
@@ -103,7 +111,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
 		logger.Generatef("generating manifests")
 	}
 	if kustomizePath == "" {
-		err = genInstallManifests(installVersion, namespace, installComponents, installRegistry, installImagePullSecret, tmpDir)
+		err = genInstallManifests(installVersion, namespace, installComponents, installRegistry, installImagePullSecret, installArch, tmpDir)
 		if err != nil {
 			return fmt.Errorf("install failed: %w", err)
 		}
@@ -192,6 +200,7 @@ fieldSpecs:
 var kustomizationTmpl = `---
 {{- $eventsAddr := .EventsAddr }}
 {{- $registry := .Registry }}
+{{- $arch := .Arch }}
 apiVersion: kustomize.config.k8s.io/v1beta1
 kind: Kustomization
 namespace: {{.Namespace}}
@@ -231,7 +240,11 @@ patchesJson6902:
 images:
 {{- range $i, $component := .Components }}
   - name: fluxcd/{{$component}}
+{{- if eq $arch "amd64" }}
     newName: {{$registry}}/{{$component}}
+{{- else }}
+    newName: {{$registry}}/{{$component}}-{{$arch}}
+{{- end }}
 {{- end }}
 {{- end }}
 `
@@ -253,7 +266,7 @@ spec:
   template:
     spec:
       nodeSelector:
-        kubernetes.io/arch: amd64
+        kubernetes.io/arch: {{.Arch}}
         kubernetes.io/os: linux
 {{- if .ImagePullSecret }}
       imagePullSecrets:
@@ -295,7 +308,7 @@ func downloadManifests(version string, tmpDir string) error {
 	return nil
 }
 
-func genInstallManifests(version string, namespace string, components []string, registry, imagePullSecret, tmpDir string) error {
+func genInstallManifests(version string, namespace string, components []string, registry, imagePullSecret, arch, tmpDir string) error {
 	eventsAddr := ""
 	if utils.containsItemString(components, defaultNotification) {
 		eventsAddr = fmt.Sprintf("http://%s/", defaultNotification)
@@ -308,6 +321,7 @@ func genInstallManifests(version string, namespace string, components []string,
 		EventsAddr      string
 		Registry        string
 		ImagePullSecret string
+		Arch            string
 	}{
 		Version:         version,
 		Namespace:       namespace,
@@ -315,6 +329,7 @@ func genInstallManifests(version string, namespace string, components []string,
 		EventsAddr:      eventsAddr,
 		Registry:        registry,
 		ImagePullSecret: imagePullSecret,
+		Arch:            arch,
 	}
 
 	if err := downloadManifests(version, tmpDir); err != nil {
diff --git a/cmd/gotk/main.go b/cmd/gotk/main.go
index 8ba5a45c37a61ab975643740a2251d285952c027..cad7015be8f005617752348260728d711b912fce 100644
--- a/cmd/gotk/main.go
+++ b/cmd/gotk/main.go
@@ -108,6 +108,7 @@ var (
 	defaultVersion      = "latest"
 	defaultNamespace    = "gitops-system"
 	defaultNotification = "notification-controller"
+	supportedArch       = []string{"arm64", "amd64"}
 )
 
 func init() {
diff --git a/docs/cmd/gotk_bootstrap.md b/docs/cmd/gotk_bootstrap.md
index aaa3f81ced001050f844d0986590a11c5ca3eabf..e3cf9bfab1f1eff071e48fe3c7a8b56dac93df41 100644
--- a/docs/cmd/gotk_bootstrap.md
+++ b/docs/cmd/gotk_bootstrap.md
@@ -9,6 +9,7 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
 ### Options
 
 ```
+      --arch string                arch can be amd64 or arm64 (default "amd64")
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
   -h, --help                       help for bootstrap
       --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
diff --git a/docs/cmd/gotk_bootstrap_github.md b/docs/cmd/gotk_bootstrap_github.md
index 1162a0d1410e96d641796de6d6eb58af4ab6279c..947adae9c7c12692434a58c673cafa48a8a3b9d2 100644
--- a/docs/cmd/gotk_bootstrap_github.md
+++ b/docs/cmd/gotk_bootstrap_github.md
@@ -54,6 +54,7 @@ gotk bootstrap github [flags]
 ### Options inherited from parent commands
 
 ```
+      --arch string                arch can be amd64 or arm64 (default "amd64")
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
       --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
       --kubeconfig string          path to the kubeconfig file (default "~/.kube/config")
diff --git a/docs/cmd/gotk_bootstrap_gitlab.md b/docs/cmd/gotk_bootstrap_gitlab.md
index dda38ac1bebdc0dcae35a89587dae93caa31883c..5b7d716589855e8e126bc33f6fa7914d6f1021ec 100644
--- a/docs/cmd/gotk_bootstrap_gitlab.md
+++ b/docs/cmd/gotk_bootstrap_gitlab.md
@@ -51,6 +51,7 @@ gotk bootstrap gitlab [flags]
 ### Options inherited from parent commands
 
 ```
+      --arch string                arch can be amd64 or arm64 (default "amd64")
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
       --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
       --kubeconfig string          path to the kubeconfig file (default "~/.kube/config")
diff --git a/docs/cmd/gotk_install.md b/docs/cmd/gotk_install.md
index a8096fe5431f5e500ee924e18f4b0738fe1c0651..16f638785cdac323c8c86a85a1163d42ae1a131b 100644
--- a/docs/cmd/gotk_install.md
+++ b/docs/cmd/gotk_install.md
@@ -31,6 +31,7 @@ gotk install [flags]
 ### Options
 
 ```
+      --arch string                arch can be amd64 or arm64 (default "amd64")
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
       --dry-run                    only print the object that would be applied
       --export                     write the install manifests to stdout and exit