Quay lại blog

Proxy cho pipeline CI/CD: cấu hình GitHub Actions, GitLab CI và Jenkins để truy cập tài nguyên riêng tư

Hướng dẫn đầy đủ về cách thiết lập proxy trong các pipeline CI/CD: GitHub Actions, GitLab CI và Jenkins. Cách vượt qua geo-blocking, truy cập API riêng tư và tăng tốc độ xây dựng thông qua proxy.

📅16 tháng 5, 2026
```html

Pipeline của bạn gặp lỗi 403 Forbidden hoặc Connection refused khi cố gắng truy cập API bên ngoài hoặc tải xuống phụ thuộc? Có thể vấn đề là địa chỉ IP của máy chủ CI/CD của bạn đã bị chặn ở phía tài nguyên. Proxy giải quyết vấn đề này: bạn định tuyến lưu lượng qua IP cần thiết và pipeline hoạt động mà không gặp sự cố. Trong bài viết này - hướng dẫn từng bước cho GitHub Actions, GitLab CI và Jenkins.

Tại sao cần proxy trong CI/CD: các kịch bản thực tế

Các pipeline CI/CD hoạt động trên các máy chủ với địa chỉ IP cố định - các runner đám mây của GitHub, GitLab hoặc trên các agent Jenkins tự quản. Những địa chỉ IP này rất quen thuộc, và nhiều dịch vụ bên ngoài hoặc chặn chúng hoặc giới hạn số lượng yêu cầu. Dưới đây là những tình huống cụ thể mà không có proxy sẽ không thể thực hiện:

Truy cập vào các tài nguyên bị giới hạn theo địa lý

Nhiều registry npm doanh nghiệp, kho Maven và API nội bộ chỉ có thể truy cập từ một số quốc gia hoặc dải IP nhất định. Nếu runner GitHub Actions của bạn nằm trong khu vực bị chặn ở cấp độ firewall của dịch vụ mục tiêu, pipeline sẽ không thể tải xuống các phụ thuộc hoặc gửi dữ liệu. Proxy với vị trí địa lý cần thiết giải quyết vấn đề này mà không cần thay đổi cơ sở hạ tầng.

Giới hạn tốc độ và chặn theo IP

Các runner đám mây của GitHub Actions sử dụng IP từ các dải Microsoft Azure. Nhiều API công khai biết về những dải này và áp dụng các giới hạn nghiêm ngặt - hoặc chặn hoàn toàn. Ví dụ, việc phân tích dữ liệu công khai, yêu cầu đến các API bên ngoài trong quá trình thử nghiệm, tải xuống các bản phân phối từ các CDN bị hạn chế - tất cả đều thường xuyên gặp sự cố chính vì địa chỉ IP của các runner đám mây. Việc xoay vòng qua proxy cho phép vượt qua giới hạn tốc độ.

Kiểm tra tích hợp với các trang web thực tế

Nếu các bài kiểm tra tích hợp của bạn truy cập vào các trang web thực tế hoặc các sàn thương mại điện tử (Wildberries, Ozon, Avito, Amazon), những trang web này sẽ thấy cùng một địa chỉ IP từ runner mỗi khi chạy và nhanh chóng chặn nó. Proxy với việc xoay vòng IP cho phép các bài kiểm tra diễn ra ổn định mà không gặp captcha và chặn.

Truy cập vào các tài nguyên nội bộ của doanh nghiệp

Các mạng doanh nghiệp thường bị đóng cửa với thế giới bên ngoài. Nếu pipeline cần triển khai lên máy chủ nội bộ hoặc truy cập vào API riêng tư, proxy (hoặc tunnel SOCKS5) bên trong mạng doanh nghiệp trở thành cầu nối giữa runner đám mây và cơ sở hạ tầng kín.

Kiểm tra tích hợp quảng cáo và tiếp thị

Các nhóm làm việc với API Facebook Ads, API TikTok Ads hoặc API Google Ads thường tự động hóa việc tạo chiến dịch thông qua CI/CD. Những nền tảng này có quy định nghiêm ngặt về IP: yêu cầu từ các IP của trung tâm dữ liệu có thể bị chặn hoặc yêu cầu xác minh bổ sung. Proxy cư trú trong pipeline làm cho các yêu cầu giống như lưu lượng người dùng thông thường.

Chọn loại proxy nào cho pipeline

Việc chọn loại proxy phụ thuộc vào nhiệm vụ. Đối với các pipeline CI/CD, có ba lựa chọn phù hợp - mỗi loại có ưu điểm và hạn chế riêng:

Loại proxy Tốc độ Độ tin cậy của các trang web Tốt nhất cho
Proxy trung tâm dữ liệu Rất cao Trung bình Tải xuống phụ thuộc, kho nội bộ, API nhanh mà không có kiểm tra nghiêm ngặt
Proxy cư trú Trung bình Cao Kiểm tra tích hợp với các trang web thực tế, API quảng cáo (Facebook, TikTok), sàn thương mại điện tử
Proxy di động Trung bình Tối đa Kiểm tra API di động, làm việc với các nền tảng có bảo vệ chống bot tối đa

Nguyên tắc thực tiễn:

Nếu nhiệm vụ là tải xuống các gói hoặc truy cập vào dịch vụ nội bộ, hãy chọn proxy trung tâm dữ liệu - chúng nhanh và rẻ hơn. Nếu nhiệm vụ là kiểm tra trên các trang web thực tế hoặc làm việc với các nền tảng quảng cáo - cần proxy cư trú. Giao thức SOCKS5 được ưu tiên hơn HTTP/HTTPS, vì nó hoạt động minh bạch hơn với các cổng và giao thức không chuẩn.

Cấu hình proxy trong GitHub Actions

GitHub Actions là công cụ CI/CD phổ biến nhất hiện nay. Cấu hình proxy ở đây được thực hiện thông qua các biến môi trường và bí mật của kho. Chúng ta sẽ phân tích từng bước.

Bước 1: Thêm thông tin proxy vào bí mật của kho

Không bao giờ ghi trực tiếp tên người dùng và mật khẩu proxy vào tệp YAML của workflow. Sử dụng Bí mật GitHub:

  1. Mở kho → Cài đặtBí mật và biếnActions
  2. Nhấn Bí mật kho mới
  3. Tạo bí mật PROXY_URL với giá trị dạng http://user:[email protected]:port

Bước 2: Sử dụng biến môi trường trong workflow

Hầu hết các công cụ (curl, wget, npm, pip, Maven) tự động nhận các biến môi trường tiêu chuẩn HTTP_PROXY, HTTPS_PROXYNO_PROXY. Ví dụ về workflow:

name: Build with Proxy

on: [push]

env:
  HTTP_PROXY: ${{ secrets.PROXY_URL }}
  HTTPS_PROXY: ${{ secrets.PROXY_URL }}
  NO_PROXY: localhost,127.0.0.1,internal.company.com

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: npm ci

      - name: Run integration tests
        run: npm test

      - name: Call external API
        run: |
          curl -v https://api.example.com/data

Bước 3: Proxy SOCKS5 trong GitHub Actions

Nếu bạn sử dụng SOCKS5 (được khuyến nghị cho hầu hết các nhiệm vụ), các biến môi trường tiêu chuẩn không đủ - cần một tunnel cục bộ. Sử dụng tiện ích proxychains hoặc cấu hình microsocks:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Setup SOCKS5 proxy tunnel
        run: |
          sudo apt-get install -y proxychains4
          echo "socks5 proxy.host 1080 user password" >> /etc/proxychains4.conf

      - name: Run command through SOCKS5
        run: proxychains4 curl https://restricted-resource.com/api

Cấu hình proxy cho các công cụ cụ thể

Một số công cụ bỏ qua các biến hệ thống và yêu cầu cấu hình riêng:

Công cụ Cách cấu hình proxy
npm / yarn npm config set proxy http://user:pass@host:port
pip (Python) pip install --proxy http://user:pass@host:port package
Maven Thông qua settings.xml phần <proxies>
Gradle systemProp.https.proxyHost=host trong gradle.properties
Git git config --global http.proxy http://user:pass@host:port
Docker build --build-arg HTTP_PROXY=http://user:pass@host:port

Cấu hình proxy trong GitLab CI

GitLab CI cung cấp nhiều cấp độ để thiết lập các biến môi trường: ở cấp độ dự án, nhóm hoặc phiên bản. Điều này làm cho việc quản lý proxy linh hoạt hơn so với GitHub Actions.

Bước 1: Thêm biến vào GitLab CI/CD Variables

  1. Mở dự án → Cài đặtCI/CD → phần Biến
  2. Nhấn Thêm biến
  3. Thêm biến PROXY_URL với loại Masked (ẩn giá trị trong log)
  4. Giá trị: http://user:[email protected]:port

Bước 2: Sử dụng các biến trong .gitlab-ci.yml

variables:
  HTTP_PROXY: $PROXY_URL
  HTTPS_PROXY: $PROXY_URL
  NO_PROXY: "localhost,127.0.0.1,.internal.company.com"

stages:
  - build
  - test
  - deploy

build:
  stage: build
  image: node:20-alpine
  script:
    - npm ci
    - npm run build

integration_tests:
  stage: test
  image: python:3.11
  script:
    - pip install -r requirements.txt
    - pytest tests/integration/

deploy:
  stage: deploy
  script:
    - curl -X POST https://api.external-service.com/deploy
      -H "Authorization: Bearer $DEPLOY_TOKEN"
      -d '{"version": "$CI_COMMIT_SHA"}'

Proxy chỉ cho các job cụ thể

Nếu proxy không cần thiết ở mọi nơi (ví dụ, chỉ cho các bài kiểm tra tích hợp, nhưng không cho việc xây dựng), hãy đặt các biến ở cấp độ job cụ thể, không phải toàn cục:

integration_tests:
  stage: test
  variables:
    HTTP_PROXY: $PROXY_URL
    HTTPS_PROXY: $PROXY_URL
  script:
    - pytest tests/integration/

build:
  stage: build
  # Proxy không được chỉ định ở đây - kết nối trực tiếp
  script:
    - npm ci && npm run build

GitLab Runner tự quản: cấu hình proxy ở cấp độ runner

Nếu bạn sử dụng GitLab Runner tự quản, có thể thiết lập proxy toàn cục trong cấu hình của runner. Mở tệp /etc/gitlab-runner/config.toml và thêm vào phần [runners.env]:

[[runners]]
  name = "my-runner"
  url = "https://gitlab.com/"
  token = "TOKEN"
  executor = "docker"
  environment = [
    "HTTP_PROXY=http://user:[email protected]:port",
    "HTTPS_PROXY=http://user:[email protected]:port",
    "NO_PROXY=localhost,127.0.0.1"
  ]

Điều này thuận tiện khi tất cả các pipeline trên runner này cần sử dụng proxy - không cần phải chỉ định nó trong mỗi .gitlab-ci.yml.

Cấu hình proxy trong Jenkins

Jenkins là công cụ linh hoạt nhất trong ba công cụ, nhưng cũng khó cấu hình nhất. Proxy ở đây có thể được thiết lập ở nhiều cấp độ: toàn cục cho toàn bộ Jenkins, cho một Pipeline cụ thể hoặc cho một bước riêng lẻ.

Cách 1: Cấu hình proxy toàn cục trong Jenkins

  1. Mở Quản lý JenkinsHệ thống
  2. Tìm phần Cấu hình Proxy HTTP
  3. Điền vào các trường: Server, Port, Username, Password
  4. Trong trường No Proxy Host, chỉ định các địa chỉ nội bộ bằng dấu phẩy
  5. Nhấn Kiểm tra URL để kiểm tra và lưu lại

Cấu hình này ảnh hưởng đến việc tải các plugin và cập nhật của chính Jenkins, nhưng không tự động được truyền vào môi trường thực thi của các pipeline. Cần có cấu hình riêng cho các pipeline.

Cách 2: Proxy trong Declarative Pipeline thông qua môi trường

pipeline {
    agent any

    environment {
        HTTP_PROXY  = credentials('proxy-url-credential')
        HTTPS_PROXY = credentials('proxy-url-credential')
        NO_PROXY    = 'localhost,127.0.0.1,internal.company.com'
    }

    stages {
        stage('Build') {
            steps {
                sh 'npm ci'
                sh 'npm run build'
            }
        }

        stage('Integration Tests') {
            steps {
                sh 'pytest tests/integration/'
            }
        }

        stage('Deploy') {
            steps {
                sh '''
                    curl -X POST https://api.external-service.com/deploy \
                    -H "Authorization: Bearer ${DEPLOY_TOKEN}" \
                    -d "version=${GIT_COMMIT}"
                '''
            }
        }
    }
}

Bước 3: Thêm thông tin xác thực proxy vào Jenkins Credentials

  1. Mở Quản lý JenkinsThông tin xác thựcHệ thốngThông tin xác thực toàn cầu
  2. Nhấn Thêm thông tin xác thực
  3. Loại: Văn bản bí mật
  4. ID: proxy-url-credential
  5. Bí mật: http://user:[email protected]:port

Cách 3: Proxy thông qua các tham số JVM cho các dự án Java

Nếu pipeline của bạn xây dựng một dự án Java (Maven, Gradle), các biến môi trường hệ thống có thể không hoạt động - JVM sử dụng các thuộc tính hệ thống riêng. Thêm chúng vào JAVA_OPTS:

environment {
    JAVA_OPTS = '-Dhttps.proxyHost=proxy.host -Dhttps.proxyPort=8080 -Dhttps.proxyUser=user -Dhttps.proxyPassword=password -Dhttp.nonProxyHosts=localhost|127.0.0.1|*.internal.com'
}

Proxy bên trong các container Docker trong pipeline

Hầu hết các pipeline CI/CD hiện đại chạy các bước bên trong các container Docker. Việc truyền proxy vào container là một nhiệm vụ riêng, có thể được giải quyết bằng nhiều cách.

Truyền proxy qua --build-arg khi xây dựng hình ảnh

Nếu proxy chỉ cần thiết trong quá trình xây dựng hình ảnh Docker (ví dụ, để cài đặt các gói bên trong Dockerfile), hãy sử dụng các tham số build:

# Trong .github/workflows/build.yml hoặc .gitlab-ci.yml
docker build \
  --build-arg HTTP_PROXY=$HTTP_PROXY \
  --build-arg HTTPS_PROXY=$HTTPS_PROXY \
  --build-arg NO_PROXY=$NO_PROXY \
  -t myapp:latest .

# Trong Dockerfile
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
ENV HTTP_PROXY=$HTTP_PROXY
ENV HTTPS_PROXY=$HTTPS_PROXY
ENV NO_PROXY=$NO_PROXY

RUN apt-get update && apt-get install -y curl
RUN npm ci

⚠️ Quan trọng: bảo mật khi xây dựng hình ảnh

Các biến được chỉ định qua ARGENV trong Dockerfile được lưu trữ trong siêu dữ liệu của hình ảnh và có thể nhìn thấy thông qua docker inspect. Nếu proxy yêu cầu xác thực, hãy đảm bảo rằng hình ảnh hoàn chỉnh không được công bố trên registry công khai - nếu không, thông tin xác thực sẽ bị lộ.

Cấu hình toàn cục cho Docker daemon để sử dụng proxy

Trên các runner tự quản, có thể cấu hình proxy cho toàn bộ Docker daemon - như vậy tất cả các container sẽ tự động nhận proxy mà không cần thay đổi trong Dockerfile:

# /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://user:[email protected]:port"
Environment="HTTPS_PROXY=http://user:[email protected]:port"
Environment="NO_PROXY=localhost,127.0.0.1,registry.internal.com"

# Áp dụng các thay đổi:
# systemctl daemon-reload
# systemctl restart docker

Bảo mật: cách lưu trữ thông tin xác thực proxy

Thông tin xác thực proxy cũng giống như các bí mật khác, như khóa API hoặc mật khẩu cơ sở dữ liệu. Việc rò rỉ chúng có nghĩa là bất kỳ ai cũng có thể sử dụng proxy của bạn mà không tốn phí. Dưới đây là các quy tắc để lưu trữ an toàn:

Danh sách kiểm tra bảo mật

  • Không bao giờ ghi tên người dùng/mật khẩu proxy trực tiếp vào các tệp YAML của pipeline
  • ✅ Sử dụng Các biến ẩn trong GitLab và Bí mật mã hóa trong GitHub - chúng sẽ được ẩn trong log
  • ✅ Trong Jenkins, sử dụng loại Văn bản bí mật hoặc Tên người dùng với mật khẩu trong Kho thông tin xác thực
  • ✅ Thêm NO_PROXY cho các địa chỉ nội bộ - lưu lượng truy cập đến cơ sở hạ tầng của bạn không nên đi qua proxy
  • ✅ Thường xuyên xoay vòng mật khẩu proxy - chỉ cập nhật trong kho bí mật, không thay đổi mã của pipeline
  • ✅ Sử dụng xác thực IP cho proxy (whitelist IP của runner) ở những nơi hỗ trợ - điều này đáng tin cậy hơn mật khẩu
  • ✅ Kiểm tra log của proxy để phát hiện hoạt động bất thường

Định dạng URL proxy: cái gì đi đâu

Giao thức Định dạng URL Khi nào sử dụng
HTTP http://user:pass@host:port Hầu hết các công cụ, npm, pip, curl
HTTPS https://user:pass@host:port Kết nối được mã hóa với máy chủ proxy
SOCKS5 socks5://user:pass@host:port Cổng không chuẩn, lưu lượng UDP, tương thích tối đa

Các lỗi thường gặp và cách khắc phục

Ngay cả sau khi cấu hình đúng, vẫn có thể xảy ra sự cố. Dưới đây là những lỗi phổ biến nhất và cách giải quyết:

Lỗi: Cần xác thực proxy (407)

Nguyên nhân: Tên người dùng hoặc mật khẩu không chính xác, hoặc chúng không được truyền bởi công cụ.

Giải pháp: Kiểm tra định dạng URL - các ký tự đặc biệt trong mật khẩu cần được mã hóa URL. Ví dụ, p@ss#wordp%40ss%23word. Cũng hãy đảm bảo rằng biến môi trường thực sự được truyền vào bước - in nó ra bằng echo $HTTP_PROXY (các ký tự đầu tiên) để kiểm tra.

Lỗi: Xác thực chứng chỉ SSL thất bại

Nguyên nhân: Proxy thực hiện kiểm tra SSL (MITM) và thay thế chứng chỉ. Khách hàng không tin tưởng chứng chỉ của proxy.

Giải pháp: Thêm chứng chỉ gốc của proxy vào danh sách tin cậy. Đối với curl: --cacert /path/to/proxy-ca.crt. Đối với npm: npm config set cafile /path/to/proxy-ca.crt. Hoặc sử dụng proxy không có kiểm tra SSL - điều này là ưu tiên hơn cho CI/CD.

Lỗi: Thời gian kết nối qua proxy

Nguyên nhân: Máy chủ proxy không thể truy cập từ IP của runner, hoặc cổng bị chặn bởi firewall.

Giải pháp: Kiểm tra khả năng truy cập proxy bằng lệnh nc -zv proxy.host port trong bước của pipeline. Đảm bảo rằng IP của runner đã được thêm vào whitelist của nhà cung cấp proxy (nếu sử dụng xác thực IP). Đối với các runner đám mây của GitHub Actions, các dải IP được công bố tại meta.github.com.

Lỗi: Công cụ bỏ qua các biến HTTP_PROXY

Nguyên nhân: Một số công cụ (đặc biệt là Java-based) không đọc các biến môi trường hệ thống.

Giải pháp: Sử dụng cấu hình proxy gốc cho công cụ cụ thể (xem bảng trên). Đối với Java, thêm các thuộc tính JVM thông qua JAVA_OPTS. Đối với curl, sử dụng cờ -x http://proxy:port một cách rõ ràng.

Lỗi: Các dịch vụ nội bộ cũng đi qua proxy

Nguyên nhân: Biến NO_PROXY không được chỉ định hoặc được chỉ định không chính xác.

Giải pháp: Chỉ định tất cả các miền và IP nội bộ trong NO_PROXY. Sử dụng wildcard cho các miền: NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,.internal.company.com. Lưu ý: một số công cụ hỗ trợ định dạng CIDR, trong khi những công cụ khác chỉ hỗ trợ các miền chính xác.

Kết luận

Cấu hình proxy trong pipeline CI/CD không phải là một nhiệm vụ đơn lẻ, mà là một phần của kiến trúc tự động hóa đúng đắn. Chúng ta đã phân tích ba công cụ chính: GitHub Actions (thông qua Bí mật và biến môi trường), GitLab CI (thông qua Biến với việc ẩn) và Jenkins (thông qua Kho thông tin xác thực và Declarative Pipeline). Các nguyên tắc chính đều giống nhau cho tất cả: không bao giờ lưu trữ thông tin xác thực trong mã, sử dụng NO_PROXY cho các địa chỉ nội bộ và chọn loại proxy cho nhiệm vụ cụ thể.

Việc chọn loại proxy đúng là rất quan trọng cho sự ổn định của pipeline. Đối với việc tải xuống các phụ thuộc và truy cập vào các API tiêu chuẩn, chỉ cần các proxy trung tâm dữ liệu nhanh là đủ. Tuy nhiên, nếu pipeline của bạn thực hiện kiểm tra tích hợp trên các trang web thực tế, làm việc với các nền tảng quảng cáo (API Facebook Ads, API TikTok Ads) hoặc truy cập vào các sàn thương mại điện tử - hãy sử dụng proxy cư trú: IP của chúng được coi là lưu lượng người dùng thông thường và rất hiếm khi bị chặn hoặc gặp giới hạn tốc độ.

Nguyên tắc chính: hãy kiểm tra proxy trong một bước riêng ở đầu pipeline - điều này sẽ giúp bạn nhanh chóng chẩn đoán các vấn đề và không lãng phí thời gian tìm kiếm lỗi ở cuối quá trình xây dựng dài. Thêm bước curl -v https://api.ipify.org ngay sau khi cấu hình proxy - nó sẽ cho bạn thấy IP mà các yêu cầu đang rời khỏi và xác nhận rằng việc proxy hoạt động chính xác.

```