Docker ile Go Programlama Dilinde Basit İnşa Süreci
--
Bu makalede, Docker kullanarak Go programlama dilinde basit bir inşa süreci açıklayacağım. İlk olarak, Docker’ın ne olduğu ve neden kullanıldığına kısaca değineceğim, ardından basit bir programın yazılmasını ele alacağım. Daha sonra, Dockerfile ve docker-compose adı verilen dosyaların nasıl oluşturulacağı ve Docker ile Go programının nasıl inşa edileceği anlatacağım.
Docker Nedir ?
Docker, uygulamaları ve servisleri bir çevre birimine paketleyen ve bu çevre birimini değiştirebilir kılan açık kaynaklı bir platformdur. Docker konteynerlerinin kullanımı, uygulamaların farklı ortamlarda sorunsuz bir şekilde çalışmasını sağlar.
Docker Neden Kullanılır ?
Docker, uygulama geliştirme ve dağıtım sürecini basitleştirmek için kullanılır. Docker konteynerleri, bir uygulamanın tüm bağımlılıklarını ve çalıştırılması gereken diğer yazılım bileşenlerini içerir. Bu nedenle, uygulama Docker konteynerinde paketlendiğinde, uygulama farklı bir ortamda çalıştırıldığında bile aynı şekilde çalışır.
Docker kullanımı, uygulama geliştiricilerinin uygulamalarını geliştirdikleri ortamdan, test edildiği ve dağıtıldığı ortama kadar her adımda aynı ortamı kullanmalarını sağlar. Bu, geliştiricilerin ve operasyonel ekiplerin birlikte çalışmasını kolaylaştırır ve uygulama hatalarının daha hızlı bir şekilde tespit edilip çözülmesini sağlar.
Ayrıca, Docker konteynerleri, sunucuların kaynak kullanımını optimize eder ve sunucu hızını artırır. Docker konteynerleri, sanal makinelerden daha hafiftir ve daha az kaynak tüketirler, bu nedenle bir sunucuda daha fazla konteyner çalıştırılabilir.
Sonuç olarak, Docker, uygulama geliştirme ve dağıtım sürecini kolaylaştıran, uygulamaların farklı ortamlarda sorunsuz bir şekilde çalışmasını sağlayan ve sunucu kaynaklarının verimli kullanımını sağlayan bir platformdur.
Aşağıda basit bir golang proje dosyaları oluşturulmuştur. Burada kurulumları atlayacağım.
Kullanılan Paketler
mkdir go-docker
cd go-docker
mkdir database
cd database
touch database.go
//database.go dosyamızı aşağıdaki gibi satır satır yazıyoruz.
package database
import (
"go-docker/model"
"log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var instance *gorm.DB
var dbError error
func Connect(connectionString string) {
instance, dbError = gorm.Open(mysql.Open(connectionString), &gorm.Config{})
if dbError != nil {
panic("Failed to connect to database!")
}
log.Println("Connected to Database!")
}
func Migrate() {
instance.AutoMigrate(&model.User{})
}
mkdir model
cd model
touch user.go
//user.go dosyamızı aşağıdaki gibi satır satır yazıyoruz.
package model
import (
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string `json:"name"`
Username string `json:"username" gorm:"unique"`
Email string `json:"email" gorm:"unique"`
Password string `json:"password"`
}
type LoginRequest struct {
Email string `json:"email"`
Password string `json:"password"`
}
func (user *User) HashPassword(password string) error {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
if err != nil {
return err
}
user.Password = string(bytes)
return nil
}
func (user *User) CheckPassword(providedPassword string) error {
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(providedPassword))
if err != nil {
return err
}
return nil
}
touch main.go
//main.go dosyamızı aşağıdaki gibi satır satır yazıyoruz.
package main
import (
"go-docker/database"
"log"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
database.Connect("root:example@tcp(godockerDB)/golang?parseTime=true")
database.Migrate()
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("I'm a GET request!")
})
log.Fatal(app.Listen(":3000"))
}
touch Dockerfile
touch docker-compose.yml
Dockerfile
Bir imajın tanımlanmalarını yaptığımız dosyalara denilir. Projemizin bulunduğu dizinde Dockerfile isimli dosyamızı olduşturduk, bu dosyanın içerisine satır satır ne yapmak istediğimizi yazıyoruz.
FROM golang:1.19 AS builder
WORKDIR /app/go-docker
RUN go install github.com/cosmtrek/air@latest
COPY go.mod .
RUN go mod download
COPY . .
RUN go build -o ./out/go-docker
EXPOSE 3000
CMD ["air", "-c", ".air.toml"]
FROM: Yapının hangi temel imajdan oluşturulacağını belirler. Bu durumda, golang:1.19
resmi Golang imajının 1.19 sürümünü temel alınarak bir imaj oluşturulacak.
AS: Bu, yapı aşamalarının adlandırılmasını sağlar. Bu örnekte, “builder” adında bir aşama oluşturuluyor.
WORKDIR: Çalışma dizininin belirlenmesini sağlar. Bu durumda, /app/go-docker
klasörü çalışma dizini olarak belirlenmiştir.
RUN: Bu anahtar, Dockerfile’da yürütülecek komutları belirtir. Bu Dockerfile’da kullanılan RUN komutları, go install
ve go build
komutlarıdır.
go install
komutu, github.com/cosmtrek/air
paketini yükler.
go mod download
komutu, proje bağımlılıklarının indirilmesini sağlar.
go build
komutu, projeyi derleyerek /out/go-docker
klasörüne yerleştirir.
COPY: Bu anahtar, dosyaları Docker imajına kopyalamak için kullanılır. Bu durumda, go.mod
ve proje dosyaları kopyalanır.
EXPOSE: Bu, Docker konteynerinin hangi portlarını dinlemesi gerektiğini belirler. Bu durumda, konteyner 3000 numaralı bağlantı noktasında dinlemeli.
CMD: Bu anahtar, konteyner çalıştırıldığında yürütülecek komutu belirler. Bu durumda, air
uygulaması -c .air.toml
seçeneği ile çalıştırılacaktır.
docker build -t go-docker .
Bu komut ile bulunduğumuz dizindeki tüm dosyaları ve Dockerfile içeriğini Docker Engine üzerine gönderdik.
docker image ls
Bilgisayarımızdaki imajların listesini elde ettik. Bu çıktıda gözümüze çarpan bazı anahtar kelimeleri aşağıda açıklıyoruz.
REPOSITORY: Bu alanda imajın ismi yer alıyor. Eğer bir sunucu adresi yoksa Docker Hub varsayılan olarak kullanılır.
TAG: Bu alan en önemli kısımlardan biri imajın o sürümüne ait bir isim varsa o yer alır. Bunu belirtmediğimiz sürece otomatik olarak latest değeri varsayılan olarak kullanılır.
docker build -t go-docker:0.0.1 //bu şekilde sürüm belirtebilirdik.
IMAGE ID: Imajı tanımlayan 256 bitlik bir numaradır.
CREATED: imajın ne zaman oluşturulduğunu tutar.
SIZE: imajın toplam boyutunu tutar.
docker ps
Bu komutu kullanarak o an açık konteynırları görebiliriz. Eğer hepsini görmek istiyorsak -a parametresini eklemeliyiz. Yine bu komut çıktısını ele alalım.
CONTAINER ID: Konteynır için üretilen bir numaradır.
IMAGE: Konteynırın hangi imajdan üretildiğini gösterir.
COMMAND: Konteynır çalışırken hangi komutun çalıştırıldığını bize gösterir.
STATUS: Konteynır o an hangi durumda olduğunu bize gösterir.
Docker-compose dosyamıza geçmeden, docker komutlarıyla ilgili bir kaç ipucu daha aşağıda sizinle paylaşıyorum.
docker rm name
//Bu komutu kullanarak bir konteynırı silebiliriz.
docker rm $(docker ps -a -q)
//Bu komutu kullanarak tüm konteynırları silebiliriz.
//docker ps -a -q komutu tüm konteynırların ID değerlerini bize verir.
//force-remove için ise rm 'den sonra -f ile gönderin.
Docker-compose
Kompleks uygulamaların tanımlanmasına ve çalıştırılmasına yardımcı olan bir docker aracıdır. Birden fazla container tanımlaması yapabilir, tek bir komutla uygulamamızın ihtiyaç duyduğu tüm gereksinimleri ayağa kaldırabiliriz.
version: '3'
services:
api:
image: go-docker
ports:
- 3000:3000
volumes:
- .:/app/go-docker
depends_on:
- db
command: air
db:
image: mysql:latest
container_name: godockerDB
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: example
ports:
- 3306:3306
volumes:
- database:/var/lib/mysql
volumes:
database:
version: Docker Compose dosyasının sürüm numarası. Bu, dosyanın hangi sözdizimini kullandığını belirtir.
services: Docker Compose’un başlatacağı tüm hizmetlerin tanımlandığı bölüm. Bu, birden fazla hizmeti içerebilir.
image: Hizmetin temel alınacak Docker imajının adı. Bu imaj, Docker hub’dan veya yerel bir kaynaktan gelebilir.
ports: Hizmetin hangi portlar üzerinden yayın yapacağını belirten bir liste.
volumes: Hizmetin kullandığı disk alanının adı ve konumu.
depends_on: Hizmetin başlamadan önce bağımlı olduğu hizmetlerin adını belirten bir liste.
command: Hizmetin başlatılması için kullanılacak komut.
environment: Hizmetin çalıştırılması sırasında belirtilen ortam değişkenlerinin adı ve değeri.
container_name: Hizmetin oluşturulacak Docker konteynerinin adı.
database: Volumes bölümünde tanımlanan “database” adlı disk alanının özellikleri. Bu, tüm hizmetler tarafından kullanılabilir.
docker compose up --build
Yukarıdaki komutu kullanarak konteynırlarımızı çalıştıralım. Aşağıda aktif konteynırlarımızı görüyoruz. Artık http://127.0.0.1:3000/ eriştiğimizde karşıma “I’m a GET request!” çıktısını verecektir.
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
65bedb5a0995 go-docker "air" 2 minutes ago Up 2 minutes 0.0.0.0:3000->3000/tcp go-docker-api-1
72a7bc35d5a4 mysql "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp go-docker-db-1