test-gitea-actions/README-docker-in-docker.md
Your Name 031d552374
All checks were successful
Docker-in-Docker Example / docker-example (push) Successful in 7s
test-actions / build (push) Successful in 3s
'Generic Commit'
2025-06-01 11:53:25 +12:00

3.9 KiB

Docker-in-Docker in Gitea Actions

The Problem

When running Docker commands inside a Gitea Actions container, volume mounts don't work as expected because:

  1. Gitea Actions runs your job inside a container
  2. When you try to mount volumes using docker run -v, Docker looks for paths on the host system, not inside the action container
  3. This causes empty or incorrect directory mounts

The Solution

Gitea Actions provides an environment variable JOB_CONTAINER_NAME that contains the name of the job container. You can use --volumes-from to share volumes from the job container to your nested Docker containers.

Basic Usage

Instead of:

# This won't work in Gitea Actions
docker run -v $(pwd):/workspace alpine:latest ls -la /workspace

Use:

# This works in Gitea Actions
docker run --volumes-from="${JOB_CONTAINER_NAME}" alpine:latest sh -c "cd ${GITHUB_WORKSPACE} && ls -la"

Complete Example

# .gitea/workflows/docker-example.yaml
name: Docker-in-Docker Example
on: [push]

jobs:
  docker-build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        
      - name: Build and run Docker container
        run: |
          # Build a Docker image
          docker build -t my-app:latest .
          
          # Run container with access to workspace files
          docker run --rm \
            --volumes-from="${JOB_CONTAINER_NAME}" \
            -w "${GITHUB_WORKSPACE}" \
            my-app:latest

Advanced Usage

Running Multiple Containers

# Create a network for containers to communicate
docker network create myapp-network

# Run a database container
docker run -d \
  --name mydb \
  --network myapp-network \
  postgres:latest

# Run your app with access to workspace
docker run --rm \
  --volumes-from="${JOB_CONTAINER_NAME}" \
  --network myapp-network \
  -w "${GITHUB_WORKSPACE}" \
  -e DATABASE_URL=postgres://mydb:5432/myapp \
  my-app:latest

# Cleanup
docker stop mydb
docker rm mydb
docker network rm myapp-network

Using with Docker Compose

For docker-compose, you'll need to use regular docker run commands or configure your Gitea runner to support additional volume mounts.

Important Notes

  1. Always use --volumes-from="${JOB_CONTAINER_NAME}" when you need access to workspace files
  2. Use ${GITHUB_WORKSPACE} as the working directory inside your containers
  3. The JOB_CONTAINER_NAME variable is only available when running in Gitea Actions, not locally
  4. For local development, use standard volume mounts (-v $(pwd):/workspace)

Debugging Tips

  1. Check if you're in Gitea Actions:

    if [ -n "${JOB_CONTAINER_NAME:-}" ]; then
      echo "Running in Gitea Actions"
    else
      echo "Running locally"
    fi
    
  2. List available environment variables:

    env | grep -E "(JOB_|GITHUB_|GITEA_)" | sort
    
  3. Debug volume mounts:

    # Show what's mounted in the job container
    mount | grep -E "(overlay|workspace)"
    

Common Issues

Issue: "volume is in use" error

Solution: Add --rm flag to automatically remove containers after they exit

Issue: Files created in Docker container have wrong permissions

Solution: Run containers with the same user as the job container:

docker run --rm \
  --volumes-from="${JOB_CONTAINER_NAME}" \
  --user "$(id -u):$(id -g)" \
  alpine:latest command

Issue: Need to persist data between steps

Solution: Create named volumes or use the workspace directory:

# Create a named volume
docker volume create mydata

# Use it in multiple steps
docker run --rm \
  --volumes-from="${JOB_CONTAINER_NAME}" \
  -v mydata:/data \
  alpine:latest sh -c "echo 'test' > /data/file.txt"

References