You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitHub Actions作业间共享服务容器?当前构建后容器销毁

在GitHub Actions跨作业共享服务容器的解决方案

GitHub Actions中,每个作业(Job)运行在独立的Runner实例上,作业关联的服务容器会随作业结束被销毁,无法直接跨作业共享。针对你的场景,提供以下几种可行方案:

方案1:合并依赖服务容器的作业

如果build、test步骤不需要严格拆分,将它们合并到同一个作业中,这样Postgres服务容器会全程可用:

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  RAILS_ENV: test
  RACK_ENV: test
  RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
  POSTGRES_PASSWORD: postgres15
  POSTGRES_USERNAME: postgres
  POSTGRES_HOST: localhost

jobs:
  build-test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15.1-alpine
        ports:
          - 5432:5432
        env:
          POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
          POSTGRES_USER: ${{ env.POSTGRES_USERNAME }}
        options: >-
          --health-cmd pg_isready 
          --health-interval 10s 
          --health-timeout 5s 
          --health-retries 5
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Initialize Ruby
        uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
      - name: Setup Rails
        run: bin/setup
      - name: Lint Ruby
        run: bundle exec rubocop
      - name: Run tests
        run: bin/rails test:all

  coverage:
    runs-on: ubuntu-latest
    needs: [ build-test ]
    steps:
      - uses: joshmfrankel/simplecov-check-action@main
        with:
          minimum_suite_coverage: 98
          minimum_file_coverage: 90
          github_token: ${{ secrets.GITHUB_TOKEN }}
          check_job_name: coverage

方案2:每个作业单独配置服务容器,缓存数据库状态

若必须保持作业拆分,可为每个需要Postgres的作业单独配置服务容器,同时通过缓存数据库数据避免重复初始化:

修改build作业,缓存数据库数据

build:
  runs-on: ubuntu-latest
  services:
    postgres:
      image: postgres:15.1-alpine
      ports:
        - 5432:5432
      env:
        POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
        POSTGRES_USER: ${{ env.POSTGRES_USERNAME }}
      options: >-
        --health-cmd pg_isready 
        --health-interval 10s 
        --health-timeout 5s 
        --health-retries 5
      volumes:
        - postgres-data:/var/lib/postgresql/data
  steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Initialize Ruby
      uses: ruby/setup-ruby@v1
      with:
        bundler-cache: true
    - name: Setup Rails
      run: bin/setup
    - name: Cache Postgres data
      uses: actions/cache@v3
      with:
        path: /var/lib/postgresql/data
        key: ${{ runner.os }}-postgres-${{ hashFiles('db/schema.rb', 'Gemfile.lock') }}
        restore-keys: ${{ runner.os }}-postgres-

修改test作业,复用缓存数据

test:
  runs-on: ubuntu-latest
  needs: [ build ]
  services:
    postgres:
      image: postgres:15.1-alpine
      ports:
        - 5432:5432
      env:
        POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
        POSTGRES_USER: ${{ env.POSTGRES_USERNAME }}
      options: >-
        --health-cmd pg_isready 
        --health-interval 10s 
        --health-timeout 5s 
        --health-retries 5
      volumes:
        - postgres-data:/var/lib/postgresql/data
  steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Initialize Ruby
      uses: ruby/setup-ruby@v1
      with:
        bundler-cache: true
    - name: Restore Postgres data
      uses: actions/cache@v3
      with:
        path: /var/lib/postgresql/data
        key: ${{ runner.os }}-postgres-${{ hashFiles('db/schema.rb', 'Gemfile.lock') }}
        restore-keys: ${{ runner.os }}-postgres-
    - name: Lint Ruby
      run: bundle exec rubocop
    - name: Run tests
      run: bin/rails test:all

缓存key基于db/schema.rb和Gemfile.lock的哈希值,确保数据库结构或依赖变更时自动更新缓存。

方案3:使用外部托管数据库(可选)

如果允许额外成本,可采用AWS RDS、Heroku Postgres等外部数据库服务,让所有作业连接同一数据库,彻底摆脱Runner上的服务容器限制。

内容的提问来源于stack exchange,提问作者bitsmyth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:36:31