diff --git a/.gitea/workflows/docker-example.yaml b/.gitea/workflows/docker-example.yaml new file mode 100644 index 0000000..97af947 --- /dev/null +++ b/.gitea/workflows/docker-example.yaml @@ -0,0 +1,44 @@ +name: Docker-in-Docker Example +run-name: Docker-in-Docker Example + +on: [push] + +jobs: + docker-example: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Show environment + run: | + echo "JOB_CONTAINER_NAME: ${JOB_CONTAINER_NAME}" + echo "GITHUB_WORKSPACE: ${GITHUB_WORKSPACE}" + + - name: Test Docker with volumes-from + run: | + # Create a test file + echo "Hello from Gitea Actions!" > test.txt + + # Run Docker container with proper volume sharing + docker run --rm \ + --volumes-from="${JOB_CONTAINER_NAME}" \ + alpine:latest sh -c "cd ${GITHUB_WORKSPACE} && cat test.txt" + + - name: Build and run custom image + run: | + # Create a simple Dockerfile + cat > Dockerfile << 'EOF' + FROM alpine:latest + WORKDIR /app + CMD ["sh", "-c", "echo 'Container started!' && ls -la"] + EOF + + # Build the image + docker build -t test-app:latest . + + # Run with volume sharing + docker run --rm \ + --volumes-from="${JOB_CONTAINER_NAME}" \ + -w "${GITHUB_WORKSPACE}" \ + test-app:latest \ No newline at end of file diff --git a/README-docker-in-docker.md b/README-docker-in-docker.md new file mode 100644 index 0000000..93cc6e2 --- /dev/null +++ b/README-docker-in-docker.md @@ -0,0 +1,146 @@ +# 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: +```bash +# This won't work in Gitea Actions +docker run -v $(pwd):/workspace alpine:latest ls -la /workspace +``` + +Use: +```bash +# This works in Gitea Actions +docker run --volumes-from="${JOB_CONTAINER_NAME}" alpine:latest sh -c "cd ${GITHUB_WORKSPACE} && ls -la" +``` + +## Complete Example + +```yaml +# .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 + +```bash +# 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: + ```bash + if [ -n "${JOB_CONTAINER_NAME:-}" ]; then + echo "Running in Gitea Actions" + else + echo "Running locally" + fi + ``` + +2. List available environment variables: + ```bash + env | grep -E "(JOB_|GITHUB_|GITEA_)" | sort + ``` + +3. Debug volume mounts: + ```bash + # 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: +```bash +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: +```bash +# 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 + +- [Gitea Actions Documentation](https://docs.gitea.io/en-us/actions-overview/) +- [Related GitHub Issue #189](https://gitea.com/gitea/act_runner/issues/189) \ No newline at end of file diff --git a/docker-in-docker-example.sh b/docker-in-docker-example.sh new file mode 100755 index 0000000..d5cda5f --- /dev/null +++ b/docker-in-docker-example.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +set -euo pipefail + +echo "=== Docker-in-Docker Example for Gitea Actions ===" +echo "JOB_CONTAINER_NAME: ${JOB_CONTAINER_NAME:-not set}" +echo "GITHUB_WORKSPACE: ${GITHUB_WORKSPACE:-$(pwd)}" +echo "" + +# Create a simple Dockerfile for testing +cat > Dockerfile.test << 'EOF' +FROM alpine:latest +RUN apk add --no-cache bash +WORKDIR /app +COPY . . +CMD ["bash", "-c", "echo 'Hello from Docker container!' && ls -la"] +EOF + +# Create a test file +echo "This is a test file created in Gitea Actions" > test-data.txt + +if [ -n "${JOB_CONTAINER_NAME:-}" ]; then + echo "Running in Gitea Actions - using --volumes-from for Docker operations" + echo "" + + # Build the Docker image + echo "1. Building Docker image..." + docker build -f Dockerfile.test -t test-image:latest . + echo "" + + # Run container with volumes from the job container + echo "2. Running Docker container with shared volumes..." + docker run --rm \ + --volumes-from="${JOB_CONTAINER_NAME}" \ + -w "${GITHUB_WORKSPACE}" \ + test-image:latest + echo "" + + # Example: Running a command that needs access to workspace files + echo "3. Running Alpine container to process workspace files..." + docker run --rm \ + --volumes-from="${JOB_CONTAINER_NAME}" \ + alpine:latest sh -c "cd ${GITHUB_WORKSPACE} && echo 'Files in workspace:' && find . -type f -name '*.txt' | head -10" + echo "" + + # Example: Using docker-compose (if needed) + echo "4. Creating docker-compose.yml for multi-container setup..." + cat > docker-compose.test.yml << EOF +version: '3' +services: + app: + image: alpine:latest + volumes_from: + - ${JOB_CONTAINER_NAME} + working_dir: ${GITHUB_WORKSPACE} + command: ["sh", "-c", "echo 'Hello from docker-compose!' && ls -la"] +EOF + + # Note: docker-compose with volumes_from requires special handling + echo "Note: For docker-compose, you may need to use docker run instead or configure the runner differently" + +else + echo "Running locally - using standard volume mounts" + echo "" + + # Build the Docker image + echo "1. Building Docker image..." + docker build -f Dockerfile.test -t test-image:latest . + echo "" + + # Run container with local volume mount + echo "2. Running Docker container with local volume..." + docker run --rm -v "$(pwd):/app" test-image:latest + echo "" + + # Example: Running Alpine with local mount + echo "3. Running Alpine container with local mount..." + docker run --rm -v "$(pwd):/workspace" -w /workspace alpine:latest sh -c "echo 'Files in workspace:' && find . -type f -name '*.txt' | head -10" +fi + +# Cleanup +rm -f Dockerfile.test test-data.txt docker-compose.test.yml + +echo "" +echo "=== Example completed successfully ===" \ No newline at end of file diff --git a/test.sh b/test.sh index 40dfe9c..c6ccc53 100755 --- a/test.sh +++ b/test.sh @@ -50,32 +50,8 @@ if [ -n "${JOB_CONTAINER_NAME:-}" ]; then rm -f test-file.txt else echo "--------------------------------" - echo "Running locally - using direct volume mounts" + echo "Running locally - no test." echo "--------------------------------" - - echo "ls -la ./" - docker run --rm -i --entrypoint /bin/bash -v ./:/workspace debian:latest -c "ls -la /workspace" - echo "--------------------------------" - echo "ls -la \$PWD" - docker run --rm -i --entrypoint /bin/bash -v "$PWD:/workspace" debian:latest -c "ls -la /workspace" - echo "--------------------------------" - echo "ls -la \$SCRIPT_DIR" - docker run --rm -i --entrypoint /bin/bash -v "$SCRIPT_DIR:/workspace" debian:latest -c "ls -la /workspace" fi -echo "--------------------------------" - -MOUNT_DIR="$SCRIPT_DIR" -if [ -n "${HOST_WORKSPACE_PATH:-}" ]; then - MOUNT_DIR=$(echo "$SCRIPT_DIR" | sed "s|^/workspace|$HOST_WORKSPACE_PATH|") - if [ "$MOUNT_DIR" != "$SCRIPT_DIR" ]; then - echo "Docker-in-Docker: Mapping $SCRIPT_DIR to $MOUNT_DIR" - fi -fi - -echo "MOUNT_DIR: $MOUNT_DIR" -echo "ls -la \$MOUNT_DIR" -docker run --rm -i --entrypoint /bin/bash -v "$MOUNT_DIR:/workspace" debian:latest -c "ls -la /workspace" - -echo "--------------------------------"