Giới Thiệu
Trong bài viết này, tôi sẽ hướng dẫn bạn cách xây dựng và triển khai hai ứng dụng Go đơn giản lên AWS EC2 sử dụng Docker và Nginx. Chúng ta sẽ tạo một pipeline CI/CD tự động với GitHub Actions để mỗi khi push code lên GitHub, ứng dụng sẽ tự động được build và deploy.
Mục Tiêu
- Tạo hai ứng dụng Go đơn giản
- Containerize ứng dụng với Docker
- Cấu hình Nginx làm reverse proxy
- Tự động hóa quá trình triển khai với GitHub Actions
- Triển khai lên AWS EC2
Bước 1: Chuẩn Bị Môi Trường
1.1. Tạo Tài Khoản và Cài Đặt Công Cụ
GitHub Account
- Đăng ký tài khoản tại GitHub
- Tạo hai repository mới:
app-x
vàapp-y
Docker Hub Account
- Đăng ký tại Docker Hub
- Tạo hai repository:
app-x
vàapp-y
AWS Account
- Đăng ký tài khoản AWS nếu chưa có
- Tạo EC2 instance với Amazon Linux 2023
1.2. Cấu Hình EC2
Tạo Instance
# Chọn Amazon Linux 2023 # Instance type: t2.micro # Storage: 8GB
Cấu Hình Security Group
- Mở cổng 22 (SSH)
- Mở cổng 80 (HTTP)
Tạo SSH Key
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
Bước 2: Tạo Ứng Dụng Go
2.1. App X
Tạo Thư Mục và File
mkdir app-x cd app-x
Tạo File
main.go
package main import ( "fmt" "log" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello from App X!") } func main() { http.HandleFunc("/", handler) log.Println("App X is running on port 8080...") log.Fatal(http.ListenAndServe(":8080", nil)) }
Tạo
go.mod
go mod init app-x go mod tidy
2.2. App Y
Tương tự như App X, nhưng thay đổi port thành 8081 và message thành “Hello from App Y!”.
Bước 3: Containerize với Docker
3.1. Tạo Dockerfile
Dockerfile cho App X
FROM golang:1.21-alpine WORKDIR /app COPY go.mod ./ RUN go mod download COPY . . RUN go build -o main . EXPOSE 8080 CMD ["./main"]
Dockerfile cho App Y
Tương tự như App X, nhưng thay đổi port thành 8081.
3.2. Build và Test Docker Image
# App X
docker build -t your-dockerhub-username/app-x:latest .
docker run -p 8080:8080 your-dockerhub-username/app-x:latest
# App Y
docker build -t your-dockerhub-username/app-y:latest .
docker run -p 8081:8081 your-dockerhub-username/app-y:latest
Bước 4: Cấu Hình Nginx
4.1. Cài Đặt Nginx
sudo dnf update -y
sudo dnf install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
4.2. Cấu Hình Reverse Proxy
Tạo file cấu hình /etc/nginx/conf.d/multi-app.conf
:
server {
listen 80 default_server;
server_name localhost;
# App X
location /x/ {
proxy_pass http://localhost:8080/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# App Y
location /y/ {
proxy_pass http://localhost:8081/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Redirect root to App X
location = / {
return 301 /x/;
}
}
Bước 5: Tự Động Hóa với GitHub Actions
5.1. Tạo Workflow File
Tạo file .github/workflows/deploy.yml
trong mỗi repository:
name: CI/CD Pipeline
on:
push:
branches:
- main
env:
DOCKER_IMAGE: your-dockerhub-username/app-x # hoặc app-y
CONTAINER_NAME: app-x # hoặc app-y
PORT: 8080 # hoặc 8081
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker Image
run: |
docker build -t ${{ env.DOCKER_IMAGE }}:latest .
docker push ${{ env.DOCKER_IMAGE }}:latest
- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ec2-user
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
# Install Docker if not exists
if ! command -v docker &> /dev/null; then
sudo dnf update -y
sudo dnf install -y docker
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker ec2-user
fi
# Install Nginx if not exists
if ! command -v nginx &> /dev/null; then
sudo dnf install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
fi
# Configure Nginx
sudo tee /etc/nginx/conf.d/multi-app.conf << 'EOL'
server {
listen 80 default_server;
server_name localhost;
# App X
location /x/ {
proxy_pass http://localhost:8080/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# App Y
location /y/ {
proxy_pass http://localhost:8081/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Redirect root to App X
location = / {
return 301 /x/;
}
}
EOL
# Test and reload Nginx
sudo nginx -t && sudo systemctl reload nginx
# Pull and run new container
sudo docker pull ${{ env.DOCKER_IMAGE }}:latest
sudo docker stop ${{ env.CONTAINER_NAME }} || true
sudo docker rm ${{ env.CONTAINER_NAME }} || true
sudo docker run --name ${{ env.CONTAINER_NAME }} \
-p ${{ env.PORT }}:${{ env.PORT }} \
--restart unless-stopped \
-d ${{ env.DOCKER_IMAGE }}:latest
5.2. Cấu Hình GitHub Secrets
Thêm các secrets sau vào repository:
DOCKER_USERNAME
DOCKER_PASSWORD
EC2_HOST
SSH_PRIVATE_KEY
Bước 6: Kiểm Tra và Xử Lý Sự Cố
6.1. Kiểm Tra Ứng Dụng
# Kiểm tra container
docker ps
# Xem log container
docker logs app-x
docker logs app-y
# Kiểm tra Nginx
sudo nginx -t
sudo systemctl status nginx
6.2. Xử Lý Sự Cố Thường Gặp
Container không chạy
# Kiểm tra log docker logs container_name # Khởi động lại container docker restart container_name
Nginx không hoạt động
# Kiểm tra cấu hình sudo nginx -t # Xem log lỗi sudo tail -f /var/log/nginx/error.log
Không truy cập được ứng dụng
# Kiểm tra firewall sudo systemctl status firewalld # Kiểm tra port sudo netstat -tulpn | grep LISTEN
Kết Luận
Trong bài viết này, chúng ta đã:
- Tạo hai ứng dụng Go đơn giản
- Containerize chúng với Docker
- Cấu hình Nginx làm reverse proxy
- Tự động hóa quá trình triển khai với GitHub Actions
- Triển khai lên AWS EC2
Bạn có thể mở rộng dự án này bằng cách:
- Thêm database
- Cấu hình SSL/TLS
- Thêm monitoring và logging
- Tối ưu hóa performance
- Thêm các tính năng bảo mật
Bình luận