Ver3.0 ๐ Go์ธ์ด ํฌ๋ก์ค ์ปดํ์ผ ์์ ์ ๋ณต

๐ Go์ธ์ด ํฌ๋ก์ค ์ปดํ์ผ ์์ ์ ๋ณต
ํ ๋ฒ์ ๋น๋๋ก ๋ชจ๋ ํ๋ซํผ์ ์ ๋ณตํ๋ ๋ง๋ฒ ๊ฐ์ ์ด์ผ๊ธฐ
์๋
! ์ค๋์ Go์ธ์ด์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๋ฌด๊ธฐ ์ค ํ๋์ธ ํฌ๋ก์ค ์ปดํ์ผ์ ๋ํด ์ด์ผ๊ธฐํด๋ณด๋ ค๊ณ ํด. ๐ฏ
ํน์ ํ๋ก๊ทธ๋จ ํ๋ ๋ง๋ค์ด์ ์๋์ฐ, ๋งฅ, ๋ฆฌ๋
์ค์ ๋ค ๋ฐฐํฌํ๋ ค๋ฉด ๊ฐ๊ฐ ๋ค๋ฅธ ์ปดํจํฐ์์ ๋น๋ํด์ผ ํ๋ค๊ณ ์๊ฐํ๋ ์ ์์ด? ๊ทธ๋ฐ๋ฐ Go๋ ๊ทธ๋ฐ ๊ณ ๋ฏผ์ ์์ ํ ๋ ๋ ค๋ฒ๋ ธ์ด!
๋งฅ๋ถ์์ ์์
ํ๋ฉด์ ์๋์ฐ์ฉ ์คํํ์ผ์ ๋ง๋ค๊ณ , ๋ฆฌ๋
์ค ์๋ฒ์ฉ ๋ฐ์ด๋๋ฆฌ๋ ๋๋ฑ ๋ง๋ค ์ ์๋ค๋... ๋ง์น ๋ง๋ฒ ๊ฐ์ง ์์? โจ
์ด๊ฒ ๋ฐ๋ก Go์ ํฌ๋ก์ค ์ปดํ์ผ ๋ฅ๋ ฅ์ด์ผ. ์ฌ๋ฅ๋ท์์ ํ๋ก๊ทธ๋๋ฐ ์ฌ๋ฅ์ ๊ณต์ ํ๋ ๊ฐ๋ฐ์๋ค๋ ์ด ๊ธฐ๋ฅ์ ์ ๋ง ๋ง์ด ํ์ฉํ๊ณ ์์ด.
๐ช ํฌ๋ก์ค ์ปดํ์ผ์ด ๋ญ๊ธธ๋?
ํฌ๋ก์ค ์ปดํ์ผ(Cross Compile)์ด๋ผ๋ ์ฉ์ด๊ฐ ์ข ์ด๋ ต๊ฒ ๋๊ปด์ง ์ ์๋๋ฐ, ์ฌ์ค ๊ฐ๋
์ ์ ๋ง ๋จ์ํด.
๋ด๊ฐ ์ง๊ธ ์ฌ์ฉํ๋ ์ปดํจํฐ์ ๋ค๋ฅธ ์ด์์ฒด์ ๋ ์ํคํ
์ฒ๋ฅผ ์ํ ์คํ ํ์ผ์ ๋ง๋๋ ๊ฒ์ ๋งํด. ๐ฏ
๐ก ์ฌ์ด ์์๋ก ์ดํดํ๊ธฐ
๋งฅ๋ถ(macOS)์์ ๊ฐ๋ฐํ๊ณ ์๋๋ฐ, ์๋์ฐ ์ฌ์ฉ์๋ฅผ ์ํ .exe ํ์ผ์ ๋ง๋ค์ด์ผ ํ๋ค๋ฉด?
์ผ๋ฐ์ ์ผ๋ก๋ ์๋์ฐ ์ปดํจํฐ๊ฐ ํ์ํ๊ฒ ์ง. ํ์ง๋ง Go๋ ๋งฅ๋ถ์์ ๋ช
๋ น์ด ํ๋๋ก ์๋์ฐ์ฉ ์คํํ์ผ์ ๋ง๋ค ์ ์์ด!
์ ํต์ ์ธ ์ธ์ด๋ค(C, C++ ๋ฑ)์์๋ ํฌ๋ก์ค ์ปดํ์ผ์ด ์ ๋ง ๋ณต์กํ์ด. ๊ฐ ํ๋ซํผ๋ณ๋ก ๋ค๋ฅธ ์ปดํ์ผ๋ฌ๋ฅผ ์ค์นํ๊ณ , ๋ณต์กํ ์ค์ ์ ํด์ผ ํ๊ฑฐ๋ .
ํ์ง๋ง Go๋ ์ฒ์๋ถํฐ ํฌ๋ก์ค ์ปดํ์ผ์ ์ผ๋์ ๋๊ณ ์ค๊ณ๋์๊ธฐ ๋๋ฌธ์ ์ ๋ง ๊ฐ๋จํด! ๐
๐ ์ Go๋ ํฌ๋ก์ค ์ปดํ์ผ์ด ์ฌ์ธ๊น?
Go ์ปดํ์ผ๋ฌ๋ ์์ Go ์ธ์ด๋ก ์์ฑ๋์ด ์๊ณ , ๋ชจ๋ ํ๋ซํผ์ ์ปดํ์ผ๋ฌ๊ฐ Go ์ค์น ์ ํจ๊ป ํฌํจ๋์ด ์์ด.
๊ทธ๋์ ๋ณ๋์ ํด์ฒด์ธ์ ์ค์นํ ํ์ ์์ด ํ๊ฒฝ๋ณ์ ๋ ๊ฐ๋ง ์ค์ ํ๋ฉด ๋์ด์ผ!
๐ ๏ธ ๊ธฐ๋ณธ์ ์ธ ํฌ๋ก์ค ์ปดํ์ผ ๋ฐฉ๋ฒ
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ํฌ๋ก์ค ์ปดํ์ผํ๋ ๋ฐฉ๋ฒ์ ์์๋ณผ๊น? ์ ๋ง ๊ฐ๋จํ๋๊น ๊ฑฑ์ ํ์ง ๋ง! ๐
๐ ๊ธฐ๋ณธ ๋ฌธ๋ฒ
Go์์ ํฌ๋ก์ค ์ปดํ์ผ์ ํ๋ ค๋ฉด ๋ ๊ฐ์ง ํ๊ฒฝ๋ณ์๋ฅผ ์ค์ ํด์ผ ํด:
๐ฏ ํต์ฌ ํ๊ฒฝ๋ณ์
GOOS: ํ๊ฒ ์ด์์ฒด์ (์: windows, linux, darwin)
GOARCH: ํ๊ฒ ์ํคํ
์ฒ (์: amd64, arm64, 386)
์ด ๋ ํ๊ฒฝ๋ณ์๋ฅผ ๋น๋ ๋ช ๋ น์ด ์์ ๋ถ์ฌ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋ผ. ์ ๋ง ๊ฐ๋จํ์ง?
๐ป ์ค์ ์์
๊ฐ๋จํ Hello World ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด์ ์ฌ๋ฌ ํ๋ซํผ์ฉ์ผ๋ก ๋น๋ํด๋ณด์!
// main.go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Printf("Hello from Go!\n")
fmt.Printf("OS: %s\n", runtime.GOOS)
fmt.Printf("Architecture: %s\n", runtime.GOARCH)
}
์ด์ ์ด ํ๋ก๊ทธ๋จ์ ๋ค์ํ ํ๋ซํผ์ฉ์ผ๋ก ์ปดํ์ผํด๋ณด์! ๐
๐ช Windows์ฉ ๋น๋ (64๋นํธ)
# Linux๋ macOS์์ ์คํ
GOOS=windows GOARCH=amd64 go build -o myapp.exe main.go
# Windows PowerShell์์ ์คํ
$env:GOOS="windows"; $env:GOARCH="amd64"; go build -o myapp.exe main.go
์ด๋ ๊ฒ ํ๋ฉด myapp.exe ํ์ผ์ด ์์ฑ๋ผ. ์ด ํ์ผ์ ์๋์ฐ ์ปดํจํฐ๋ก ๊ฐ์ ธ๊ฐ๋ฉด ๋ฐ๋ก ์คํํ ์ ์์ด!
๐ macOS์ฉ ๋น๋
# Intel Mac์ฉ (amd64)
GOOS=darwin GOARCH=amd64 go build -o myapp-mac-intel main.go
# Apple Silicon (M1/M2) Mac์ฉ (arm64)
GOOS=darwin GOARCH=arm64 go build -o myapp-mac-arm main.go
๐ก Pro Tip
macOS๋ ์ฝ๋๋ช
์ด darwin์ด์ผ. ์ฒ์์๋ ์ข ํท๊ฐ๋ฆด ์ ์๋๋ฐ, ์ด๊ฑด macOS์ ๊ธฐ๋ฐ์ด ๋๋ ์ด์์ฒด์ ์ด๋ฆ์์ ๋ฐ์จ ๊ฑฐ์ผ.
๊ทธ๋ฆฌ๊ณ ์ต์ ๋งฅ๋ถ์ Apple Silicon(M1, M2 ๋ฑ)์ ์ฌ์ฉํ๋๊น arm64๋ก ๋น๋ํด์ผ ํด!
๐ง Linux์ฉ ๋น๋
# Linux 64๋นํธ์ฉ
GOOS=linux GOARCH=amd64 go build -o myapp-linux main.go
# Linux ARM 64๋นํธ์ฉ (๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ๋ฑ)
GOOS=linux GOARCH=arm64 go build -o myapp-linux-arm main.go
# Linux 32๋นํธ์ฉ
GOOS=linux GOARCH=386 go build -o myapp-linux-32 main.go
๋ฆฌ๋ ์ค๋ ์๋ฒ ํ๊ฒฝ์์ ๋ง์ด ์ฌ์ฉ๋๋๊น, ํนํ ์ค์ํด. ํด๋ผ์ฐ๋ ์๋ฒ์ ๋ฐฐํฌํ ๋ ์ ๋ง ์ ์ฉํ์ง! โ๏ธ
๐ ์ง์ํ๋ ํ๋ซํผ ์ ์ฒด ๋ชฉ๋ก
Go๊ฐ ์ง์ํ๋ ํ๋ซํผ์ด ์ผ๋ง๋ ๋ง์์ง ๊ถ๊ธํ์ง? ์ ๋ง ๋๋ผ์ธ ์ ๋๋ก ๋ค์ํด! ๐ฒ
๋ค์ ๋ช ๋ น์ด๋ก ์ง์ํ๋ ๋ชจ๋ ํ๋ซํผ ์กฐํฉ์ ํ์ธํ ์ ์์ด:
go tool dist list
์ด ๋ช ๋ น์ด๋ฅผ ์คํํ๋ฉด 50๊ฐ๊ฐ ๋๋ ํ๋ซํผ ์กฐํฉ์ด ๋์. ์ฃผ์ ํ๋ซํผ๋ค์ ์ ๋ฆฌํด๋ณผ๊ฒ!
๐ช Windows
โข windows/amd64 (64๋นํธ)
โข windows/386 (32๋นํธ)
โข windows/arm64 (ARM 64๋นํธ)
๐ macOS (Darwin)
โข darwin/amd64 (Intel Mac)
โข darwin/arm64 (Apple Silicon)
๐ง Linux
โข linux/amd64 (64๋นํธ)
โข linux/386 (32๋นํธ)
โข linux/arm (32๋นํธ ARM)
โข linux/arm64 (64๋นํธ ARM)
๐ ๊ธฐํ ํ๋ซํผ
โข freebsd, openbsd, netbsd
โข android, ios
โข plan9, solaris
โข dragonfly, illumos
๐ฎ ํน๋ณํ ํ๋ซํผ๋ค
Go๋ ์ฌ์ง์ด WebAssembly(js/wasm)๋ ์ง์ํด! ์ด๊ฑด Go ์ฝ๋๋ฅผ ์น๋ธ๋ผ์ฐ์ ์์ ์คํํ ์ ์๋ค๋ ๋ป์ด์ผ.
๋ํ ๋ชจ๋ฐ์ผ ํ๋ซํผ์ธ Android์ iOS๋ ์ง์ํ๋๊น, ์ ๋ง ๋ค์ํ ๊ณณ์์ Go๋ฅผ ์ฌ์ฉํ ์ ์์ด! ๐ฑ
โ๏ธ ๊ณ ๊ธ ๋น๋ ์ต์ ๋ค
๊ธฐ๋ณธ์ ์ธ ํฌ๋ก์ค ์ปดํ์ผ์ ๋์ด์, ๋ ์ธ๋ฐํ ์ ์ด๊ฐ ํ์ํ ๋๊ฐ ์์ด. ์ด์ ๊ณ ๊ธ ์ต์ ๋ค์ ์์๋ณด์! ๐
๐ง ๋น๋ ํ๊ทธ ํ์ฉํ๊ธฐ
๋น๋ ํ๊ทธ๋ฅผ ์ฌ์ฉํ๋ฉด ํน์ ํ๋ซํผ์์๋ง ์ปดํ์ผ๋๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ด.
์ด๊ฑด ํ๋ซํผ๋ณ๋ก ๋ค๋ฅธ ๊ตฌํ์ด ํ์ํ ๋ ์ ๋ง ์ ์ฉํด!
// file_windows.go
//go:build windows
package main
import "fmt"
func platformSpecific() {
fmt.Println("์ด ์ฝ๋๋ Windows์์๋ง ์ปดํ์ผ๋ฉ๋๋ค!")
}
// file_linux.go
//go:build linux
package main
import "fmt"
func platformSpecific() {
fmt.Println("์ด ์ฝ๋๋ Linux์์๋ง ์ปดํ์ผ๋ฉ๋๋ค!")
}
์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ํ๋ซํผ์ ๋ง๋ ์ฝ๋๋ง ์ปดํ์ผ๋๋๊น, ๋ถํ์ํ ์ฝ๋๊ฐ ๋ฐ์ด๋๋ฆฌ์ ํฌํจ๋์ง ์์! ๐
๐ฆ ๋ฐ์ด๋๋ฆฌ ํฌ๊ธฐ ์ค์ด๊ธฐ
Go ๋ฐ์ด๋๋ฆฌ๋ ๋ชจ๋ ์์กด์ฑ์ ํฌํจํ๋ ์ ์ ๋งํฌ ๋ฐฉ์์ด๋ผ ํฌ๊ธฐ๊ฐ ์ข ํฐ ํธ์ด์ผ.
ํ์ง๋ง ๋ช ๊ฐ์ง ์ต์
์ผ๋ก ํฌ๊ธฐ๋ฅผ ๋ง์ด ์ค์ผ ์ ์์ด!
# ๋๋ฒ๊ทธ ์ ๋ณด ์ ๊ฑฐ ๋ฐ ์ต์ ํ
go build -ldflags="-s -w" -o myapp main.go
# ๋ ๊ณต๊ฒฉ์ ์ธ ์ต์ ํ
go build -ldflags="-s -w" -trimpath -o myapp main.go
๐ฏ ldflags ์ต์ ์ค๋ช
-s: ์ฌ๋ณผ ํ
์ด๋ธ ์ ๊ฑฐ
-w: DWARF ๋๋ฒ๊น
์ ๋ณด ์ ๊ฑฐ
-trimpath: ํ์ผ ๊ฒฝ๋ก ์ ๋ณด ์ ๊ฑฐ
์ด ์ต์ ๋ค์ ์ฌ์ฉํ๋ฉด ๋ฐ์ด๋๋ฆฌ ํฌ๊ธฐ๊ฐ 30~40% ์ ๋ ์ค์ด๋ค ์ ์์ด! ํ์ง๋ง ๋๋ฒ๊น ์ด ์ด๋ ค์์ง๋๊น, ํ๋ก๋์ ๋น๋์๋ง ์ฌ์ฉํ๋ ๊ฒ ์ข์.
๐ท๏ธ ๋ฒ์ ์ ๋ณด ํฌํจํ๊ธฐ
๋ฐฐํฌํ ๋ ๋ฒ์ ์ ๋ณด๋ฅผ ๋ฐ์ด๋๋ฆฌ์ ํฌํจ์ํค๋ฉด ์ ๋ง ์ ์ฉํด. ๋์ค์ ์ด๋ค ๋ฒ์ ์ธ์ง ํ์ธํ๊ธฐ ์ฝ๊ฑฐ๋ !
// main.go
package main
import "fmt"
var (
version = "dev"
commit = "none"
date = "unknown"
)
func main() {
fmt.Printf("Version: %s\n", version)
fmt.Printf("Commit: %s\n", commit)
fmt.Printf("Build Date: %s\n", date)
}
# ๋น๋ ์ ๋ฒ์ ์ ๋ณด ์ฃผ์
go build -ldflags="-X main.version=1.0.0 -X main.commit=$(git rev-parse HEAD) -X main.date=$(date +%Y-%m-%d)" -o myapp
์ด๋ ๊ฒ ํ๋ฉด ์คํ ํ์ผ์ ๋ฒ์ ์ ๋ณด๊ฐ ํฌํจ๋์ด์, ๋์ค์ ์ด๋ค ๋ฒ์ ์ธ์ง ์ฝ๊ฒ ํ์ธํ ์ ์์ด! ๐
๐ CGO ๋นํ์ฑํํ๊ธฐ
CGO๋ Go์์ C ์ฝ๋๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ์ธ๋ฐ, ํฌ๋ก์ค ์ปดํ์ผํ ๋๋ ๋ฌธ์ ๊ฐ ๋ ์ ์์ด.
์์ Go ์ฝ๋๋ง ์ฌ์ฉํ๋ค๋ฉด CGO๋ฅผ ๋นํ์ฑํํ๋ ๊ฒ ์ข์!
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o myapp main.go
๐ก CGO_ENABLED=0์ ์ฅ์
โข ์์ ํ ์ ์ ๋งํฌ ๋ฐ์ด๋๋ฆฌ ์์ฑ
โข ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์กด์ฑ ์ ๊ฑฐ
โข ํฌ๋ก์ค ์ปดํ์ผ์ด ๋ ์์ ์
โข ๋ฐฐํฌ๊ฐ ํจ์ฌ ๊ฐ๋จํด์ง
ํนํ Docker ์ปจํ ์ด๋๋ก ๋ฐฐํฌํ ๋ CGO_ENABLED=0์ผ๋ก ๋น๋ํ๋ฉด, scratch ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ ์ ์์ด์ ์ปจํ ์ด๋ ํฌ๊ธฐ๊ฐ ์์ฒญ ์์์ ธ! ๐ณ
๐ค ์๋ํ ์คํฌ๋ฆฝํธ ๋ง๋ค๊ธฐ
๋งค๋ฒ ์ฌ๋ฌ ํ๋ซํผ์ฉ์ผ๋ก ๋น๋ํ๋ ๊ฒ ๊ท์ฐฎ๋ค๋ฉด? ์คํฌ๋ฆฝํธ๋ก ์๋ํํ๋ฉด ๋ผ! ๐
์ฌ๋ฅ๋ท์์ ํ๋ก์ ํธ๋ฅผ ๊ณต์ ํ ๋๋ ์ด๋ฐ ์๋ํ ์คํฌ๋ฆฝํธ๊ฐ ์์ผ๋ฉด ์ ๋ง ํธ๋ฆฌํด.
๐ Bash ์คํฌ๋ฆฝํธ ์์
#!/bin/bash
# build.sh
APP_NAME="myapp"
VERSION="1.0.0"
BUILD_DIR="./build"
# ๋น๋ ๋๋ ํ ๋ฆฌ ์์ฑ
mkdir -p $BUILD_DIR
# ํ๋ซํผ ๋ชฉ๋ก
platforms=(
"windows/amd64"
"windows/386"
"darwin/amd64"
"darwin/arm64"
"linux/amd64"
"linux/386"
"linux/arm"
"linux/arm64"
)
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
output_name=$APP_NAME'-'$VERSION'-'$GOOS'-'$GOARCH
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
echo "Building for $GOOS/$GOARCH..."
env GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=0 go build \
-ldflags="-s -w -X main.version=$VERSION" \
-o $BUILD_DIR/$output_name \
main.go
if [ $? -ne 0 ]; then
echo "Failed to build for $GOOS/$GOARCH"
exit 1
fi
done
echo "Build completed successfully!"
์ด ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ฉด ๋ชจ๋ ํ๋ซํผ์ฉ ๋ฐ์ด๋๋ฆฌ๊ฐ build ํด๋์ ์์ฑ๋ผ! ์ ๋ง ํธ๋ฆฌํ์ง? ๐
๐ฏ Makefile ํ์ฉํ๊ธฐ
Makefile์ ์ฌ์ฉํ๋ฉด ๋ ์ฒด๊ณ์ ์ผ๋ก ๋น๋ ํ๋ก์ธ์ค๋ฅผ ๊ด๋ฆฌํ ์ ์์ด.
# Makefile
APP_NAME := myapp
VERSION := 1.0.0
BUILD_DIR := ./build
.PHONY: all clean windows linux darwin
all: clean windows linux darwin
clean:
rm -rf $(BUILD_DIR)
mkdir -p $(BUILD_DIR)
windows:
GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-windows-amd64.exe
GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-windows-386.exe
linux:
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-linux-amd64
GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-linux-arm64
darwin:
GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-darwin-amd64
GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o $(BUILD_DIR)/$(APP_NAME)-$(VERSION)-darwin-arm64
์ด์ make all ๋ช
๋ น์ด ํ๋๋ก ๋ชจ๋ ํ๋ซํผ์ฉ ๋น๋๋ฅผ ํ ์ ์์ด! ๐
๐ GoReleaser ์ฌ์ฉํ๊ธฐ
๋ ๊ฐ๋ ฅํ ๋๊ตฌ๋ฅผ ์ํ๋ค๋ฉด GoReleaser๋ฅผ ์ถ์ฒํด! ์ด๊ฑด Go ํ๋ก์ ํธ์ ๋ฆด๋ฆฌ์ค๋ฅผ ์๋ํํด์ฃผ๋ ๋๊ตฌ์ผ.
# .goreleaser.yaml
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X main.version={{.Version}}
- -X main.commit={{.Commit}}
- -X main.date={{.Date}}
archives:
- format: tar.gz
name_template: >-
{{ .ProjectName }}_
{{- .Version }}_
{{- .Os }}_
{{- .Arch }}
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
changelog:
sort: asc
GoReleaser๋ฅผ ์ฌ์ฉํ๋ฉด GitHub Release์ ์๋์ผ๋ก ์ ๋ก๋ํ๊ณ , ์ฒดํฌ์ฌ๋ ์์ฑํ๊ณ , ๋ณ๊ฒฝ ๋ก๊ทธ๋ ๋ง๋ค์ด์ค! ์ ๋ง ํธ๋ฆฌํด! ๐
๐ณ Docker์ ํจ๊ป ์ฌ์ฉํ๊ธฐ
์์ฆ์ Docker๋ฅผ ๋ง์ด ์ฌ์ฉํ์์? Go์ ํฌ๋ก์ค ์ปดํ์ผ๊ณผ Docker๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ ๋ง ๊ฐ๋ ฅํด! ๐ช
๐๏ธ ๋ฉํฐ ์คํ ์ด์ง ๋น๋
Go ์ ํ๋ฆฌ์ผ์ด์ ์ Docker๋ก ๋ฐฐํฌํ ๋๋ ๋ฉํฐ ์คํ ์ด์ง ๋น๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๋ฒ ์คํธ ํ๋ํฐ์ค์ผ.
# Dockerfile
# ๋น๋ ์คํ
์ด์ง
FROM golang:1.21-alpine AS builder
WORKDIR /app
# ์์กด์ฑ ๋ค์ด๋ก๋
COPY go.mod go.sum ./
RUN go mod download
# ์์ค ์ฝ๋ ๋ณต์ฌ ๋ฐ ๋น๋
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
-ldflags="-s -w" \
-o myapp \
main.go
# ์คํ ์คํ
์ด์ง
FROM scratch
# ๋น๋๋ ๋ฐ์ด๋๋ฆฌ๋ง ๋ณต์ฌ
COPY --from=builder /app/myapp /myapp
# SSL ์ธ์ฆ์ ๋ณต์ฌ (HTTPS ํต์ ์ด ํ์ํ ๊ฒฝ์ฐ)
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/myapp"]
โจ ๋ฉํฐ ์คํ ์ด์ง ๋น๋์ ์ฅ์
โข ์ต์ข
์ด๋ฏธ์ง ํฌ๊ธฐ๊ฐ ์์ฒญ ์์์ ธ (์ MB ์์ค!)
โข ๋น๋ ๋๊ตฌ๊ฐ ์ต์ข
์ด๋ฏธ์ง์ ํฌํจ๋์ง ์์
โข ๋ณด์์ด ํฅ์๋ผ
โข ๋ฐฐํฌ ์๋๊ฐ ๋นจ๋ผ์ ธ
scratch ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋ง ์ต์ํ์ ํฌ๊ธฐ๋ก Docker ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค ์ ์์ด. 5MB ์ดํ๋ ๊ฐ๋ฅํด! ๐ฏ
๐ ๋ฉํฐ ํ๋ซํผ Docker ์ด๋ฏธ์ง
Docker Buildx๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ์ํคํ ์ฒ์ฉ ์ด๋ฏธ์ง๋ฅผ ํ ๋ฒ์ ๋น๋ํ ์ ์์ด!
# ๋ฉํฐ ํ๋ซํผ ์ด๋ฏธ์ง ๋น๋
docker buildx build \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
-t myapp:latest \
--push \
.
์ด๋ ๊ฒ ํ๋ฉด Intel ์๋ฒ, ARM ์๋ฒ, ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ๋ฑ ๋ค์ํ ํ๊ฒฝ์์ ๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ ์ ์์ด! ๐
๐ฏ ์ค์ ๋ฐฐํฌ ์ ๋ต
์ด์ ์ค์ ๋ก ์ด๋ป๊ฒ ๋ฐฐํฌํ๋์ง ์์๋ณด์! ์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ์ํฉ์ ๋ง๊ฒ ์ ํํ๋ฉด ๋ผ. ๐ฆ
๐ค GitHub Releases ํ์ฉ
์คํ์์ค ํ๋ก์ ํธ๋ผ๋ฉด GitHub Releases๊ฐ ์ ๋ง ์ข์. ์ฌ์ฉ์๋ค์ด ์ฝ๊ฒ ๋ค์ด๋ก๋ํ ์ ์๊ฑฐ๋ !
๐ GitHub Actions ์ํฌํ๋ก์ฐ ์์
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v*'
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: |
mkdir -p dist
# Windows
GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o dist/myapp-windows-amd64.exe
# macOS
GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o dist/myapp-darwin-amd64
GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o dist/myapp-darwin-arm64
# Linux
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o dist/myapp-linux-amd64
GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o dist/myapp-linux-arm64
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: dist/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
์ด๋ ๊ฒ ์ค์ ํ๋ฉด ํ๊ทธ๋ฅผ ํธ์ํ ๋๋ง๋ค ์๋์ผ๋ก ๋ชจ๋ ํ๋ซํผ์ฉ ๋ฐ์ด๋๋ฆฌ๊ฐ ๋น๋๋๊ณ ๋ฆด๋ฆฌ์ค๊ฐ ์์ฑ๋ผ! ์์ ์๋ํ! ๐ค
โ๏ธ ํด๋ผ์ฐ๋ ๋ฐฐํฌ
ํด๋ผ์ฐ๋ ์๋น์ค์ ๋ฐฐํฌํ ๋๋ ํฌ๋ก์ค ์ปดํ์ผ์ด ์ ์ฉํด. ๋ก์ปฌ์์ ๋น๋ํด์ ์ ๋ก๋ํ๋ฉด ๋๊ฑฐ๋ !
๐ฉ๏ธ AWS Lambda
Lambda๋ Linux ํ๊ฒฝ์ด๋๊น:
GOOS=linux GOARCH=amd64
๋ก ๋น๋ํ๊ณ ZIP์ผ๋ก ์์ถํด์ ์
๋ก๋!
โ๏ธ Google Cloud Functions
๋ง์ฐฌ๊ฐ์ง๋ก Linux ํ๊ฒฝ:
GOOS=linux GOARCH=amd64
๋น๋ ํ ๋ฐฐํฌ ๋ช
๋ น์ด ์คํ!
๐ท Azure Functions
Windows๋ Linux ์ ํ ๊ฐ๋ฅ:
GOOS=linux ๋๋
GOOS=windows
๐ ์ผ๋ฐ ์๋ฒ
์๋ฒ OS์ ๋ง์ถฐ ๋น๋:
Ubuntu โ GOOS=linux
CentOS โ GOOS=linux
๐ฑ ๋ชจ๋ฐ์ผ ์ฑ ๋ฐฐํฌ
Go๋ก ๋ชจ๋ฐ์ผ ์ฑ๋ ๋ง๋ค ์ ์์ด! gomobile ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ผ.
# gomobile ์ค์น
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
# Android์ฉ ๋น๋
gomobile bind -target=android -o myapp.aar
# iOS์ฉ ๋น๋
gomobile bind -target=ios -o MyApp.framework
์ด๋ ๊ฒ ํ๋ฉด Android์ iOS์์ ์ฌ์ฉํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ฑ๋ผ! ๐ฑ
โ ๏ธ ์ฃผ์์ฌํญ๊ณผ ํธ๋ฌ๋ธ์ํ
ํฌ๋ก์ค ์ปดํ์ผ์ด ํญ์ ์๋ฒฝํ๊ฒ ์๋ํ๋ ๊ฑด ์๋์ผ. ๋ช ๊ฐ์ง ์ฃผ์ํ ์ ๋ค์ด ์์ด! ๐
๐ซ CGO ์ฌ์ฉ ์ ๋ฌธ์
โ ๏ธ CGO ๊ด๋ จ ์ฃผ์์ฌํญ
CGO๋ฅผ ์ฌ์ฉํ๋ ํจํค์ง(์: SQLite ๋๋ผ์ด๋ฒ)๋ฅผ ์ฌ์ฉํ๋ฉด ํฌ๋ก์ค ์ปดํ์ผ์ด ๋ณต์กํด์ ธ.
๊ฐ ํ๋ซํผ๋ณ๋ก C ์ปดํ์ผ๋ฌ๊ฐ ํ์ํ๊ฑฐ๋ .
ํด๊ฒฐ ๋ฐฉ๋ฒ:
โข ์์ Go ๊ตฌํ ํจํค์ง ์ฌ์ฉ (์: modernc.org/sqlite)
โข Docker๋ฅผ ์ฌ์ฉํ ๋น๋ ํ๊ฒฝ ๊ตฌ์ถ
โข ๊ฐ ํ๋ซํผ์์ ์ง์ ๋น๋
๐ ํ์ผ ๊ฒฝ๋ก ๋ฌธ์
Windows์ Unix ๊ณ์ด OS๋ ํ์ผ ๊ฒฝ๋ก ๊ตฌ๋ถ์๊ฐ ๋ฌ๋ผ. Windows๋ ๋ฐฑ์ฌ๋์(\), Unix๋ ์ฌ๋์(/)๋ฅผ ์ฌ์ฉํด.
// ์๋ชป๋ ๋ฐฉ๋ฒ
path := "config\\app.json" // Windows์์๋ง ์๋
// ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ
import "path/filepath"
path := filepath.Join("config", "app.json") // ๋ชจ๋ OS์์ ์๋
filepath ํจํค์ง๋ฅผ ์ฌ์ฉํ๋ฉด OS์ ๋ง๋ ๊ฒฝ๋ก๋ฅผ ์๋์ผ๋ก ์์ฑํด์ค! ๐
๐ญ ํ๋ซํผ๋ณ ๋์ ์ฐจ์ด
์ผ๋ถ ๊ธฐ๋ฅ์ ํ๋ซํผ๋ง๋ค ๋ค๋ฅด๊ฒ ๋์ํ ์ ์์ด. ํนํ ์์คํ ์ฝ์ด๋ ๋คํธ์ํฌ ๊ด๋ จ ๊ธฐ๋ฅ๋ค์ด ๊ทธ๋.
package main
import (
"fmt"
"runtime"
)
func main() {
switch runtime.GOOS {
case "windows":
// Windows ์ ์ฉ ๋ก์ง
fmt.Println("Running on Windows")
case "darwin":
// macOS ์ ์ฉ ๋ก์ง
fmt.Println("Running on macOS")
case "linux":
// Linux ์ ์ฉ ๋ก์ง
fmt.Println("Running on Linux")
default:
fmt.Println("Unknown OS")
}
}
runtime.GOOS๋ฅผ ์ฌ์ฉํ๋ฉด ์คํ ์ค์ธ OS๋ฅผ ํ์ธํ ์ ์์ด!
๐งช ํ ์คํธ์ ์ค์์ฑ
๐ฏ ๋ฐ๋์ ์ค์ ํ๊ฒฝ์์ ํ ์คํธํ๊ธฐ!
ํฌ๋ก์ค ์ปดํ์ผ๋ก ๋ง๋ ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ก์ปฌ์์ ์ ์๋ํ๋ค๊ณ ํด์ ํ๊ฒ ํ๋ซํผ์์๋ ์ ์๋ํ๋ค๋ ๋ณด์ฅ์ ์์ด.
ํนํ ๋ค์ ์ฌํญ๋ค์ ๊ผญ ํ์ธํด์ผ ํด:
โข ํ์ผ ์์คํ
๊ถํ
โข ๋คํธ์ํฌ ์ค์
โข ํ๊ฒฝ ๋ณ์
โข ์ธ๋ถ ์์กด์ฑ
โข ์์คํ
๋ฆฌ์์ค
๐ ๋๋ฒ๊น ํ
ํฌ๋ก์ค ์ปดํ์ผ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋๋ฒ๊น ํ๊ธฐ ์ด๋ ค์ธ ๋๋ ์ด๋ ๊ฒ ํด๋ด:
// ์์ธํ ๋ก๊น
์ถ๊ฐ
import "log"
log.SetFlags(log.LstdFlags | log.Lshortfile)
log.Printf("OS: %s, Arch: %s", runtime.GOOS, runtime.GOARCH)
// ํจ๋ ๋ณต๊ตฌ
defer func() {
if r := recover(); r != nil {
log.Printf("Panic recovered: %v", r)
}
}()
๐จ ์ค์ ํ๋ก์ ํธ ์์
์ด๋ก ๋ง ๋ฐฐ์ฐ๋ฉด ์ฌ๋ฏธ์์์? ์ค์ ๋ก ์ฌ์ฉํ ์ ์๋ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด์! ๐ ๏ธ
๐ ์์คํ ๋ชจ๋ํฐ๋ง ๋๊ตฌ
์ฌ๋ฌ ํ๋ซํผ์์ ์๋ํ๋ ๊ฐ๋จํ ์์คํ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ฅผ ๋ง๋ค์ด๋ณผ๊ฒ.
// main.go
package main
import (
"fmt"
"runtime"
"time"
)
type SystemInfo struct {
OS string
Architecture string
NumCPU int
GoVersion string
}
func getSystemInfo() SystemInfo {
return SystemInfo{
OS: runtime.GOOS,
Architecture: runtime.GOARCH,
NumCPU: runtime.NumCPU(),
GoVersion: runtime.Version(),
}
}
func getMemoryStats() runtime.MemStats {
var m runtime.MemStats
runtime.ReadMemStats(&m)
return m
}
func main() {
info := getSystemInfo()
fmt.Println("=== System Information ===")
fmt.Printf("OS: %s\n", info.OS)
fmt.Printf("Architecture: %s\n", info.Architecture)
fmt.Printf("CPU Cores: %d\n", info.NumCPU)
fmt.Printf("Go Version: %s\n", info.GoVersion)
fmt.Println("\n=== Memory Statistics ===")
for {
mem := getMemoryStats()
fmt.Printf("\rAlloc: %d MB | TotalAlloc: %d MB | Sys: %d MB | NumGC: %d",
mem.Alloc/1024/1024,
mem.TotalAlloc/1024/1024,
mem.Sys/1024/1024,
mem.NumGC)
time.Sleep(1 * time.Second)
}
}
์ด ํ๋ก๊ทธ๋จ์ ์ฌ๋ฌ ํ๋ซํผ์ฉ์ผ๋ก ๋น๋ํด๋ณด์!
#!/bin/bash
# build-monitor.sh
APP="sysmonitor"
VERSION="1.0.0"
# Windows
GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o ${APP}-windows.exe
# macOS
GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o ${APP}-mac-intel
GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o ${APP}-mac-arm
# Linux
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ${APP}-linux
echo "Build completed!"
๐ ๊ฐ๋จํ ์น ์๋ฒ
ํฌ๋ก์ค ํ๋ซํผ ์น ์๋ฒ๋ ๋ง๋ค์ด๋ณด์!
// server.go
package main
import (
"fmt"
"log"
"net/http"
"runtime"
)
func handler(w http.ResponseWriter, r *http.Request) {
info := fmt.Sprintf(`
<h1>Hello from Go Server!</h1>
<p>OS: %s</p>
<p>Architecture: %s</p>
<p>Go Version: %s</p>
<p>Request from: %s</p>
`, runtime.GOOS, runtime.GOARCH, runtime.Version(), r.RemoteAddr)
fmt.Fprintf(w, info)
}
func main() {
http.HandleFunc("/", handler)
port := ":8080"
fmt.Printf("Server starting on http://localhost%s\n", port)
fmt.Printf("OS: %s, Arch: %s\n", runtime.GOOS, runtime.GOARCH)
if err := http.ListenAndServe(port, nil); err != nil {
log.Fatal(err)
}
}
์ด ์๋ฒ๋ฅผ ๋ค์ํ ํ๋ซํผ์ ๋ฐฐํฌํ๋ฉด, ๊ฐ ํ๊ฒฝ์์ ๋์ผํ๊ฒ ์๋ํด! ์ ๋ง ํธ๋ฆฌํ์ง? ๐
๐ฎ ๊ณ ๊ธ ํ์ฉ ์ฌ๋ก
์ด์ ์ข ๋ ๊ณ ๊ธ ๊ธฐ์ ๋ค์ ์์๋ณด์! ์ค๋ฌด์์ ์ ๋ง ์ ์ฉํ ํ๋ค์ด์ผ. ๐
๐ญ ์กฐ๊ฑด๋ถ ์ปดํ์ผ ๊ณ ๊ธ ํ์ฉ
๋น๋ ํ๊ทธ๋ฅผ ์กฐํฉํ๋ฉด ์ ๋ง ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋ง๋ค ์ ์์ด!
// config_dev.go
//go:build dev
package main
const (
APIEndpoint = "http://localhost:8080"
Debug = true
)
// config_prod.go
//go:build prod
package main
const (
APIEndpoint = "https://api.production.com"
Debug = false
)
# ๊ฐ๋ฐ ํ๊ฒฝ ๋น๋
go build -tags dev -o myapp-dev
# ํ๋ก๋์
ํ๊ฒฝ ๋น๋
go build -tags prod -o myapp-prod
์ด๋ ๊ฒ ํ๋ฉด ํ๊ฒฝ๋ณ๋ก ๋ค๋ฅธ ์ค์ ์ ์ฝ๊ฒ ๊ด๋ฆฌํ ์ ์์ด! ๐ฏ
๐ ํ๋ฌ๊ทธ์ธ ์์คํ
Go์ plugin ํจํค์ง๋ฅผ ์ฌ์ฉํ๋ฉด ๋์ ์ผ๋ก ๋ก๋๋๋ ํ๋ฌ๊ทธ์ธ์ ๋ง๋ค ์ ์์ด.
ํ์ง๋ง ์ฃผ์ํ ์ ์ด ์์ด - ํ๋ฌ๊ทธ์ธ์ ๊ฐ์ ํ๋ซํผ์์๋ง ์๋ํด!
// plugin.go
package main
import "fmt"
func Hello() {
fmt.Println("Hello from plugin!")
}
// ํ๋ฌ๊ทธ์ธ ๋น๋ (Linux/macOS๋ง ์ง์)
go build -buildmode=plugin -o plugin.so plugin.go
๐ก ํ๋ฌ๊ทธ์ธ ๋์
Windows์์๋ plugin ํจํค์ง๊ฐ ์ง์๋์ง ์์. ๋์ ๋ค์ ๋ฐฉ๋ฒ๋ค์ ๊ณ ๋ คํด๋ด:
โข gRPC๋ฅผ ์ฌ์ฉํ ๋ง์ดํฌ๋ก์๋น์ค
โข WebAssembly ๋ชจ๋
โข ๋ณ๋ ํ๋ก์ธ์ค๋ก ์คํ
๐ ๊ตญ์ ํ(i18n) ์ง์
์ฌ๋ฌ ๋๋ผ์ ๋ฐฐํฌํ ๋๋ ๊ตญ์ ํ๊ฐ ์ค์ํด!
package main
import (
"fmt"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
func main() {
// ํ๊ตญ์ด
p := message.NewPrinter(language.Korean)
p.Printf("์๋
ํ์ธ์! ์ซ์: %d\n", 1234567)
// ์์ด
p = message.NewPrinter(language.English)
p.Printf("Hello! Number: %d\n", 1234567)
// ์ผ๋ณธ์ด
p = message.NewPrinter(language.Japanese)
p.Printf("ใใใซใกใฏ! ๆฐๅญ: %d\n", 1234567)
}
์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ์ง์ญ์ ๋ง๋ ํ์์ผ๋ก ์ถ๋ ฅํ ์ ์์ด! ๐
๐ ์ฑ๋ฅ ์ต์ ํ ํ
ํฌ๋ก์ค ์ปดํ์ผ๋ ๋ฐ์ด๋๋ฆฌ์ ์ฑ๋ฅ์ ์ต๋ํ ๋์ด์ฌ๋ฆฌ๋ ๋ฐฉ๋ฒ๋ค์ ์์๋ณด์! โก
๐ฏ ์ปดํ์ผ๋ฌ ์ต์ ํ ์ต์
# ๊ธฐ๋ณธ ์ต์ ํ
go build -ldflags="-s -w" -o myapp
# ๋ ๊ณต๊ฒฉ์ ์ธ ์ต์ ํ
go build -ldflags="-s -w" -gcflags="all=-l -B" -o myapp
# ์ธ๋ผ์ด๋ ๋นํ์ฑํ (๋๋ฒ๊น
์ฉ)
go build -gcflags="all=-N -l" -o myapp-debug
๐ฏ gcflags ์ต์ ์ค๋ช
-l: ์ธ๋ผ์ด๋ ๋นํ์ฑํ
-N: ์ต์ ํ ๋นํ์ฑํ
-B: ๋ฐ์ด๋ ์ฒดํฌ ๋นํ์ฑํ (์ํํ ์ ์์!)
ํ๋ก๋์
์์๋ -s -w๋ง ์ฌ์ฉํ๋ ๊ฒ ์์ ํด. ๋ค๋ฅธ ์ต์
๋ค์ ์ ์คํ๊ฒ ์ฌ์ฉํด์ผ ํด!
๐ฆ ๋ฐ์ด๋๋ฆฌ ์์ถ
๋น๋๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ UPX๋ก ์์ถํ๋ฉด ํฌ๊ธฐ๋ฅผ ๋ ์ค์ผ ์ ์์ด!
# UPX ์ค์น (macOS)
brew install upx
# UPX ์ค์น (Linux)
apt-get install upx
# ๋ฐ์ด๋๋ฆฌ ์์ถ
upx --best --lzma myapp
# ์์ถ ์ ํ ๋น๊ต
ls -lh myapp*
โ ๏ธ UPX ์ฌ์ฉ ์ ์ฃผ์์ฌํญ
โข ์ผ๋ถ ์ํฐ๋ฐ์ด๋ฌ์ค๊ฐ ์คํํ ์ ์์ด
โข ์คํ ์ ์์ถ ํด์ ์๊ฐ์ด ์ถ๊ฐ๋ผ
โข ๋๋ฒ๊น
์ด ์ด๋ ค์์ ธ
โข ๋ชจ๋ ํ๋ซํผ์์ ์๋ํ์ง ์์ ์ ์์ด
๐ ๋ณ๋ ฌ ๋น๋
์ฌ๋ฌ ํ๋ซํผ์ ๋์์ ๋น๋ํ๋ฉด ์๊ฐ์ ๋ง์ด ์ ์ฝํ ์ ์์ด!
#!/bin/bash
# parallel-build.sh
build_platform() {
local GOOS=$1
local GOARCH=$2
local output="myapp-${GOOS}-${GOARCH}"
if [ "$GOOS" = "windows" ]; then
output="${output}.exe"
fi
echo "Building for $GOOS/$GOARCH..."
GOOS=$GOOS GOARCH=$GOARCH go build -ldflags="-s -w" -o "dist/$output" main.go
echo "โ Completed $GOOS/$GOARCH"
}
# ๋ณ๋ ฌ ์คํ
build_platform "windows" "amd64" &
build_platform "darwin" "amd64" &
build_platform "darwin" "arm64" &
build_platform "linux" "amd64" &
# ๋ชจ๋ ๋น๋๊ฐ ์๋ฃ๋ ๋๊น์ง ๋๊ธฐ
wait
echo "All builds completed!"
๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ๋ฉด ๋น๋ ์๊ฐ์ด ํฌ๊ฒ ๋จ์ถ๋ผ! โฑ๏ธ
๐ก๏ธ ๋ณด์ ๊ณ ๋ ค์ฌํญ
๋ฐฐํฌํ ๋๋ ๋ณด์๋ ์ ๋ง ์ค์ํด! ๋ช ๊ฐ์ง ์ฒดํฌ๋ฆฌ์คํธ๋ฅผ ์์๋ณด์. ๐
๐ ๋ฏผ๊ฐํ ์ ๋ณด ์ ๊ฑฐ
// ์๋ชป๋ ๋ฐฉ๋ฒ โ
const APIKey = "sk-1234567890abcdef"
// ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ โ
import "os"
apiKey := os.Getenv("API_KEY")
if apiKey == "" {
log.Fatal("API_KEY environment variable is required")
}
์ ๋๋ก API ํค๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฝ๋์ ํ๋์ฝ๋ฉํ๋ฉด ์ ๋ผ! ํ๊ฒฝ๋ณ์๋ ์ค์ ํ์ผ์ ์ฌ์ฉํด์ผ ํด.
๐ญ ๋ฐ์ด๋๋ฆฌ ๋๋ ํ
Go ๋ฐ์ด๋๋ฆฌ๋ ๋ฆฌ๋ฒ์ค ์์ง๋์ด๋ง์ด ๋น๊ต์ ์ฌ์ด ํธ์ด์ผ. ์ค์ํ ๋ก์ง์ด ์๋ค๋ฉด ๋๋ ํ๋ฅผ ๊ณ ๋ คํด๋ด.
# garble์ ์ฌ์ฉํ ๋๋
ํ
go install mvdan.cc/garble@latest
garble -literals -tiny build -o myapp-obfuscated main.go
๐ garble ์ต์
-literals: ๋ฌธ์์ด ๋ฆฌํฐ๋ด ๋๋
ํ
-tiny: ๋ฐ์ด๋๋ฆฌ ํฌ๊ธฐ ์ต์ํ
-seed: ์ฌํ ๊ฐ๋ฅํ ๋น๋๋ฅผ ์ํ ์๋
โ ์ฒดํฌ์ฌ ์์ฑ
๋ฐฐํฌํ ๋ฐ์ด๋๋ฆฌ์ ๋ฌด๊ฒฐ์ฑ์ ํ์ธํ ์ ์๋๋ก ์ฒดํฌ์ฌ์ ์ ๊ณตํ๋ ๊ฒ ์ข์!
#!/bin/bash
# generate-checksums.sh
cd dist
# SHA256 ์ฒดํฌ์ฌ ์์ฑ
for file in *; do
if [ -f "$file" ]; then
sha256sum "$file" >> checksums.txt
fi
done
echo "Checksums generated in checksums.txt"
์ฌ์ฉ์๋ค์ ์ด ์ฒดํฌ์ฌ์ผ๋ก ๋ค์ด๋ก๋ํ ํ์ผ์ด ๋ณ์กฐ๋์ง ์์๋์ง ํ์ธํ ์ ์์ด! ๐ก๏ธ
๐ ์ค๋ฌด ๋ฒ ์คํธ ํ๋ํฐ์ค
์ง๊ธ๊น์ง ๋ฐฐ์ด ๋ด์ฉ์ ์ข ํฉํด์, ์ค๋ฌด์์ ์ฌ์ฉํ ์ ์๋ ๋ฒ ์คํธ ํ๋ํฐ์ค๋ฅผ ์ ๋ฆฌํด๋ณผ๊ฒ! ๐
๐ ํ๋ก์ ํธ ๊ตฌ์กฐ
myproject/
โโโ cmd/
โ โโโ myapp/
โ โโโ main.go
โโโ internal/
โ โโโ config/
โ โโโ handler/
โ โโโ service/
โโโ pkg/
โ โโโ utils/
โโโ build/
โ โโโ build.sh
โ โโโ Dockerfile
โโโ dist/
โโโ .goreleaser.yaml
โโโ Makefile
โโโ go.mod
โโโ go.sum
์ด๋ฐ ๊ตฌ์กฐ๋ก ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ๋ฉด ๊ด๋ฆฌํ๊ธฐ ์ ๋ง ํธํด! ๐๏ธ
๐ CI/CD ํ์ดํ๋ผ์ธ
์์ ํ CI/CD ํ์ดํ๋ผ์ธ ์์ ๋ฅผ ๋ง๋ค์ด๋ณผ๊ฒ.
# .github/workflows/ci-cd.yml
name: CI/CD Pipeline
on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Run tests
run: go test -v -race -coverprofile=coverage.txt ./...
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage.txt
build:
needs: test
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docker:
needs: test
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
myapp:latest
myapp:${{ github.ref_name }}
์ด๋ ๊ฒ ์ค์ ํ๋ฉด ์ฝ๋๋ฅผ ํธ์ํ ๋๋ง๋ค ์๋์ผ๋ก ํ ์คํธํ๊ณ , ํ๊ทธ๋ฅผ ๋ฌ๋ฉด ์๋์ผ๋ก ๋น๋ํ๊ณ ๋ฐฐํฌํด! ์์ ์๋ํ! ๐ค
๐ ๋ฌธ์ํ
README์ ํ๋ซํผ๋ณ ์ค์น ๋ฐฉ๋ฒ์ ๋ช ํํ๊ฒ ์์ฑํ๋ ๊ฒ ์ค์ํด!
# MyApp
## Installation
### Windows
```powershell
# Download the latest release
curl -LO https://github.com/user/myapp/releases/latest/download/myapp-windows-amd64.exe
# Run
.\myapp-windows-amd64.exe
```
### macOS
```bash
# Intel Mac
curl -LO https://github.com/user/myapp/releases/latest/download/myapp-darwin-amd64
chmod +x myapp-darwin-amd64
./myapp-darwin-amd64
# Apple Silicon (M1/M2)
curl -LO https://github.com/user/myapp/releases/latest/download/myapp-darwin-arm64
chmod +x myapp-darwin-arm64
./myapp-darwin-arm64
```
### Linux
```bash
curl -LO https://github.com/user/myapp/releases/latest/download/myapp-linux-amd64
chmod +x myapp-linux-amd64
./myapp-linux-amd64
```
## Docker
```bash
docker run -it myapp:latest
```
์ฌ์ฉ์๋ค์ด ์ฝ๊ฒ ๋ฐ๋ผํ ์ ์๋๋ก ๋ช ํํ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํ๋ ๊ฒ ์ค์ํด! ๐
๐ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์! ์ฌ๊ธฐ๊น์ง ์ ๋ง ๊ธด ์ฌ์ ์ด์์ด. Go์ ํฌ๋ก์ค ์ปดํ์ผ์ ๋ํด ์ ๋ง ๋ง์ ๊ฑธ ๋ฐฐ์ ์ง? ๐
โจ ํต์ฌ ์์ฝ
1. ๊ฐ๋จํ ํฌ๋ก์ค ์ปดํ์ผ
GOOS์ GOARCH ํ๊ฒฝ๋ณ์๋ง ์ค์ ํ๋ฉด ๋!
2. ์๋ํ๊ฐ ํต์ฌ
์คํฌ๋ฆฝํธ, Makefile, GoReleaser๋ก ๋น๋ ํ๋ก์ธ์ค๋ฅผ ์๋ํํ์.
3. Docker์์ ์กฐํฉ
๋ฉํฐ ์คํ
์ด์ง ๋น๋๋ก ์ต์ ํฌ๊ธฐ์ ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค ์ ์์ด.
4. CI/CD ํตํฉ
GitHub Actions ๋ฑ์ผ๋ก ์์ ์๋ํ๋ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ์.
5. ๋ณด์๊ณผ ํ
์คํธ
ํญ์ ์ค์ ํ๊ฒฝ์์ ํ
์คํธํ๊ณ , ๋ณด์์ ๊ณ ๋ คํ์.
Go์ ํฌ๋ก์ค ์ปดํ์ผ ๊ธฐ๋ฅ์ ์ ๋ง ๊ฐ๋ ฅํด. ํ ๋ฒ์ ๋น๋๋ก ๋ชจ๋ ํ๋ซํผ์ ์ง์ํ ์ ์๋ค๋ ๊ฑด ์์ฒญ๋ ์ฅ์ ์ด์ผ! ๐
ํนํ ์คํ์์ค ํ๋ก์ ํธ๋ CLI ๋๊ตฌ๋ฅผ ๋ง๋ค ๋ ์ด ๊ธฐ๋ฅ์ด ๋น์ ๋ฐํด.
์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ํ๋ก๊ทธ๋๋ฐ ์ฌ๋ฅ์ ๊ณต์ ํ ๋๋, ์ด๋ฐ ํฌ๋ก์ค ์ปดํ์ผ ๊ธฐ์ ์ ํ์ฉํ๋ฉด ๋ ๋ง์ ์ฌ์ฉ์๋ค์๊ฒ ๋๋ฌํ ์ ์์ด.
Windows ์ฌ์ฉ์๋ , Mac ์ฌ์ฉ์๋ , Linux ์ฌ์ฉ์๋ ๋ชจ๋๊ฐ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์๊ฑฐ๋ ! ๐ช
๐ฏ ๋ค์ ๋จ๊ณ
์ด์ ์ง์ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด๋ฉด์ ์ค์ตํด๋ณด๋ ๊ฒ ์ค์ํด!
๊ฐ๋จํ CLI ๋๊ตฌ๋ถํฐ ์์ํด์, ์ ์ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์
์ผ๋ก ๋ฐ์ ์์ผ๋ณด์.
โข ๊ฐ๋จํ ํ์ผ ๋ณํ ๋๊ตฌ
โข ์์คํ
๋ชจ๋ํฐ๋ง ์ ํธ๋ฆฌํฐ
โข ์น ์๋ฒ๋ API ์๋ฒ
โข ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ
๋ญ๋ ๋ง๋ค์ด๋ณด๋ฉด์ ๋ฐฐ์ฐ๋ ๊ฒ ์ต๊ณ ์ผ! ๐จ
Go์ ํฌ๋ก์ค ์ปดํ์ผ์ ์ฒ์์๋ ๋ณต์กํด ๋ณด์ผ ์ ์์ง๋ง, ํ๋ฒ ์ต์ํด์ง๋ฉด ์ ๋ง ํธ๋ฆฌํด.
๋ ์ด์ ์ฌ๋ฌ ์ปดํจํฐ๋ฅผ ์ค๊ฐ๋ฉฐ ๋น๋ํ ํ์๊ฐ ์์ด. ๋ด ๋งฅ๋ถ์์ ๋ชจ๋ ํ๋ซํผ์ฉ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ง๋ค ์ ์์ผ๋๊น! โจ
์ด ๊ธ์ด Go ํฌ๋ก์ค ์ปดํ์ผ์ ์์ํ๋ ๋ฐ ๋์์ด ๋์์ผ๋ฉด ์ข๊ฒ ์ด.
๊ถ๊ธํ ์ ์ด ์๊ฑฐ๋ ๋ ์๊ณ ์ถ์ ๋ด์ฉ์ด ์๋ค๋ฉด, Go ์ปค๋ฎค๋ํฐ์ ์ฐธ์ฌํด์ ๋ฌผ์ด๋ณด๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ! ๐ค
์, ์ด์ ๋น์ ์ Go ํ๋ก์ ํธ๋ฅผ ์ ์ธ๊ณ ๋ชจ๋ ํ๋ซํผ์ ๋ฐฐํฌํด๋ณด์! ๐
Happy coding! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.