1376 words
7 minutes
Setting Up ArgoCD with NGINX Ingress on a Bare-Metal Kubernetes Cluster

This guide walks you through setting up ArgoCD — a declarative, GitOps-based continuous delivery tool — on a bare-metal Kubernetes cluster. By the end, you’ll have ArgoCD fully accessible through a web browser via an NGINX Ingress Controller, and you’ll deploy sample applications using both the CLI and the Web UI.

Note: This guide assumes you already have a running Kubernetes cluster (e.g., set up with kubeadm). If you don’t have one yet, check out my previous post on Kubernetes Single-Node Setup.


Table of Contents#

  1. Installing ArgoCD
  2. Setting Up NGINX Ingress Controller
  3. Creating an Ingress for ArgoCD
  4. Installing the ArgoCD CLI
  5. Initial Login and Password Setup
  6. Accessing the ArgoCD Web UI
  7. Tuning the Refresh Interval
  8. Deploying an Application via CLI
  9. Deploying an Application via Web UI
  10. ArgoCD CLI Tips

1. Installing ArgoCD#

1.1 Download the Installation Manifest#

First, download the official ArgoCD installation manifest:

Terminal window
wget https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

1.2 Configure a Custom Root Path (Optional)#

If you want to access ArgoCD through a sub-path (e.g., http://<your-ip>/argocd-lab) instead of using a dedicated domain, you’ll need to modify the argocd-server Deployment in the downloaded install.yaml.

Find the Deployment resource named argocd-server and add the --rootpath, --basehref, and --insecure arguments:

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/name: argocd-server
app.kubernetes.io/part-of: argocd
name: argocd-server
...
# Add these under spec.template.spec.containers[0].args
spec:
containers:
- args:
- /usr/local/bin/argocd-server
- --staticassets
- /shared/app
- --insecure
- --rootpath
- /argocd-lab
- --basehref
- /argocd-lab

Note: The path /argocd-lab is used in this guide as an example to avoid conflicts with ArgoCD’s default /argocd path. Feel free to change it to whatever path suits your needs — just make sure it stays consistent across your Ingress configuration and CLI login commands. If you’re using a dedicated domain or want ArgoCD on the root URL, you can skip the --rootpath and --basehref flags entirely.

1.3 Create the Namespace and Deploy#

Create the argocd namespace and apply the manifest:

Terminal window
kubectl create namespace argocd
Terminal window
kubectl apply -f install.yaml -n argocd

2. Setting Up NGINX Ingress Controller#

A Note on NGINX Ingress: We are using NGINX Ingress Controller here because it is very easy to set up for demonstration purposes. However, if you are planning to deploy this in a production environment, you should consider alternatives that provide better long-term security support and active maintenance (such as Traefik, HAProxy, Contour, etc.).

Important for bare-metal/on-prem clusters: Clusters bootstrapped with kubeadm don’t come with a built-in Ingress Controller. Without one, any Ingress resource you create won’t work — kubectl get ingress will show no ADDRESS, and you’ll get connection refused errors when trying to access services.

2.1 Check If an Ingress Controller Exists#

Terminal window
kubectl get ingressclass

If the output is No resources found, you need to install one.

2.2 Install NGINX Ingress Controller#

Since we’re on bare-metal (no cloud LoadBalancer), install the NGINX Ingress Controller using the bare-metal manifest:

Terminal window
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/baremetal/deploy.yaml

2.3 Enable Host Networking#

Edit the ingress-nginx-controller Deployment to enable hostNetwork, which allows the controller to bind directly to port 80/443 on the node — no external LoadBalancer or MetalLB required:

Terminal window
kubectl edit deployment ingress-nginx-controller -n ingress-nginx

Add hostNetwork: true under spec.template.spec, at the same level as containers:

spec:
template:
spec:
hostNetwork: true
containers:
- name: controller
...

2.4 Verify the Installation#

Wait a moment, then confirm the controller pod is running and the IngressClass is registered:

Terminal window
kubectl get pods -n ingress-nginx
Terminal window
kubectl get ingressclass

Expected output:

NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 30s

3. Creating an Ingress for ArgoCD#

Create an ingress.yaml file to expose ArgoCD through the /argocd-lab path:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /argocd-lab
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80

Apply it:

Terminal window
kubectl apply -f ingress.yaml

4. Installing the ArgoCD CLI#

Download and install the ArgoCD CLI binary:

Terminal window
curl -SL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
Terminal window
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd

Clean up the downloaded file:

Terminal window
rm argocd-linux-amd64

Verify the installation:

Terminal window
argocd version

Expected output:

argocd: v3.4.4+443415b
BuildDate: 2026-06-18T09:15:00Z
GitCommit: 443415b5527ac55366e0760c93ef0e1abd0cf273
GitTreeState: clean
GoVersion: go1.26.0
Compiler: gc
Platform: linux/amd64

Note: You may see a fatal message about the server address being unspecified — this is normal before logging in.


5. Initial Login and Password Setup#

5.1 Retrieve the Default Admin Password#

ArgoCD generates a random initial password for the admin account during installation:

Terminal window
argocd admin initial-password -n argocd

Example output:

[PASSWORD]
This password must be only used for first time login. We strongly recommend
you update the password using `argocd account update-password`.

5.2 Log In via CLI#

Log in using the generated password. Replace <your-ip> with your node’s IP address:

Terminal window
argocd login <your-ip>:80 --grpc-web-root-path=/argocd-lab --plaintext --insecure

When prompted, enter admin as the username and the password from the previous step.

5.3 Change the Admin Password#

For security, update the default password immediately:

Terminal window
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 '<your-ip>:80/argocd-lab' updated

6. Accessing the ArgoCD Web UI#

Open your browser and navigate to:

http://<your-ip>/argocd-lab

Log in with the admin username and the password you just set.

ArgoCD Login Page


7. Tuning the Refresh Interval#

By default, ArgoCD polls your Git repositories every 3 minutes to check for changes. If you want faster feedback (e.g., during development), you can lower this interval.

Create a config.yaml file:

apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
timeout.reconciliation: 20s

Apply the configuration:

Terminal window
kubectl apply -f config.yaml

Verify the change:

Terminal window
kubectl describe configmap -n argocd argocd-cm

Restart the repo server to pick up the new setting:

Terminal window
kubectl -n argocd rollout restart deploy argocd-repo-server

Tip: A 20-second interval is great for development and testing, but for production environments you may want to keep it at the default 3 minutes (or higher) to reduce load on both ArgoCD and your Git server.


8. Deploying an Application via CLI#

8.1 Create the Application#

Create a sample application called simple-deploy pointing to a Git repository:

Terminal window
argocd app create simple-deploy \
--repo https://github.com/maliqpotter/argo-simple-project.git \
--path simple-demo \
--dest-server https://kubernetes.default.svc \
--dest-namespace default
application 'simple-deploy' created

8.2 Check the Application Status#

Terminal window
argocd app get simple-deploy

The initial status will be OutOfSync because no Kubernetes resources have been created yet:

Name: argocd/simple-deploy
Project: default
Server: https://kubernetes.default.svc
Namespace: default
Source:
- Repo: https://github.com/maliqpotter/argo-simple-project.git
Path: simple-demo
Sync Status: OutOfSync from (1873ef1)
Health Status: Missing
GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
apps Deployment default simple-nginx OutOfSync Missing

8.3 Sync (Deploy) the Application#

Trigger a sync to deploy the application:

Terminal window
argocd app sync simple-deploy

Once the sync completes, verify the status:

Terminal window
argocd app get simple-deploy
Name: argocd/simple-deploy
Project: default
Server: https://kubernetes.default.svc
Namespace: default
Source:
- Repo: https://github.com/maliqpotter/argo-simple-project.git
Path: simple-demo
Sync Policy: Manual
Sync Status: Synced to (1873ef1)
Health Status: Healthy
GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
apps Deployment default simple-nginx Synced Healthy deployment.apps/simple-nginx created

8.4 Verify the Resources#

Check that the pods and deployment were created:

Terminal window
kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
simple-deploy-5d7468b6f8-75w68 1/1 Running 0 2m11s
simple-deploy-5d7468b6f8-mkkph 1/1 Running 0 2m11s
simple-deploy-5d7468b6f8-mkgdz 1/1 Running 0 2m11s
Terminal window
kubectl get deployment -n default
NAME READY UP-TO-DATE AVAILABLE AGE
simple-deploy 3/3 3 3 2m38s

9. Deploying an Application via Web UI#

In addition to the CLI, you can create and deploy applications directly from the ArgoCD dashboard.

9.1 Open the Dashboard#

After logging in, you’ll see the ArgoCD dashboard showing your existing applications (like the simple-deploy app we just created via CLI).

Click the + NEW APP button to create a new application.

ArgoCD Dashboard with NEW APP button highlighted

9.2 Fill in the General Settings#

Under the GENERAL section, configure:

  • Application Name: nginx-with-ingress
  • Project Name: default
  • Sync Policy: Manual (or Automatic if you want auto-sync)

ArgoCD New App - General Configuration

9.3 Configure the Source and Destination#

Under the SOURCE section:

  • Repository URL: https://github.com/maliqpotter/argo-simple-project.git
  • Revision: HEAD (or the specific branch you want, e.g., main)
  • Path: nginx-with-ingress

Under the DESTINATION section:

  • Cluster URL: https://kubernetes.default.svc
  • Namespace: default

Then click the CREATE button at the top of the form.

ArgoCD New App - Source and Destination Configuration

9.4 Sync the Application#

Once the nginx-with-ingress application appears on the dashboard with an OutOfSync status, click the SYNC button on the application card, then click SYNCHRONIZE to confirm.

ArgoCD Dashboard showing the Sync button

After the sync completes, the application status will change to Synced and Healthy. You can click into the application to see a visual map of all the Kubernetes resources that were created (Deployments, ReplicaSets, Pods, etc.).


10. ArgoCD CLI Tips#

10.1 Set Default Namespace#

Since ArgoCD is installed in the argocd namespace, you can set it as your default to avoid typing -n argocd on every command:

Option A — Set the kubectl context:

Terminal window
kubectl config set-context --current --namespace=argocd

Option B — Use an environment variable:

Terminal window
export ARGOCD_OPTS='--port-forward-namespace argocd'

10.2 Enable Bash Completion#

Speed up your CLI workflow with tab completion:

Terminal window
argocd completion bash | sudo tee /etc/bash_completion.d/argocd
Terminal window
source ~/.bashrc

References#


This guide is based on a real-world deployment. Adjust IPs, paths, and version numbers to match your own environment.

Setting Up ArgoCD with NGINX Ingress on a Bare-Metal Kubernetes Cluster
https://im-gatan.com/posts/argocd-setup-guide/
Author
Gatan
Published at
2026-06-21
License
CC BY-NC-SA 4.0