This document outlines the process for deploying the go-layout application to production environments.
The go-layout application is designed for containerized deployment using Docker and Kubernetes (specifically k3s). The application consists of:
- Web API Service: The main web API service
- Task Service: Background task processing service
- Database Migrations: Separate container for running database migrations
- Docker and Docker Compose for local development
- kubectl for interacting with Kubernetes clusters
- Access to a Docker registry (default: docker.io)
- A running k3s cluster (single node or multi-node)
All services are packaged as Docker containers. The following commands build and push the images:
# Build and push all images (Web API, Task, Migrations)
make build
# Build and push individual services
make build-web-api
make build-task
make build-migrateThe version tag for the images is automatically determined from git tags/commits.
Before deploying the application, database migrations should be run to ensure the database schema is up to date.
For production deployments, migrations are run via a Kubernetes job:
# Run migrations on a single-node k3s
make deploy-migrate
# Run migrations on a multi-node k3s cluster
make deploy-migrate-clusterFor simple deployments on a single k3s node:
make deploy-singleThis will deploy:
- The Web API service
- The Task service
- Supporting services (if configured in the k3s manifests)
- Ingress configuration for external access
For deploying to a multi-node k3s cluster:
make deploy-clusterThis deploys the same components but with appropriate configuration for a distributed environment.
To deploy to a specific server:
make deploy-server SERVER=<server_name>To deploy to all servers:
make deploy-allProduction configuration is stored in config/prod/.env and is packaged into the Docker images during build.
Important environment variables for production:
GO_ENV=prod: Sets the application to run in production modeHTTP_MODE=release: Configures Gin to run in release modePG_URL: PostgreSQL connection stringREDIS_URL: Redis connection string (if Redis is used)RABBITMQ_URL: RabbitMQ connection string (if RabbitMQ is used)JWT_SECRET: Secret key for JWT authenticationHTTP_ALLOW_ORIGINS: CORS allowed origins
Kubernetes-specific configuration is stored in:
deploy/k3s/single/for single-node deploymentsdeploy/k3s/cluster/for multi-node cluster deployments
These include:
- ConfigMaps and Secrets for application configuration
- Deployment manifests for services
- Service definitions
- Ingress configuration
- Resource limits and requests
The application provides health check endpoints that are used by Kubernetes to monitor service health:
- Liveness probes check if the service is running
- Readiness probes check if the service is able to handle requests
The application is designed to be stateless and can be scaled horizontally by increasing the number of replicas:
kubectl scale deployment/web-api-deployment --replicas=3 -n go-layout
kubectl scale deployment/task-deployment --replicas=2 -n go-layoutTo roll back to a previous version:
- Identify the previous version tag
- Update the deployment with the previous version:
kubectl set image deployment/web-api-deployment web-api=${REGISTRY}/go-layout-web-api:${PREVIOUS_VERSION} -n go-layout
kubectl set image deployment/task-deployment task=${REGISTRY}/go-layout-task:${PREVIOUS_VERSION} -n go-layout# View Web API service logs
kubectl logs -l app=web-api -n go-layout
# View Task service logs
kubectl logs -l app=task -n go-layout
# View migration job logs
kubectl logs -l app=db-migrate -n go-layoutkubectl get pods -n go-layout- Database Connection Failures: Check PG_URL environment variable and network connectivity
- Memory/CPU Limits: Check if pods are hitting resource limits
- Ingress Issues: Verify ingress configuration and TLS certificates
Edit the deploy/config/servers.yaml file to add the servers you want to deploy to:
servers:
- name: muggleday
host: www.muggleday.com
user: deploy
k3s_version: v1.28.1+k3s1
region: cn # Use 'cn' for China region (faster mirror) or 'global' for international
- name: customer1
host: server1.customer1.com
user: deploy
k3s_version: v1.28.1+k3s1
region: cn # Use 'cn' for China region (faster mirror) or 'global' for internationalThe region parameter determines which mirror to use for k3s installation:
cn: Uses the China mirror for faster installation in mainland Chinaglobal: Uses the default global mirror
# Deploy to a single server
make deploy-server SERVER=muggleday# Deploy to all servers in the configuration
make deploy-all# Build and push images
make build# Deploy to single node k3s
make deploy-single# Deploy to k3s cluster
make deploy-clusterAll environment variables are managed through ConfigMaps and Secrets:
-
ConfigMap (
configmap.yaml):- Contains non-sensitive configuration
- Includes database, Redis, and RabbitMQ connection settings
-
Secret (
secret.yaml):- Contains sensitive information
- Includes database passwords and RabbitMQ credentials
The deployment consists of:
-
Web API Service:
- Single node: 1 replica
- Cluster: 3 replicas with pod anti-affinity
- Exposed via Ingress
-
Task Service:
- Single node: 1 replica
- Cluster: 2 replicas with pod anti-affinity
-
Database Services:
- PostgreSQL
- Redis
- RabbitMQ
- CPU: 200m-500m
- Memory: 256Mi-512Mi
- CPU: 100m-300m
- Memory: 128Mi-256Mi
- PostgreSQL: 500m-1000m CPU, 512Mi-1Gi Memory, 5Gi Storage
- Redis: 200m-500m CPU, 256Mi-512Mi Memory, 1Gi Storage
- RabbitMQ: 200m-500m CPU, 256Mi-512Mi Memory, 1Gi Storage
- Check pod status:
kubectl get pods -n go-layout- Check service status:
kubectl get svc -n go-layout- View pod logs:
kubectl logs -n go-layout <pod-name>- If pods are not starting:
kubectl describe pod -n go-layout <pod-name>- If services are not accessible:
kubectl describe svc -n go-layout <service-name>- If server deployment fails:
# Check the SSH connection
ssh <user>@<server-host>
# Check the k3s installation
ssh <user>@<server-host> "sudo systemctl status k3s"- All sensitive data is stored in Kubernetes Secrets
- Pod anti-affinity ensures high availability in cluster mode
- Resource limits prevent resource exhaustion
- Non-root user is used in containers for security
To scale services:
# Scale Web API service
kubectl scale deployment api-deployment -n go-layout --replicas=<number>
# Scale Task service
kubectl scale deployment task-deployment -n go-layout --replicas=<number>