داکرایز کردن گولنگ با دیتابیس MySQL + Docker Compose

توسعه و تست API‌ ها به‌صورت لوکال که به یک پایگاه داده متصل هستند، کار ساده‌ای نیست و معمولاً پایگاه داده به نقطه دردسر تبدیل می‌شود. اما با استفاده از Docker، این فرآیند ساده‌تر و راحت‌تر شده و امکان تکرار محیط را به‌راحتی فراهم می‌کند. در این پست، خواهیم دید چگونه می‌توانیم یک API نوشته‌شده با Golang را همراه با یک پایگاه داده MySQL داکرایز کنیم و آن را برای Docker Compose آماده کنیم.

خب برای شروع باید یک فایل به نام Dockerfile بسازید و درون اون ما میایم گولنگ خودمون داکرایز میکنیم:

# Build Stage
FROM golang:alpine3.20 AS builder

WORKDIR /build

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

COPY . .
RUN go build -o /app .

# Final Stage
FROM alpine:3.20

COPY --from=builder /app /app
CMD ["/app"]

در بخش FROM مشاهده می‌کنیم که به جای استفاده از یک تصویر کامل Golang، از نسخه golang:alpine به‌عنوان تصویر پایه استفاده کرده‌ایم و مراحل را با برچسب builder نام‌گذاری کرده‌ایم. این نام‌گذاری به ما کمک می‌کند فایل‌ها را از یک مرحله به مرحله دیگر کپی کنیم. پس از آن، یک دایرکتوری کاری ایجاد کردیم. سپس به‌جای کپی کردن تمام فایل‌ها به‌صورت یکجا، فقط فایل‌های go.mod و go.sum را کپی کرده و وابستگی‌ها را نصب کردیم.پ

پس از نصب وابستگی‌ها، باقی فایل‌ها را کپی می‌کنیم. سپس با اجرای دستور go build از کد منبع یک باینری ایجاد می‌کنیم و با استفاده از فلگ -o نام باینری را به مکان فعلی اختصاص می‌دهیم.

حالا قسمت جالب ماجرا اینجاست: در مرحله نهایی نیازی به تصویر Golang یا مشابه آن نداریم. می‌توانیم از یک تصویر پایه Alpine استفاده کنیم، بخاطر اینکه یک باینری داریم که می‌تواند روی هر سیستم لینوکسی، بدون توجه به جزئیات زبان برنامه‌نویسی، اجرا شود. در مرحله بعد، می‌توانیم باینری را از مرحله `builder` به مرحله نهایی کپی کرده و آن را اجرا کنیم.

در قدم بعدی شما باید یک فایل به نام compose.yml بسازید و کد زیر درونش پیاده سازی کنید:

services:
  app:
     container_name: go-api
     build:
       context: .
       dockerfile: Dockerfile
     image: go-api
     ports:
       - 8080:8080
     environment:
       - DB_HOST=mysql
       - DB_PORT=3306
       - DB_USER=user
       - DB_PASSWORD=password
       - DB_NAME=my-database
     depends_on:
       mysql:
         condition: service_healthy
     networks:
       - go-network

  mysql:
    container_name: go-mysql
    image: mysql:9.0
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password
    volumes:
      - dbdata:/var/lib/mysql
    networks:
      - go-network
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  dbdata:

networks:
  go-network:
    driver: bridge

این یک تنظیمات نسبتاً ساده است، اما چند نکته کلیدی وجود دارد که باید ذکر کنم: اگر به مقدار DB_HOST نگاه کنیم، مقدار آن mysql است و خبری از localhost یا آدرس IP نیست، زیرا در Docker Compose سرویس‌ها از طریق نام سرویس با یکدیگر ارتباط برقرار می‌کنند. این قابلیت شبکه‌سازی داخلی توسط Docker Compose به‌صورت پیش‌فرض ارائه می‌شود.

در قدم بعدی نیاز دارید که سرویس هاتون بالا بیارید، برای اینکار شما میتونید دستور زیر در ترمینال خودتون اجرا کنید و منتظر باشید تا عملیات کامل شود:

docker compose up

وقتی عملیات تموم شد برای اینکه ببینید سرویس هاتون فعال هست باید دستور زیر اجرا کنید:

docker ps

حالا باید وارد کانتینر بشیم و برای اینکار دستور زیر میتونید اجرا کنید، ایدی کانتینر هم میتونید با دستور بالا پیدا کنید:

docker exec -it <container-id> sh

بعد از اینکه وارد شدید، میتونید وارد مای اس کیو ال بشید:

mysql -u root -p

بعد از وارد شدن شما باید یک دیتابیس بسازید:

CREATE DATABASE my_database;

حالا برای اعطای مجوزهای مناسب و انجام عملیات، دستور زیر را اجرا کنید:

GRANT ALL PRIVILEGES ON my_database.* TO 'user'@'%';
FLUSH PRIVILEGES;

خب حالا یک بار سرویس هاتون متوقف کنید و دوباره با دستور up ران کنید.

به همین راحتی شما یک پروژه گولنگ با داکر راه اندازی کردید.

1 🔥
1 🎉
0 😮
1 👍
0 💜
1 👏
میلاد خسروی
نویسنده کد نیوز

برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁