Kubernetes Migration Guide
Follow these steps to migrate your application to Kubernetes. This tool automates Steps 3β7 for you.
Containerize App β Push to GHCR β Configure Project β Deploy to Repo β CI/CD Builds Image β ArgoCD Syncs β App Live β
1 Containerize Your Application
Create a Dockerfile in your project root. Below are examples for common stacks:
Node.js / Express:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
Python / FastAPI / Django:
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Java / Spring Boot:
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
.dockerignore file to exclude node_modules/, .git/, .env, and other unnecessary files from the image.
Test locally:
docker run -p 8080:8080 my-app
2 Migrate from Local Storage to Cloud Storage
multer diskStorage, local file system writes, or stores uploads on disk β you must migrate to cloud storage before deploying to Kubernetes. Containers are ephemeral; local files are lost on restart or scaling.
Why?
- Kubernetes pods are ephemeral β local files are destroyed when pods restart or scale
- Multiple replicas cannot share a local disk
- Use our internal cloud storage API for file uploads, downloads, and folder management
Refer to the complete Files & Folders API guide for endpoints, authentication, upload/download, folder structure, and code examples:
π FILES_AND_FOLDERS_API.md β Full Reference
3 Add Health Check Endpoints
Kubernetes uses health checks to know if your app is alive and ready to serve traffic. Add these endpoints:
app.get('/health', (req, res) => res.json({ status: 'ok' }));
app.get('/ready', (req, res) => {
// Check DB connection, redis, etc.
res.json({ status: 'ready' });
});
@app.get("/health")
async def health(): return {"status": "ok"}
@app.get("/ready")
async def ready(): return {"status": "ready"}
/health and /ready).
4 Prepare Environment Variables
Move all configuration to environment variables. Never hardcode secrets, database URLs, or API keys.
Create a .env file (do NOT commit this to git):
REDIS_URL=redis://redis-host:6379
S3_BUCKET=my-uploads
S3_ENDPOINT=https://s3.amazonaws.com
S3_ACCESS_KEY=AKIA...
S3_SECRET_KEY=xxxxx
JWT_SECRET=my-super-secret
NODE_ENV=production
.env file. The tool will create a Kubernetes Secret ({project}-secrets) and inject all variables into your pod automatically.
5 Configure This Tool (One-Time Setup)
Go to the Setup tab and configure:
- Chart Repository β URL of your universal Helm chart repo
- GitOps Repository β Central config repo that ArgoCD watches for new apps
- GHCR Credentials β GitHub username + PAT so image pull secrets are created automatically
- Cloudflare DNS β API token + Zone ID + Cluster IP for automatic DNS pointing
6 Fill in Project Configuration
Go to the Project Config tab and provide:
- Project name β lowercase, dashes only (e.g.,
designer-backend) - Namespace β K8s namespace for isolation (e.g.,
design) - Git repo URL + token β where your source code lives
- Image registry/repository β usually
ghcr.io/org-name/app-name - Hostname β domain for the app (e.g.,
app.admarksolution.com) - Container port β the port your app listens on inside the container
- Environment variables β upload your
.envfile
7 Generate & Deploy
Click "Generate Configuration" to preview all files, then click "Deploy to Repository". The tool will automatically:
| Action | What it does |
|---|---|
| Git Push | Commits values.yaml, ArgoCD app, GitHub Actions workflow to your repo |
| Namespace | Creates the K8s namespace if it doesn't exist |
| Image Pull Secret | Creates ghcr-secret so the cluster can pull your private images |
| Env Secret | Creates {project}-secrets with your environment variables |
| ArgoCD | Registers app in the GitOps repo β ApplicationSet auto-creates the ArgoCD Application |
| DNS | Creates/updates Cloudflare A record pointing your hostname to the cluster IP |
8 Push Code & Watch It Deploy
After the initial setup, the CI/CD pipeline handles everything:
- Push code to your repoβs
mainbranch - GitHub Actions builds Docker image with timestamp tag
- Image pushed to GHCR
- Workflow updates
k8s/values.yamlwith new image tag - ArgoCD detects the change and auto-syncs
- New version is live! π
git push to main triggers a full build β deploy cycle automatically. No manual kubectl commands needed.
π§ Quick Troubleshooting
| Symptom | Fix |
|---|---|
| ImagePullBackOff | Check ghcr-secret exists in namespace. Re-save GHCR creds in Setup tab and re-deploy. |
| CrashLoopBackOff | App is crashing. Check logs: kubectl logs -n NAMESPACE POD_NAME. Usually missing env vars or wrong port. |
| ArgoCD OutOfSync | Click Sync in ArgoCD. If errors, check Events tab for specifics. |
| 502 Bad Gateway | Pod is running but app isnβt listening on the configured port. Verify containerPort matches your app. |
| TLS Certificate Pending | cert-manager needs DNS to resolve. Wait 2β5 min after DNS creation. Check: kubectl get certificate -n NAMESPACE |
| Workflow not triggering | Ensure the first push has a Dockerfile and .github/workflows/deploy.yml. GitHub Actions wonβt run from the default branch until the workflow file exists there. |
Chart Repository Configuration
Configure the universal chart repository that will be used for all deployments.
GitOps Config Repository (ArgoCD ApplicationSet)
Configure the central GitOps repo where app configs are registered. ArgoCD ApplicationSet watches this repo to auto-create Applications.
Container Registry Credentials (Image Pull Secret)
Configure GHCR/registry credentials so the service can automatically create ghcr-secret in each project namespace. No more manual secret creation!
read:packages scope for pulling images
Cloudflare DNS (Auto DNS Pointing)
When enabled, A records are auto-created/updated for project hostnames (DNS only, not proxied).
Project Configuration
Repository Information
Image Configuration
Deployment Type
Environment Variables / Secrets
Upload a .env file or paste key=value pairs. These will be stored as a Kubernetes Secret ({project-name}-secrets) in the namespace and injected into your containers automatically.
Additional Options
Deployment Templates
Quick start with pre-configured templates
π Web Application
Single web application with ingress and TLS
π» Full Stack Application
Frontend and Backend services with separate domains
π§ Microservices
Multiple microservices architecture
Generated Configuration Files
π values.yaml
Generate configuration first...
π argocd-application.yaml
Generate configuration first...
π .github/workflows/deploy.yml
Generate configuration first...
- Click "Deploy to Repository" to automatically commit files to your Git repo
- Or download files manually and commit them yourself
- Create image pull secret:
kubectl create secret docker-registry ghcr-secret --docker-server=ghcr.io --docker-username=USERNAME --docker-password=TOKEN -n NAMESPACE - Apply ArgoCD application:
kubectl apply -f k8s/argocd-application.yaml - Sync in ArgoCD UI and watch your deployment! π