部署上线 #

一、部署概述 #

1.1 部署方式 #

text
┌─────────────────────────────────────────────────────────┐
│                    部署方式                              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  传统部署                                                │
│  ├── 编译二进制                                         │
│  ├── Systemd服务                                        │
│  └── Nginx反向代理                                      │
│                                                         │
│  Docker部署                                              │
│  ├── Dockerfile                                         │
│  ├── Docker Compose                                     │
│  └── Kubernetes                                         │
│                                                         │
│  云平台部署                                              │
│  ├── 云服务器                                           │
│  ├── 容器服务                                           │
│  └── Serverless                                         │
│                                                         │
└─────────────────────────────────────────────────────────┘

二、编译构建 #

2.1 本地编译 #

bash
go build -o myapp cmd/server/main.go

2.2 交叉编译 #

bash
GOOS=linux GOARCH=amd64 go build -o myapp cmd/server/main.go

GOOS=darwin GOARCH=amd64 go build -o myapp cmd/server/main.go

GOOS=windows GOARCH=amd64 go build -o myapp.exe cmd/server/main.go

2.3 编译优化 #

bash
go build -ldflags="-s -w" -o myapp cmd/server/main.go

2.4 Makefile #

makefile
.PHONY: build run clean

APP_NAME=myapp
VERSION=$(shell git describe --tags --always --dirty)
BUILD_TIME=$(shell date -u '+%Y-%m-%d_%H:%M:%S')
LDFLAGS=-ldflags "-s -w -X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME)"

build:
	go build $(LDFLAGS) -o bin/$(APP_NAME) cmd/server/main.go

run:
	go run cmd/server/main.go

clean:
	rm -rf bin/

test:
	go test -v ./...

docker:
	docker build -t $(APP_NAME):$(VERSION) .

三、Docker部署 #

3.1 Dockerfile #

dockerfile
FROM golang:1.21-alpine AS builder

WORKDIR /app

RUN apk add --no-cache git

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o myapp cmd/server/main.go

FROM alpine:latest

RUN apk --no-cache add ca-certificates tzdata

WORKDIR /app

COPY --from=builder /app/myapp .
COPY --from=builder /app/config ./config

ENV TZ=Asia/Shanghai

EXPOSE 8080

CMD ["./myapp"]

3.2 Docker Compose #

docker-compose.yml

yaml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - APP_ENV=production
    depends_on:
      - mysql
      - redis
    networks:
      - app-network
    restart: always

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app-network
    restart: always

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    networks:
      - app-network
    restart: always

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/ssl:/etc/nginx/ssl
    depends_on:
      - app
    networks:
      - app-network
    restart: always

networks:
  app-network:
    driver: bridge

volumes:
  mysql-data:
  redis-data:

3.3 构建和运行 #

bash
docker-compose build

docker-compose up -d

docker-compose logs -f app

docker-compose down

四、Nginx配置 #

4.1 反向代理 #

nginx/nginx.conf

nginx
events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

    upstream app {
        server app:8080;
    }

    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 /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/key.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;

        client_max_body_size 10M;

        location / {
            proxy_pass http://app;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            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;
            proxy_cache_bypass $http_upgrade;
        }

        location /static {
            alias /app/static;
            expires 30d;
        }

        location /ws {
            proxy_pass http://app;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
        }
    }
}

4.2 负载均衡 #

nginx
upstream app {
    least_conn;
    server app1:8080 weight=3;
    server app2:8080 weight=2;
    server app3:8080 weight=1;
}

五、Systemd服务 #

5.1 服务配置 #

/etc/systemd/system/myapp.service

ini
[Unit]
Description=My Echo Application
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=myapp
Environment=APP_ENV=production

[Install]
WantedBy=multi-user.target

5.2 服务管理 #

bash
sudo systemctl daemon-reload

sudo systemctl start myapp

sudo systemctl enable myapp

sudo systemctl status myapp

sudo systemctl restart myapp

sudo journalctl -u myapp -f

六、HTTPS配置 #

6.1 Let’s Encrypt #

bash
sudo apt install certbot python3-certbot-nginx

sudo certbot --nginx -d example.com -d www.example.com

sudo certbot renew --dry-run

6.2 自动续期 #

bash
sudo crontab -e
text
0 0 1 * * /usr/bin/certbot renew --quiet

七、监控告警 #

7.1 Prometheus指标 #

go
package main

import (
    "github.com/labstack/echo-contrib/echoprometheus"
    "github.com/labstack/echo/v4"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
    e := echo.New()
    
    e.Use(echoprometheus.NewMiddleware("myapp"))
    
    e.GET("/metrics", echo.WrapHandler(promhttp.Handler()))
    
    e.Start(":8080")
}

7.2 健康检查 #

go
e.GET("/health", func(c echo.Context) error {
    return c.JSON(http.StatusOK, map[string]string{
        "status": "healthy",
    })
})

e.GET("/ready", func(c echo.Context) error {
    if err := db.Ping(); err != nil {
        return c.JSON(http.StatusServiceUnavailable, map[string]string{
            "status": "not ready",
        })
    }
    
    return c.JSON(http.StatusOK, map[string]string{
        "status": "ready",
    })
})

八、日志管理 #

8.1 日志配置 #

go
import (
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
)

func main() {
    e := echo.New()
    
    e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
        Format: `{"time":"${time_rfc3339}","method":"${method}","uri":"${uri}",` +
            `"status":${status},"latency":${latency},"ip":"${remote_ip}"}` + "\n",
        Output: os.Stdout,
    }))
}

8.2 日志轮转 #

yaml
version: '3.8'

services:
  app:
    build: .
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

九、CI/CD #

9.1 GitHub Actions #

.github/workflows/deploy.yml

yaml
name: Deploy

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Go
      uses: actions/setup-go@v4
      with:
        go-version: '1.21'
    
    - name: Build
      run: go build -v -o myapp cmd/server/main.go
    
    - name: Test
      run: go test -v ./...
    
    - name: Build Docker image
      run: docker build -t myapp:${{ github.sha }} .
    
    - name: Push to registry
      run: |
        docker tag myapp:${{ github.sha }} registry.example.com/myapp:${{ github.sha }}
        docker push registry.example.com/myapp:${{ github.sha }}

十、总结 #

部署要点:

要点 说明
编译 交叉编译、优化
Docker Dockerfile、Compose
Nginx 反向代理、负载均衡
HTTPS Let’s Encrypt
Systemd 服务管理
监控 Prometheus、健康检查
日志 日志配置、轮转
CI/CD GitHub Actions

恭喜你完成了Echo框架的学习!

最后更新:2026-03-28