ArgoCD on MiniKube on MacOS (Intel Version)

📣 If you have an M1/M2 Mac, see this post instead

What Is Argo CD?

Argo CD is a Kubernetes controller, responsible for continuously monitoring all running applications and comparing their live state to the desired state specified in the Git repository. It can automatically apply any change to the desired state in the Git repository to the target environment, ensuring the applications remain in sync. 

Argo CD UI

In short, it’s awesome! And we’re going to try it out on minikube on our Mac 🤟


To continue with the steps below, you need to:

Launch Minikube locally

Now that we’re all set, let’s get cooking by launching Minikube. If you don’t know it already, Minikube is a lightweight Kubernetes implementation that creates a VM on your local machine and deploys a simple cluster containing only one node. It is, also, awesome!

In a new Terminal window, run the following:

❯ minikube start --driver=hyperkit

Note: Using the hyperkit driver bypasses a known issue with the docker driver on MacOS should you decide to add (which we will) an ingress controller for your argocd deployment, defined here: docker: Ingress not exposed on MacOS · Issue #7332 · kubernetes/minikube

💡 If at any point you believe you messed up, you can always reset minikube with minikube delete

Install ArgoCD

❯ kubectl create namespace argocd
❯ kubectl apply -n argocd -f

This will create a new namespace, argocd, where ArgoCD services and application resources will live.

Make sure all argocd resources are up:

❯ kn argocd
Context "minikube" modified.
Active namespace is "argocd".

❯ kga
NAME                                                    READY   STATUS    RESTARTS       AGE
pod/argocd-application-controller-0                     1/1     Running   11 (19h ago)   26h
pod/argocd-applicationset-controller-7dd9d4b769-rwgvc   1/1     Running   0              26h
pod/argocd-dex-server-655f944db8-svvkq                  1/1     Running   0              26h
pod/argocd-notifications-controller-759b6bcc4d-wmdsl    1/1     Running   1 (20h ago)    26h
pod/argocd-redis-896595fb7-mhcx9                        1/1     Running   0              26h
pod/argocd-repo-server-856b477f86-s8qtz                 1/1     Running   8 (19h ago)    26h
pod/argocd-server-5bb99cbcb-dsbvz                       1/1     Running   0              31m

NAME                                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/argocd-applicationset-controller          ClusterIP   <none>        7000/TCP,8080/TCP            26h
service/argocd-dex-server                         ClusterIP    <none>        5556/TCP,5557/TCP,5558/TCP   26h
service/argocd-metrics                            ClusterIP     <none>        8082/TCP                     26h
service/argocd-notifications-controller-metrics   ClusterIP    <none>        9001/TCP                     26h
service/argocd-redis                              ClusterIP     <none>        6379/TCP                     26h
service/argocd-repo-server                        ClusterIP      <none>        8081/TCP,8084/TCP            26h
service/argocd-server                             ClusterIP     <none>        80/TCP,443/TCP               26h
service/argocd-server-metrics                     ClusterIP      <none>        8083/TCP                     26h

NAME                                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argocd-applicationset-controller   1/1     1            1           26h
deployment.apps/argocd-dex-server                  1/1     1            1           26h
deployment.apps/argocd-notifications-controller    1/1     1            1           26h
deployment.apps/argocd-redis                       1/1     1            1           26h
deployment.apps/argocd-repo-server                 1/1     1            1           26h
deployment.apps/argocd-server                      1/1     1            1           26h

NAME                                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/argocd-applicationset-controller-7dd9d4b769   1         1         1       26h
replicaset.apps/argocd-dex-server-655f944db8                  1         1         1       26h
replicaset.apps/argocd-notifications-controller-759b6bcc4d    1         1         1       26h
replicaset.apps/argocd-redis-896595fb7                        1         1         1       26h
replicaset.apps/argocd-repo-server-856b477f86                 1         1         1       26h
replicaset.apps/argocd-server-5674bcbc44                      0         0         0       26h
replicaset.apps/argocd-server-5bb99cbcb                       1         1         1       31m

NAME                                             READY   AGE
statefulset.apps/argocd-application-controller   1/1     26h

Note that the following commands are aliases:

  • kn – Stands for kubens, a sweet set of tools used to jump between contexts and namespaces on Kubernetes clusters
  • kga – Is aliased to kubectl get all
  • k is aliased to kubectl (you’ll see this on the next command)

Now let’s set up port forwarding in order to access the UI. We can see that the service argocd-server is using ports 80 and 443 – We will use the next command to connect to the API server without exposing the service:

❯ k port-forward svc/argocd-server 8080:443
Forwarding from -> 8080
Forwarding from [::1]:8080 -> 8080

Now if we browse to (or localhost:8080) we are presented with the ArgoCD UI. Hoorah! 🎉

To login, the default user in admin, but we still need to retrieve the password. To do so, launch a new Terminal tab or window (this is important: closing or interrupting our existing terminal session will cause us to lose our current connection to the web UI; all next steps until we setup the Ingress should be performed in this new Terminal window) and run:

❯ k get secret argocd-initial-admin-secret -o yaml
apiVersion: v1
  password: S05za0QtbnB3MmdmNU5mUQ==
kind: Secret
  creationTimestamp: "2022-05-31T10:20:12Z"
  name: argocd-initial-admin-secret
  namespace: argocd
  resourceVersion: "133179"
  uid: 956bf056-1285-4465-aa77-d8ac87f65d13
type: Opaque

Grab the password and decode it:

❯ echo S05za0QtbnB3MmdmNU5mUQ== | base64 --decode

⚠️  You should delete the argocd-initial-admin-secret from the Argo CD namespace once you changed the password. The secret serves no other purpose than to store the initially generated password in clear and can safely be deleted at any time. It will be re-created on demand by Argo CD if a new admin password must be re-generated.

Alternatively, we can run:

❯ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

Sweet, now we have the admin password and can proceed with changing it.

ArgoCD CLI Login

Now that we have the admin password, we are able to sign in to argocd from the terminal. However, we need to install the argocd cli first. To do so, run:

❯ brew install argocd

There. That simple.
Now let’s login in to argocd using the CLI and update the password:

❯ argocd login localhost:8080
WARNING: server certificate had error: x509: “Argo CD” certificate is not trusted. Proceed insecurely (y/n)? y
Username: admin
'admin:login' logged in successfully
Context 'localhost:8080' updated

❯ argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
Context 'localhost:8080' updated

Note that you need to enter your current password first (the one we identified in the steps above) before typing your new password twice.


So far, we have reached the ArgoCD UI by broswing to http://localhost:8080. However, this is not ideal.

An ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.

Here is a simple example where an Ingress sends all its traffic to one Service:


In short, instead of reaching the ArgoCD UI using localhost:8080, I would rather this behaves like a “normal” site, like -for example-

With that in mind, let’s enable the ingress addon for minikube first:

❯ minikube addons enable ingress

To create the ingress, create a new file named argocd-ingress.yaml with the following content:

kind: Ingress
  name: argocd
  namespace: argocd
  annotations: argocd-frontend-config
  - secretName: secret-yourdomain-com
  - host:
      - pathType: Prefix
        path: "/"
            name: argocd-server
              number: 80

Note, make sure to replace the host value above with a domain of your choice (ie It can be anything, the beauty is that you don’t even need a domain to make this work, as we will point it to the local minikube IP in the next steps below.

Next, apply it to the argocd namespace:

❯ kubectl apply -f argocd-ingress.yaml -n argocd

Now however, attempting to browse to will result in a ERR_TOO_MANY_REDIRECTS error.

ArgoCD handles TLS termination by itself and always redirects HTTP requests to HTTPS. The problem here is that the nginx ingress controller also handles TLS termination and communicates with the backend service with HTTP and the result is that the ArgoCD’s server always responds with a redirect to HTTPS which is the cause for the multiple redirects. More on this here.

The solution is to ensure that the service doesn’t handle TLS by passing the --insecure flag to the argocd-server deployment. Edit the deployment with the following command and then add the required flag:

❯ kubectl edit deployment argocd-server -n argocd 

      - name: argocd-server
        - argocd-server
        - --insecure         <-- Add this bit


Next, we need to figure out the IP address of our minikube node and create an entry in our /etc/hosts file that will point our domain ( in my case, in yours!) to our minikube node:

❯ minikube ip

This is my node’s IP, so I will point my argocd “domain” accordingly by adding the relevant line at the end of my /etc/hosts file:

You may now close the terminal where port forwarding is running and browse to your brand new local Argo CD instance using your preferred URL!


Buy Me A Coffee