آنچه در این مقاله میخوانید
- چرا از Nginx استفاده می کنیم؟!
- nginx-proxy چیست؟
- پیش نیاز ها:
- مرحله اول: راه اندازی یک وب اپلیکیشن ساده با Go
- مرحله دوم: راهاندازی nginx-proxy و Let’s Encrypt برای امنیت اپلیکیشن
- مرحله سوم: داکریزه کردن اپلیکیشن Go
- مرحله چهارم: راه اندازی Docker Compose برای اجرای اپلیکیشن Go
- مرحله چهارم: تست نهایی اپلیکیشن Go در مرورگر
- سوالات متداول:
- جمع بندی
آموزش راهاندازی اپلیکیشن وب Go با Docker و Nginx در اوبونتو 22.04
۱۰ فروردین ۱۴۰۴
Docker یکی از پلتفرمهای پرکاربردی است که برای کانتینر سازی از آن استفاده میشود. این پلتفرم به توسعه دهندگان این اجازه را میدهد که برنامههای خود را همراه با محیط اجرایی شان بسته بندی کنند. این عمل باعث میشود که اجرای برنامه در هر بار اجرا، در یک محیط یکسان باشد و همچنین باعث روند سریع توسعه میشود.
Docker Compose یک ابزار برای مدیریت و هماهنگی در کانتینرها است و از آن استفاده میشود. این ابزار امکان اجرای چندین کانتینر متصل به هم را فراهم میکند. به جای اجرای دستی هر کانتینر، Docker Compose این عمل را به صورت خودکار انجام می دهد.
هاست Docker در لیارا، یک هاست پرسرعت و آماده استفاده، بدون نیاز به تنظیمات پیچیده!
✅ بدون نیاز به پیکربندی ✅ استقرار آسان ✅ سرعت بالا
خرید هاست Docker
آنچه در ادامه خواهید خواند:
- چرا از Nginx استفاده می کنیم؟!
- nginx-proxy چیست؟
- پیش نیاز ها
- مرحله اول: راهاندازی یک وب اپلیکیشن ساده با Go
- مرحله دوم: راهاندازی nginx-proxy و Let’s Encrypt برای امنیت اپلیکیشن
- مرحله سوم: داکریزه کردن اپلیکیشن Go
- مرحله چهارم: تست نهایی اپلیکیشن Go در مرورگر
- سوالات متداول
- جمع بندی
چرا از Nginx استفاده می کنیم؟!
Nginx یک وب سرور بسیار قدرتمند است که از مزایای بسیار زیادی برخوردار است. این مزایا شامل عملکرد بالا، تنظیمات پیشرفته و مدیریت TLS را دارد.
زمانی که از Nginx استفاده می کنید، این وب سرور مسئول انجام کارهای مربوط به رمز نگاری و ارسال درخواستها خواهد بود و اپلیکیشن شما از انجام این پردازش ها آزاد خواهد کرد.
nginx-proxy چیست؟
nginx-proxy یک سیستم خودکار است که برای مدیریت Nginx به عنوان یک پروکسی معکوس یا ریورس پراکسی در محیط Docker از آن استفاده میشود.
این ابزار پیکربندی Nginx را به صورت خودکار انجام میدهد. همچنین افزونه Let’s Encrypt همراه با آن میتواند تولید و تمدید گواهینامههای امنیتی (SSL/TLS) را برای کانتینرها خودکار کند.
در این پروژه، از gorilla/mux به عنوان Router استفاده خواهید کرد، به دلیل اینکه تمامی این کتابخانهها سرعت و انعطاف پذیری بالایی دارند که همین امر آن را به یک گزینه عالی برای مسیریابی در Go تبدیل کرده است.

📍بیشتر بخوانید: داکر (Docker) چیست؟
پیش نیاز ها:
برای پیاده سازی و انجام این راهنما الزامات زیر را فراهم کنید.
- سرور اوبونتو 22.04:
- سرور با سیستم عامل اوبونتو نسخه 22.04
- دسترسی کاربر root
- یک کاربر ثانویه با دسترسی sudo (در این راهنما با نام کاربری sammy در نظر گرفته شده است)
- نرمافزارهای پایه:
- Docker
- Docker Compose
- تنظیمات شبکه:
- یک دامنه ثبتشده معتبر (در این راهنما از your_domain به عنوان مثال استفاده شده است)
- رکورد DNS نوع A که دامنه مذکور را به IP عمومی سرور مرتبط میکند
- پیشنیازهای دانشی:
- آشنایی با مفاهیم پایه Docker و معماری آن
- اطلاعات مقدماتی درباره containerها و ایمیجها
⚠️توجه: رعایت تمامی پیشنیازهای فوق برای اجرای موفقیتآمیز این راهنما الزامی است. در صورت عدم وجود هر یک از موارد، میبایست پیش از ادامه، نسبت به تأمین آنها اقدام نمود.
مرحله اول: راه اندازی یک وب اپلیکیشن ساده با Go
در این مرحله، شما شروع به ساخت یک اپلیکیشن ساده وب با زبان Go میکنید که بعداً آن را در یک کانتینر Docker قرار خواهید داد. این اپلیکیشن از کتابخانه gorilla/mux برای مسیریابی استفاده خواهد کرد، که به دلیل سرعت و انعطافپذیری بالا انتخاب شده است.
ابتدا یک پوشه به نام ~/go-docker
را ایجاد کنید.
mkdir ~/go-docker
سپس به پوشه زیر وارد شوید.
cd ~/go-docker
در این پوشه، فایل اصلی اپلیکیشن خود را با نام main.go
ایجاد کنید.
nano main.go
در این فایل، کد زیر را وارد کنید.
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<h1>This is the homepage. Try /hello and /hello/Sammy\n</h1>")
})
r.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<h1>Hello from Docker!\n</h1>")
})
r.HandleFunc("/hello/{name}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
title := vars["name"]
fmt.Fprintf(w, "<h1>Hello, %s!\n</h1>", title)
})
http.ListenAndServe(":80", r)
}
در این کد، ابتدا بستههای net/http
و gorilla/mux
را وارد کنید که برای راهاندازی سرور HTTP و مسیریابی درخواستها به کار میروند. سپس یک روت جدید به نام r
ایجاد کنید تا بتواند سه مسیر زیر را مدیریت کند:
/
که صفحه اصلی سایت را نمایش میدهد./hello
که پیامی ساده به کاربر نشان میدهد./hello/{name}
که به صورت داینامیک اسم ورودی را دریافت کرده و یک پیام شخصیسازی شده ای را برای کاربر نمایش میدهد.
در انتها، سرور HTTP را روی پورت 80 راهاندازی کنید و از روتهایی که تنظیم کردهاید استفاده کنید.
پس از نوشتن کد، آن را ذخیره کرده و از ویرایشگر خارج شوید.
در این مرحله، پیش از اجرای اپلیکیشن Go، به کامپایل و بستهبندی آن برای اجرای داخل کانتینر Docker نیاز دارید. زبان Go بهصورت کامپایل شده است، بنابراین باید کد شما به کد ماشین قابل اجرا تبدیل شود.
تا این مرحله، محیط کاری شما آماده است و اپلیکیشن ساده Go ساخته شده است. در مرحله بعدی، شما nginx-proxy را با گواهینامه Let’s Encrypt به صورت خودکار راهاندازی خواهید کرد.
🔶برای ادامه مطالعه و یادگیری: نحوه دریافت SSL در Nginx در سرور مجازی اوبونتو Ubuntu با Let’s Encrypt
مرحله دوم: راهاندازی nginx-proxy و Let’s Encrypt برای امنیت اپلیکیشن
برای اینکه اپلیکیشن Go از طریق HTTPS در دسترس باشد، باید یک پروکسی معکوس (Reverse Proxy) را راهاندازی کنید. در این مرحله، با استفاده از nginx-proxy و افزونهی Let’s Encrypt، یک سیستم خودکار برای مدیریت گواهینامههای امنیتی TLS راهاندازی خواهیم کرد. این کار باعث میشود که اپلیکیشن بدون هیچ گونه دردسری، گواهینامهی SSL داشته باشد و ارتباطات آن امن بماند.
۱. ساخت فایل تنظیمات Docker Compose
برای راهاندازی nginx-proxy، یک فایل Docker Compose جدید به اسم nginx-proxy-compose.yaml
ایجاد کنید.
nano nginx-proxy-compose.yaml
کد زیر را داخل فایل قرار بدید و آن را ذخیره کنید.
version: '3'
services:
nginx-proxy:
restart: always
image: jwilder/nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- "/etc/nginx/vhost.d"
- "/usr/share/nginx/html"
- "/var/run/docker.sock:/tmp/docker.sock:ro"
- "/etc/nginx/certs"
letsencrypt-nginx-proxy-companion:
restart: always
image: jrcs/letsencrypt-nginx-proxy-companion
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
volumes_from:
- "nginx-proxy"
۲. اجرای Docker Compose
حال که تنظیمات را انجام دادید، دستور زیر را برای راهاندازی nginx-proxy و Let’s Encrypt اجرا کنید.
docker compose -f nginx-proxy-compose.yaml up -d
توضیح دستور:
-f nginx-proxy-compose.yaml
: مشخص کردن فایل Compose.up
: راهاندازی سرویسها.-d
: اجرای سرویسها در پسزمینه (Detached Mode).
اگر همهچیز درست پیش برود، خروجی زیر را مشاهده خواهید کرد.
[+] Running 3/3
⠿ Network go-docker_default Created 0.1s
⠿ Container go-docker-nginx-proxy-1 Started 0.5s
⠿ Container go-docker-letsencrypt-nginx-proxy-companion-1 Started 0.8s
در حال حاضر یک پروکسی معکوس با Nginx را خواهیم داشت که درخواستها را مدیریت خواهد کرد.
سیستم Let’s Encrypt بهصورت خودکار گواهینامهی امنیتی را صادر و تمدید میکند.
🔷بیشتر بخوانید: نحوه میزبانی وبسایت با استفاده از Cloudflare و Nginx در اوبونتو 22.04
مرحله سوم: داکریزه کردن اپلیکیشن Go
حال که توانستیم اپلیکیشن Go و nginx-proxy رو راهاندازی کنیم، وقت آن رسیده است که Dockerfile خود را بسازیم تا اپلیکیشن ما بتواند به یک ایمیج داکر تبدیل بشود. این کار باعث میشود که اپلیکیشن در یک محیط ثابت، بدون تغییر و نیاز به وابستگی به سیستم میزبان اجرا شده بشود.
۱. ساخت Dockerfile
فایل Dockerfile رو با دستور زیر بسازید.
nano Dockerfile
کد زیر را در آن قرار بدهید.
FROM golang:alpine AS build
RUN apk --no-cache add gcc g++ make git
WORKDIR /go/src/app
COPY . .
RUN go mod init webserver
RUN go mod tidy
RUN GOOS=linux go build -ldflags="-s -w" -o ./bin/web-app ./main.go
FROM alpine:3.17
RUN apk --no-cache add ca-certificates
WORKDIR /usr/bin
COPY --from=build /go/src/app/bin /go/bin
EXPOSE 80
ENTRYPOINT /go/bin/web-app --port 80
بعد از اضافه کردن این کد، فایل را ذخیره کنید. حال یک Dockerfile را در اختیار خواهیم داشت که اپلیکیشن Go را کامپایل میکند و در یک محیط سبک آن را اجرا خواهد کرد.
مرحله چهارم: راه اندازی Docker Compose برای اجرای اپلیکیشن Go
در این قسمت باید یک فایل Docker Compose بسازیم تا اپلیکیشن Go را داخل کانتینر اجرا کنیم. این فایل تنظیمات مورد نیاز برای اجرای کانتینر، شبکه و ارتباط با nginx-proxy رو مشخص میکند.
۱. ساخت فایل تنظیمات Docker Compose
برای شروع، دستور را اجرا کنید تا فایل go-app-compose.yaml ساخته بشود.
nano go-app-compose.yaml
تنظیمات زیر را در آن قرار دهید.
version: '3'
services:
go-web-app:
restart: always
build:
dockerfile: Dockerfile
context: .
environment:
- VIRTUAL_HOST=your_domain
- LETSENCRYPT_HOST=your_domain
نکته: your_domain
را با دامنهی واقعی اپلیکیشن خودتون جایگزین کنید.
۲. توضیح تنظیمات فایل
این فایل یک سرویس به نام go-web-app
تعریف میکند که اپلیکیشن Go شما را اجرا خواهد کرد.
restart: always
: تضمین میکند اگر کانتینر متوقف شد، دوباره اجرا بشود.build:
: منحوه ساخت ایمیج اپلیکیشن را مشخص میکند.dockerfile: Dockerfile
: داکر از فایلDockerfile
برای ساخت ایمیج استفاده میکند.context: .
: پوشه فعلی را به عنوان محدوده ساخت در نظر میگیرد.
environment:
: متغیرهای محیطی تنظیم میکند که برای nginx-proxy و Let’s Encrypt بسیار مهم هستند.VIRTUAL_HOST=your_domain
: مشخص میکند که nginx-proxy دامنه را مدیریت کند.LETSENCRYPT_HOST=your_domain
: برای این دامنه گواهینامهی SSL صادر میکند.
۳. اجرای اپلیکیشن با Docker Compose
بعد از ذخیرهی فایل، دستور زیر را اجرا کنید تا اپلیکیشن شما اجرا شود.
docker compose -f go-app-compose.yaml up -d
اگر همه چیز به درستی انجام بشود، خروجی زیر را نشان خواهد داد.
Creating network "go-docker_default" with the default driver
Building go-web-app
Step 1/13 : FROM golang:alpine AS build
---> b97a72b8e97d
...
Successfully built 71e4b1ef2e25
Successfully tagged go-docker_go-web-app:latest
...
[+] Running 1/1
⠿ Container go-docker-go-web-app-1 Started
۴. تست اپلیکیشن در مرورگر
در این بخش میتوانید اپلیکیشن را از طریق مرورگر تست کنید.
برای تست به آدرس زیر بروید.
https://your_domain/
🔶مطالعه بیشتر: نحوه بهبود عملکرد وبسایت با gzip و Nginx در سرور مجازی اوبونتو Ubuntu
مرحله چهارم: تست نهایی اپلیکیشن Go در مرورگر
بعد از اجرای موفق Docker Compose، نوبت به تست اپلیکیشن در مرورگر میرسد. داکر لاگها مراحل ساخت ایمیج و اجرای کانتینر را نمایش میدهد و نشان میدهد که تمامی مراحل بدون هیچ باگی پیش رفته است.
۱. بررسی صفحهی اصلی اپلیکیشن
مرورگر خود را باز کنید و آدرس دامنه خود را بنویسید.
https://your_domain/
اگر همهچیز درست باشه، باید پیام زیر را مشاهده کنید.
"This is the homepage. Try /hello and /hello/Sammy"
۲. تست مسیر /hello
در این بخش به این مسیر بروید.
https://your_domain/hello
در این صفحه، پیام مربوط به روت /hello
که در مرحله اول تعریف کردهاید را مشاهده خواهید کرد.
"Hello from Docker!"
۳. تست مسیر /hello/{name}
یک نام به انتهای مسیر اضافه کنید، به عنوان مثال Sammy
:
https://your_domain/hello/Sammy
اگر همه چیز به درستی پیش رفته باشد باید پیغام زیر را مشاهده کنید.
"Hello, Sammy!"
۴. رفع مشکل احتمالی گواهینامهی SSL
اگر با خطای TLS certificate invalid مواجه شدید، چند دقیقه صبر کنید تا Let’s Encrypt گواهینامهی SSL رو صادر کند. اگر بعد از چند دقیقه مشکل شما برطرف نشد.
- تنظیمات دامنه و متغیرهای محیطی را چک کنید.
- مطمئن شوید که کانتینر
letsencrypt-nginx-proxy-companion
در حال اجرا است.
🔷بیشتر بخوانید: آموزش راهاندازی برنامه React با NGINX در Docker
سوالات متداول:
در ادامه به سوالاتی که امکان دارد در این زمینه برای شما بدون پاسخ بماند، جوابهای کوتاه اما مفیدی دادهایم که با استفاده از آن میتوانید به سوال خود پاسخ صحیحی را بدهید.
چرا بعد از اجرای Docker Compose، سایت من باز نمیشود؟
بررسی کنید که کانتینرها اجرا شده باشند.
docker ps
مطمئن شوید دامنهی شما به درستی بر روی سرور تنظیم شده است.
اگر از SSL استفاده میکنید، چند دقیقه صبر کنید تا Let’s Encrypt گواهینامه شما را صادر کند.
چطور لاگهای اپلیکیشن Go را داخل کانتینر مشاهده کنیم؟
برای مشاهده لاگهای اپلیکیشن.
docker logs go-docker-go-web-app-1
(نام کانتینر را از docker ps
پیدا کنید.)
چطور اپلیکیشن را بدون نیاز به بیلد مجدد، تغییر بدیم؟
اگر تغییرات شما شامل کد ها است، کانتینر را دوباره راه اندازی کنید.
docker restart go-docker-go-web-app-1
اگر نیاز به بیلد جدید دارید.
docker compose -f go-app-compose.yaml up --build -d
چطور میتوانم دامنه جدیدی اضافه کنم؟
فایل go-app-compose.yaml
را ویرایش کنید و دامنه جدید را اضافه کنید.
environment:
- VIRTUAL_HOST=your_new_domain
- LETSENCRYPT_HOST=your_new_domain
سپس کانتینر را مجددا اجرا کنید.
docker compose down && docker compose up -d
چرا تغییرات جدید روی سایت اعمال نمیشود؟
ممکن است کش مرورگر یا کش Nginx-proxy باشد. این موارد را تست کنید.
- مرورگر را در حالت ناشناس (Incognito Mode) باز کنید.
- کانتینر Nginx-proxy را ریستارت کنید.
docker restart go-docker-nginx-proxy-1
- کش DNS را پاک کنید.
sudo systemctl restart systemd-resolved
اگر مشکل حل نشد، لاگهای Nginx-proxy را بررسی کنید.
docker logs go-docker-nginx-proxy-1
📍بیشتر بخوانید: معرفی هاست رایگان go
جمع بندی
در این آموزش، نحوه داکرایز کردن یک اپلیکیشن Go با استفاده از nginx-proxy و Let’s Encrypt را بررسی کردیم. ابتدا یک اپلیکیشن ساده Go با gorilla/mux ساختیم و سپس با پیکربندی nginx-proxy و Let’s Encrypt، درخواستها را هدایت و گواهینامه SSL ایجاد کردیم. بعد از آن، با نوشتن یک Dockerfile، اپلیکیشن را داکرایز کرده و با Docker Compose اجزا را یکپارچه اجرا کردیم. در نهایت، اپلیکیشن را روی دامنه مشخص شده قرار دادیم و مشکلات احتمالی را رفع کردیم.