Go / Build ба deploy

Build ба deploy

Та гайхалтай Go программ бичлээ. Одоо дэлхийд харуулах цаг боллоо. Build нь таны кодыг ажиллуулж болох файл болгоно, deploy нь тэр файлыг сервер дээр ажиллуулна. Go-ийн хамгийн давуу талуудын нэг бол build маш хялбар, binary нэг файлд бүгд багтдаг — тиймд dependency суулгах, runtime тохируулах хэрэггүй.

go build — binary үүсгэх

go build команд нь таны кодоос ажиллуулах боломжтой binary файл үүсгэдэг:

bash
# Одоогийн директорийн main package-ийг build хийх
go build -o myapp .

# Binary-г тодорхой нэртэйгээр хадгалах
go build -o bin/server ./cmd/server

# Оновчлолтой build — production-д заавал ашигла
go build -ldflags="-s -w" -o myapp .
bash
# Ажиллуулах
./myapp

# Файлын хэмжээ харах
ls -lh myapp
# -rwxr-xr-x  1 user  staff  8.2M myapp

-ldflags="-s -w" нь debug мэдээллийг хасаж файлын хэмжээг жижигрүүлдэг. Production binary-д заавал хэрэглэ.

Орчны хувьсагч — environment variable

Нууц мэдээлэл (database нэвтрэх мэдээлэл, API key) болон орчноос хамаарах тохиргоог environment variable ашиглан дамжуулдаг:

go
package main

import (
    "fmt"
    "log"
    "os"
)

type Тохиргоо struct {
    Порт        string
    DatabaseURL string
    Debug       bool
}

func тохиргооАвах() Тохиргоо {
    порт := os.Getenv("PORT")
    if порт == "" {
        порт = "8080" // анхдагч утга
    }

    dbURL := os.Getenv("DATABASE_URL")
    if dbURL == "" {
        log.Fatal("DATABASE_URL тохируулаагүй байна")
    }

    debug := os.Getenv("DEBUG") == "true"

    return Тохиргоо{
        Порт:        порт,
        DatabaseURL: dbURL,
        Debug:       debug,
    }
}

func main() {
    тох := тохиргооАвах()
    fmt.Printf("Server :%s дээр ажиллаж байна (debug: %v)\n", тох.Порт, тох.Debug)
}
bash
# Локал ажиллуулах
PORT=3000 DATABASE_URL=postgres://localhost/mydb DEBUG=true ./myapp

# Эсвэл .env файлаас (development-д)
export DATABASE_URL=postgres://localhost/mydb
./myapp

Код дотор нууц мэдээллийг хэзээ ч хатуу бичихгүй. Environment variable ашигла.

Cross-compilation — өөр платформд build хийх

Go-ийн хамгийн хүчтэй тал бол нэг машинаас өөр платформ, өөр процессорт зориулж build хийж чадна:

bash
# Mac дээр Linux binary үүсгэх (server-д байршуулах)
GOOS=linux GOARCH=amd64 go build -o myapp-linux .

# Windows binary үүсгэх
GOOS=windows GOARCH=amd64 go build -o myapp.exe .

# ARM процессортой Linux (Raspberry Pi, AWS Graviton)
GOOS=linux GOARCH=arm64 go build -o myapp-arm .

# Бүх платформд нэгэн зэрэг build хийх script
for os in linux darwin windows; do
    for arch in amd64 arm64; do
        нэр="myapp-${os}-${arch}"
        GOOS=$os GOARCH=$arch go build -o "bin/$нэр" .
        echo "✓ $нэр"
    done
done

Ганц go build команд — ямар ч нэмэлт хэрэгсэлгүйгээр дурын платформд binary гаргадаг. Энэ нь Go-ийн бахархал юм.

Dockerfile — container дотор ажиллуулах

Production дээр Docker ашиглан программ байршуулах нь хамгийн өргөн хэрэглэгддэг арга. Go binary нь нэг файл тул Dockerfile маш жижиг байна:

dockerfile
# Dockerfile

# ---- Build stage ----
FROM golang:1.22-alpine AS builder

WORKDIR /app

# Dependency-уудыг эхлээд copy хийж cache ашиглах
COPY go.mod go.sum ./
RUN go mod download

# Кодыг copy хийж build хийх
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o server .

# ---- Run stage ---- (маш жижиг image)
FROM alpine:latest

WORKDIR /app

# Зөвхөн binary-г авах
COPY --from=builder /app/server .

# Порт нээх
EXPOSE 8080

# Server ажиллуулах
CMD ["./server"]
bash
# Image үүсгэх
docker build -t myapp:latest .

# Локал ажиллуулах
docker run -p 8080:8080 \
  -e DATABASE_URL=postgres://localhost/mydb \
  myapp:latest

# Image-ийн хэмжээ харах
docker images myapp
# myapp   latest   abc123   5 minutes ago   12MB

Multi-stage build ашигласнаар эцсийн image нь зөвхөн 10-15MB байдаг — маш жижиг!

Systemd service — Linux сервер дээр ажиллуулах

Docker ашиглахгүй сервер дээр systemd service болгон ажиллуулж болно:

bash
# /etc/systemd/system/myapp.service
ini
[Unit]
Description=My Go Application
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/server
Restart=always
RestartSec=5

# Environment variables
Environment=PORT=8080
EnvironmentFile=/opt/myapp/.env

# Аюулгүй байдал
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
bash
# Service идэвхжүүлэх
sudo systemctl enable myapp
sudo systemctl start myapp

# Статус харах
sudo systemctl status myapp

# Log харах
sudo journalctl -u myapp -f

Systemd нь сервер дахин асаах үед программыг автоматаар эхлүүлдэг бөгөөд crash болбол дахин ажиллуулдаг.

Дараагийн хичээлд:

Build ба deploy-ийг судаллаа — одоо та жинхэнэ Go программ бичиж, дэлхийд хүргэх бүх мэдлэгтэй болсон. Дараагийн хичээл бол эцсийн төсөл юм: энэ курсэд сурсан бүх зүйлээ нэгтгэн, бүрэн ажилладаг REST API сервер бичнэ!