部署上线 #
一、部署概述 #
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