diff --git a/cmd/tk/bootstrap.go b/cmd/tk/bootstrap.go
index 9cc5261bae68e20436dfbb0b80d6521251b95034..e9595eb1fe34f8a86b39fa620c14cb1841920acb 100644
--- a/cmd/tk/bootstrap.go
+++ b/cmd/tk/bootstrap.go
@@ -45,8 +45,10 @@ var bootstrapCmd = &cobra.Command{
 }
 
 var (
-	bootstrapVersion    string
-	bootstrapComponents []string
+	bootstrapVersion         string
+	bootstrapComponents      []string
+	bootstrapRegistry        string
+	bootstrapImagePullSecret string
 )
 
 const (
@@ -61,7 +63,10 @@ func init() {
 		"toolkit version")
 	bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapComponents, "components", defaultComponents,
 		"list of components, accepts comma-separated values")
-
+	bootstrapCmd.PersistentFlags().StringVar(&bootstrapRegistry, "registry", "docker.io/fluxcd",
+		"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")
 	rootCmd.AddCommand(bootstrapCmd)
 }
 
@@ -73,7 +78,7 @@ func generateInstallManifests(targetPath, namespace, tmpDir string) (string, err
 		return "", fmt.Errorf("generating manifests failed: %w", err)
 	}
 
-	if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, tkDir); err != nil {
+	if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, bootstrapRegistry, bootstrapImagePullSecret, tkDir); err != nil {
 		return "", fmt.Errorf("generating manifests failed: %w", err)
 	}
 
diff --git a/cmd/tk/install.go b/cmd/tk/install.go
index 3ca3b282c7de2767c593bc87f3b2de2f2c5ac5f9..cdc164a7ddd7c1ffeeea83c8cbd73afea9ec40bd 100644
--- a/cmd/tk/install.go
+++ b/cmd/tk/install.go
@@ -54,11 +54,13 @@ If a previous version is installed, then an in-place upgrade will be performed.`
 }
 
 var (
-	installExport        bool
-	installDryRun        bool
-	installManifestsPath string
-	installVersion       string
-	installComponents    []string
+	installExport          bool
+	installDryRun          bool
+	installManifestsPath   string
+	installVersion         string
+	installComponents      []string
+	installRegistry        string
+	installImagePullSecret string
 )
 
 func init() {
@@ -70,8 +72,12 @@ func init() {
 		"toolkit version")
 	installCmd.Flags().StringSliceVar(&installComponents, "components", defaultComponents,
 		"list of components, accepts comma-separated values")
-	installCmd.Flags().StringVarP(&installManifestsPath, "manifests", "", "",
+	installCmd.Flags().StringVar(&installManifestsPath, "manifests", "",
 		"path to the manifest directory, dev only")
+	installCmd.Flags().StringVar(&installRegistry, "registry", "docker.io/fluxcd",
+		"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")
 	rootCmd.AddCommand(installCmd)
 }
 
@@ -97,7 +103,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
 		logger.Generatef("generating manifests")
 	}
 	if kustomizePath == "" {
-		err = genInstallManifests(installVersion, namespace, installComponents, tmpDir)
+		err = genInstallManifests(installVersion, namespace, installComponents, installRegistry, installImagePullSecret, tmpDir)
 		if err != nil {
 			return fmt.Errorf("install failed: %w", err)
 		}
@@ -185,6 +191,7 @@ fieldSpecs:
 
 var kustomizationTmpl = `---
 {{- $eventsAddr := .EventsAddr }}
+{{- $registry := .Registry }}
 apiVersion: kustomize.config.k8s.io/v1beta1
 kind: Kustomization
 namespace: {{.Namespace}}
@@ -206,19 +213,27 @@ patches:
     kind: Deployment
 
 patchesJson6902:
-{{- range $i, $v := .Components }}
-{{- if ne $v "notification-controller" }}
+{{- range $i, $component := .Components }}
+{{- if ne $component "notification-controller" }}
 - target:
     group: apps
     version: v1
     kind: Deployment
-    name: {{$v}}
+    name: {{$component}}
   patch: |-
     - op: replace
       path: /spec/template/spec/containers/0/args/0
       value: --events-addr={{$eventsAddr}}
 {{- end }}
 {{- end }}
+
+{{- if $registry }}
+images:
+{{- range $i, $component := .Components }}
+  - name: fluxcd/{{$component}}
+    newName: {{$registry}}/{{$component}}
+{{- end }}
+{{- end }}
 `
 
 var kustomizationRolesTmpl = `---
@@ -240,6 +255,10 @@ spec:
       nodeSelector:
         kubernetes.io/arch: amd64
         kubernetes.io/os: linux
+{{- if .ImagePullSecret }}
+      imagePullSecrets:
+       - name: {{.ImagePullSecret}}
+{{- end }}
 `
 
 func downloadManifests(version string, tmpDir string) error {
@@ -276,22 +295,26 @@ func downloadManifests(version string, tmpDir string) error {
 	return nil
 }
 
-func genInstallManifests(version string, namespace string, components []string, tmpDir string) error {
+func genInstallManifests(version string, namespace string, components []string, registry, imagePullSecret, tmpDir string) error {
 	eventsAddr := ""
 	if utils.containsItemString(components, defaultNotification) {
 		eventsAddr = fmt.Sprintf("http://%s/", defaultNotification)
 	}
 
 	model := struct {
-		Version    string
-		Namespace  string
-		Components []string
-		EventsAddr string
+		Version         string
+		Namespace       string
+		Components      []string
+		EventsAddr      string
+		Registry        string
+		ImagePullSecret string
 	}{
-		Version:    version,
-		Namespace:  namespace,
-		Components: components,
-		EventsAddr: eventsAddr,
+		Version:         version,
+		Namespace:       namespace,
+		Components:      components,
+		EventsAddr:      eventsAddr,
+		Registry:        registry,
+		ImagePullSecret: imagePullSecret,
 	}
 
 	if err := downloadManifests(version, tmpDir); err != nil {
diff --git a/docs/cmd/tk_bootstrap.md b/docs/cmd/tk_bootstrap.md
index 6ae349f18dd46f4636366def8df74cbeb3ce8893..163dd26fcf46af696ddce6489c84a177d74925d5 100644
--- a/docs/cmd/tk_bootstrap.md
+++ b/docs/cmd/tk_bootstrap.md
@@ -9,9 +9,11 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
 ### Options
 
 ```
-      --components strings   list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
-  -h, --help                 help for bootstrap
-  -v, --version string       toolkit version (default "latest")
+      --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
+      --registry string            container registry where the toolkit images are published (default "docker.io/fluxcd")
+  -v, --version string             toolkit version (default "latest")
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/tk_bootstrap_github.md b/docs/cmd/tk_bootstrap_github.md
index 3aa71ad630d233e693777e4d9e54d942c6605773..2a27cd4b324bff8eee656ec40ce5721d91c0d1d4 100644
--- a/docs/cmd/tk_bootstrap_github.md
+++ b/docs/cmd/tk_bootstrap_github.md
@@ -54,12 +54,14 @@ tk bootstrap github [flags]
 ### Options inherited from parent commands
 
 ```
-      --components strings   list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
-      --kubeconfig string    path to the kubeconfig file (default "~/.kube/config")
-      --namespace string     the namespace scope for this operation (default "gitops-system")
-      --timeout duration     timeout for this operation (default 5m0s)
-      --verbose              print generated objects
-  -v, --version string       toolkit version (default "latest")
+      --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")
+      --namespace string           the namespace scope for this operation (default "gitops-system")
+      --registry string            container registry where the toolkit images are published (default "docker.io/fluxcd")
+      --timeout duration           timeout for this operation (default 5m0s)
+      --verbose                    print generated objects
+  -v, --version string             toolkit version (default "latest")
 ```
 
 ### SEE ALSO
diff --git a/docs/cmd/tk_bootstrap_gitlab.md b/docs/cmd/tk_bootstrap_gitlab.md
index 0502838bca0c00d97dd1d515e6177138aed84b30..1a9fcf6c67c2fc4017f9611a1bcb60893941e56d 100644
--- a/docs/cmd/tk_bootstrap_gitlab.md
+++ b/docs/cmd/tk_bootstrap_gitlab.md
@@ -50,12 +50,14 @@ tk bootstrap gitlab [flags]
 ### Options inherited from parent commands
 
 ```
-      --components strings   list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
-      --kubeconfig string    path to the kubeconfig file (default "~/.kube/config")
-      --namespace string     the namespace scope for this operation (default "gitops-system")
-      --timeout duration     timeout for this operation (default 5m0s)
-      --verbose              print generated objects
-  -v, --version string       toolkit version (default "latest")
+      --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")
+      --namespace string           the namespace scope for this operation (default "gitops-system")
+      --registry string            container registry where the toolkit images are published (default "docker.io/fluxcd")
+      --timeout duration           timeout for this operation (default 5m0s)
+      --verbose                    print generated objects
+  -v, --version string             toolkit version (default "latest")
 ```
 
 ### SEE ALSO
diff --git a/docs/cmd/tk_install.md b/docs/cmd/tk_install.md
index d42c8aa7e7870d2c5e2707b858179a0dad27104c..36f196130eb4080d1c56bc4897d6458057fd309c 100644
--- a/docs/cmd/tk_install.md
+++ b/docs/cmd/tk_install.md
@@ -31,12 +31,14 @@ tk install [flags]
 ### Options
 
 ```
-      --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
-  -h, --help                 help for install
-      --manifests string     path to the manifest directory, dev only
-  -v, --version string       toolkit version (default "latest")
+      --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
+  -h, --help                       help for install
+      --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
+      --manifests string           path to the manifest directory, dev only
+      --registry string            container registry where the toolkit images are published (default "docker.io/fluxcd")
+  -v, --version string             toolkit version (default "latest")
 ```
 
 ### Options inherited from parent commands