Skip to content

parvvareshInfrastructure/go-app-chart

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Application with PostgreSQL on Kubernetes

A production-ready Kubernetes deployment for a Go backend application with PostgreSQL database. This project includes best practices such as StatefulSet for the database, readiness/liveness probes, resource limits, init container for database migrations, Horizontal Pod Autoscaler, and Ingress for external access. The structure follows Helm chart conventions, making it easy to package and manage with Helm in the future.

📁 Project Structure

go-app-chart/
├── templates/
│   ├── namespace.yaml
│   ├── secret.yaml
│   ├── configmap.yaml
│   ├── postgres-statefulset.yaml
│   ├── postgres-service.yaml
│   ├── backend-deployment.yaml
│   ├── backend-service.yaml
│   ├── ingress.yaml
│   └── hpa.yaml
└── README.md

All Kubernetes manifests are located in the templates/ directory. Although this is not yet a fully templated Helm chart, the layout is Helm‑compatible: you can easily add Chart.yaml and values.yaml to convert it into a reusable Helm chart.

🏗️ Architecture Overview

Internet
   │
   ▼
Ingress (go-ingress)
   │
   ▼
Service (go-service)
   │
   ▼
Deployment (go-backend) ── HPA (3-10 replicas)
   │                        │
   │                        │
   ▼                        │
PostgreSQL StatefulSet       │
   │                        │
   ▼                        │
PersistentVolume (10Gi) ────┘
  • Ingress: Routes external HTTP traffic to the backend service.
  • Backend Service: Internal ClusterIP service that load‑balances across Go application pods.
  • Backend Deployment: Runs the Go application with configured resource limits, probes, and an init container that waits for PostgreSQL and runs database migrations.
  • HorizontalPodAutoscaler (HPA): Automatically scales the backend pods between 3 and 10 replicas based on CPU utilization.
  • PostgreSQL StatefulSet: Runs a single PostgreSQL instance with persistent storage. Uses a headless service for stable network identity.
  • ConfigMap & Secret: Store non‑sensitive configuration (database name, user, host) and sensitive data (database password) respectively.

✅ Prerequisites

  • A running Kubernetes cluster (version 1.19+)
  • kubectl configured to communicate with your cluster
  • (Optional) helm if you plan to convert to a Helm chart
  • An Ingress controller (e.g., NGINX Ingress) installed in the cluster (for Ingress to work)

🚀 Deployment

1. Clone or create the project files

Place all the YAML manifests in a directory named go-app-chart/templates/. Ensure the file names match those listed above.

2. Apply the manifests in order

It is recommended to apply the resources in the following order to avoid race conditions:

# Create the namespace first
kubectl apply -f templates/namespace.yaml

# Create secrets and configmap (these don't depend on other resources)
kubectl apply -f templates/secret.yaml
kubectl apply -f templates/configmap.yaml

# Deploy PostgreSQL StatefulSet and its headless service
kubectl apply -f templates/postgres-statefulset.yaml
kubectl apply -f templates/postgres-service.yaml

# Wait for PostgreSQL to be ready (optional but recommended)
kubectl wait --for=condition=ready pod -l app=postgres -n go-app --timeout=120s

# Deploy the backend application
kubectl apply -f templates/backend-deployment.yaml
kubectl apply -f templates/backend-service.yaml

# Finally, create the Ingress and HPA
kubectl apply -f templates/ingress.yaml
kubectl apply -f templates/hpa.yaml

3. Verify the deployment

kubectl get all -n go-app

You should see the PostgreSQL pod, backend pods, services, and the HPA.

4. Access the application

If you have set up an Ingress controller and configured DNS (or used a local /etc/hosts entry for goapp.local), you can access the application at http://goapp.local.

⚙️ Configuration

ConfigMap (configmap.yaml)

The ConfigMap holds all non‑sensitive configuration:

Key Description Example Value
POSTGRES_DB Name of the database to create appdb
POSTGRES_USER PostgreSQL superuser postgres
DB_HOST Hostname of the PostgreSQL service postgres
DB_PORT Port of PostgreSQL 5432
DB_NAME Database name for the backend appdb
DB_USER Database user for the backend postgres

Secret (secret.yaml)

The Secret contains the PostgreSQL password. The value must be base64‑encoded:

echo -n 'YourStrongPassword' | base64

Replace the POSTGRES_PASSWORD field in secret.yaml with your encoded password.

Resource Limits

Resource requests and limits are set for both PostgreSQL and the Go backend. Adjust them in the respective manifests according to your application’s needs.

Horizontal Pod Autoscaling

The HPA is configured to scale the backend deployment between 3 and 10 replicas when CPU usage exceeds 70%. You can modify these values in hpa.yaml.

Ingress

The Ingress is configured for host goapp.local. Replace this with your actual domain and ensure your Ingress controller is properly set up. If you are using a different Ingress class, update ingressClassName accordingly.

🧹 Cleanup

To remove all resources created by this project:

kubectl delete namespace go-app

Note: This will delete the namespace and all resources inside it, including the persistent volume claim holding your database data. Make sure to back up any important data before deletion.

📦 Next Steps: Converting to a Helm Chart

The project is already structured like a Helm chart. To turn it into a fully functional Helm chart:

  1. Create a Chart.yaml file in the root directory:

    apiVersion: v2
    name: go-app
    description: A Go backend with PostgreSQL
    type: application
    version: 0.1.0
    appVersion: 1.0.0
  2. Create a values.yaml file and move all configurable parameters there (e.g., replica counts, image tags, resource sizes).

  3. Replace hard‑coded values in the templates with Helm template directives (e.g., {{ .Values.replicaCount }}).

  4. Test with helm template . and then install with helm install my-release ..

📝 Notes

  • The init container in backend-deployment.yaml uses pg_isready to wait for PostgreSQL. Ensure your application image includes pg_isready (part of postgresql-client) or install it in the init container.
  • For production environments, consider using a more robust PostgreSQL operator for high availability, backups, and automated failover.
  • The Secret uses a static base64‑encoded password. In production, integrate with a secrets management solution (e.g., HashiCorp Vault, External Secrets).

🤝 Contributing

Feel free to adapt this project to your needs. If you have improvements or find issues, please open an issue or submit a pull request.

About

A production-ready Kubernetes deployment for a Go backend application with PostgreSQL database

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors