Skip to main content

Deployment Strategies

OPS Intermediate

Deploy EZ-Console applications to production using various strategies.

Overview​

This guide covers different deployment strategies for EZ-Console applications, including standalone binary deployment, Docker containers, Kubernetes, and cloud platforms.

Deployment Methods​

1. Standalone Binary​

Deploy as a single executable file.

Advantages:

  • Simple deployment
  • No container runtime required
  • Direct control over resources

Steps:

# Build binary
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o server main.go

# Copy to server
scp server config.yml user@server:/opt/myapp/

# Run on server
/opt/myapp/server --global.encrypt-key=your-key --config=/opt/myapp/config.yml

2. Docker​

Deploy using Docker containers.

Advantages:

  • Consistent environment
  • Easy to scale
  • Isolation

Dockerfile:

FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-w -s" -o server main.go

FROM node:18-alpine AS frontend-builder
WORKDIR /app
COPY web/package*.json ./
RUN npm install -g pnpm && pnpm install
COPY web/ ./
RUN pnpm build

FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /app
COPY --from=builder /app/server ./
COPY --from=frontend-builder /app/dist ./static
EXPOSE 8080
CMD ["./server", "--global.encrypt-key=${ENCRYPT_KEY}"]

Deploy:

docker build -t myapp:latest .
docker run -d \
-p 8080:8080 \
-e ENCRYPT_KEY=your-key \
-v /path/to/config.yml:/app/config.yml \
myapp:latest

3. Docker Compose​

Deploy with Docker Compose for multi-container applications.

docker-compose.yml:

version: '3.8'

services:
app:
build: .
ports:
- "8080:8080"
environment:
- GLOBAL_ENCRYPT_KEY=${ENCRYPT_KEY}
- DATABASE_DRIVER=mysql
- DATABASE_HOST=db
- DATABASE_USERNAME=root
- DATABASE_PASSWORD=${DB_PASSWORD}
- DATABASE_SCHEMA=myapp
depends_on:
- db
volumes:
- ./config.yml:/app/config.yml
- ./uploads:/app/uploads
restart: unless-stopped

db:
image: mysql:8
environment:
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
- MYSQL_DATABASE=myapp
volumes:
- db-data:/var/lib/mysql
restart: unless-stopped

volumes:
db-data:

Deploy:

docker-compose up -d

4. Kubernetes​

Deploy to Kubernetes cluster.

deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080
env:
- name: GLOBAL_ENCRYPT_KEY
valueFrom:
secretKeyRef:
name: myapp-secrets
key: encrypt-key
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: myapp-secrets
key: db-password
volumeMounts:
- name: config
mountPath: /app/config.yml
subPath: config.yml
volumes:
- name: config
configMap:
name: myapp-config
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: LoadBalancer

Deploy:

kubectl apply -f deployment.yaml

5. Systemd Service​

Deploy as systemd service for Linux servers.

Create service file /etc/systemd/system/myapp.service:

[Unit]
Description=My Console Application
After=network.target mysql.service

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=/etc/myapp/environment
ExecStart=/opt/myapp/server --config=/etc/myapp/config.yml
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable myapp
sudo systemctl start myapp
sudo systemctl status myapp

Reverse Proxy Setup​

Nginx Configuration​

server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl http2;
server_name example.com;

ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;

# Frontend
location / {
root /var/www/myapp;
try_files $uri $uri/ /index.html;
}

# API
location /api {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

# WebSocket support
location /ws {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Traefik Configuration​

# docker-compose.yml with Traefik
version: '3.8'

services:
traefik:
image: traefik:v2.9
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock

app:
build: .
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls=true"

Environment Setup​

Environment Variables​

Create /etc/myapp/environment:

GLOBAL_ENCRYPT_KEY=your-32-byte-encryption-key
SERVER_HOST=0.0.0.0
SERVER_PORT=8080
SERVER_MODE=release
DATABASE_DRIVER=mysql
DATABASE_HOST=localhost
DATABASE_USERNAME=myapp
DATABASE_PASSWORD=secure-password
DATABASE_SCHEMA=myapp
LOG_LEVEL=info

Monitoring Setup​

Health Check​

GET /api/health

Response:

{
"code": "0",
"data": {
"status": "ok"
}
}

Metrics Endpoint​

import "github.com/prometheus/client_golang/prometheus/promhttp"

router.GET("/metrics", gin.WrapH(promhttp.Handler()))

Rollback Strategy​

Docker Rollback​

# Rollback to previous image
docker stop myapp
docker run -d --name myapp myapp:previous-version

Kubernetes Rollback​

# Rollback deployment
kubectl rollout undo deployment/myapp

Systemd Rollback​

# Stop service
sudo systemctl stop myapp

# Restore previous binary
cp /opt/myapp/server.backup /opt/myapp/server

# Start service
sudo systemctl start myapp

Best Practices​

1. Use Environment Variables​

# ✅ Good: Use environment variables
-e ENCRYPT_KEY=${ENCRYPT_KEY}

# ❌ Bad: Hardcode in config
encrypt_key: "hardcoded-key"

2. Version Control Configs​

Keep configuration in version control (without secrets).

3. Health Checks​

Always set up health checks for monitoring.

4. Logging​

Ensure logs are accessible and centralized.


Need help? Ask in GitHub Discussions.