5

I am trying to create an Minio/S3 container so I can run my test suite as an action on github. I currently have the following:

name: Run Tests
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-18.04

    services:
      postgres:
        ...

      minio:
        image: minio/minio
        volumes:
          - /data
        ports:
          - 9000:9000
        env:
          MINIO_ACCESS_KEY: minio
          MINIO_SECRET_KEY: minio123
        options: --entrypoint "minio server /data" --health-cmd "curl -f http://localhost:9000/minio/health/live" --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      ...

I have tried the following permutations to get the minio container to work but with no success:

volumes:
  - ./data:/data

volumes:
  - ./:/data

volumes:
  - .:/data

volumes:
  - /data:/data

And I even tried:

options: --entrypoint "mkdir /data; minio server /data" ...

options: --entrypoint "minio server /tmp" ...

options: --entrypoint ["minio server", "/tmp"] ...

And I have tried using the -v flag to mount volumes before the --entrypoint flag.

options: -v /s3_data:/data --entrypoint "minio server /data" ...

options: -v ${{ github.workspace }}/s3_data:/data --entrypoint "minio server /data" ...

options: -v ${{ github.workspace }}/s3_data:/data:rw --entrypoint "minio server /data" ...

In an attempt to get it to work. But unfortunately I get:

starting container process caused: exec: "minio server /data": stat minio server /data: no such file or directory: unknown

And I can't run the minio server without any argument :(

Robert Johnstone
  • 5,431
  • 12
  • 58
  • 88

3 Answers3

7

TL;DR;

There exists an ongoing GitHub Actions Community thread concerning the lack of support for setting jobs.<job_id>.services.<service_id>.command and this existing question is very similar to yours.


You could extend the official image as suggested by @ahasbini then build and push your docker image to a Docker Registry and use your own image in the GitHub Actions jobs.<job_id>.services.<service_id>.image. For example:

The Dockerfile:

FROM minio/minio
CMD ["server", "/data", "--address=0.0.0.0:9000"]

Note: you can use the lazybit/minio image I built for this answer.

The job.<job_id>.services.<service_id> spec:

jobs:
  ...
  minio:
    name: minio
    runs-on: ubuntu-latest
    services:
      minio:
        image: lazybit/minio
        ports:
          - 9000:9000
        env:
          MINIO_ACCESS_KEY: ${{ secrets.MINIO_ACCESS_KEY }}
          MINIO_SECRET_KEY: ${{ secrets.MINIO_SECRET_KEY }}
        volumes:
          - ${{ github.workspace }}/data:/data
        options: --name=minio --health-cmd "curl http://localhost:9000/minio/health/live"
    steps:
      - run: pip3 install minio
      - run: |
            python3 - <<'EOF'
            from minio import Minio
            from minio.error import ResponseError

            try:
                minio = Minio(
                    'localhost:9000',
                    access_key='${{ secrets.MINIO_ACCESS_KEY }}',
                    secret_key='${{ secrets.MINIO_SECRET_KEY }}',
                    secure=False
                )
            except Exception as ex:
                raise

            minio.make_bucket('foo')
            minio.make_bucket('bar')
            print(f'{minio.list_buckets()}')
            EOF

Notes:

  1. The minio/minio images do not currently have a HEALTHCHECK instruction set (docker inspect minio/minio:latest --format {{.Config.Healthcheck}}) so we need to set the --health-cmd in the jobs.<job_id>.services.<service_id>.options to hit the services livenessProbe endpoint to make sure the service is running before we start running the jobs.<job_id>.steps
  2. I had some issues connecting to the service by name so I set the minio endpoint to locahost:9000, the GitHub Actions are run in a Kubernetes Pod, they share the same network namespace and are accessible via localhost
  3. Accessing encrypted secrets in the jobs.<job_id>.services.<service_id>.env and jobs.<job_id>.steps.<step_id>.run
  4. Mounting a local directory as the volume backing the minio service using the github context's workspace

GitHub Actions minio service

masseyb
  • 3,745
  • 1
  • 17
  • 29
  • 2
    MinIO publishes a container for this purpose alone `minio/minio:edge-cicd` - https://hub.docker.com/layers/minio/minio/edge-cicd/images/sha256-29e8e51691d11e779468f275002779b221fd3902518d103e35c8a8bb2ef0f3ea?context=explore – Harshavardhana Nov 10 '21 at 19:16
  • 1
    @Harshavardhana Can you post an example using that minio/minio:edge-cicd image while also creating a specific bucket? – k0pernikus Apr 11 '22 at 12:11
  • Here is a full working example: https://github.com/minio/minio/discussions/16099 – William Desportes Nov 19 '22 at 11:39
  • 1
    The link to the GH Actions community thread is broken. I've started another one discussing this issue [here](https://github.com/orgs/community/discussions/52675). The question addresses the broader issue of passing commands to service containers, not necessarily the specifics of getting minio to run as a service container. – teuber789 Apr 12 '23 at 23:23
3

The error is complaining about the --entrypoint "minio server /data", not about the volumes configuration. It seems to be looking for a file called minio server /data rather than executing the command in a shell. Here's a good explanation of how --entrypoint flag works, the reason is because --entrypoint requires a file (either a binary file or a script) to execute and not the command with arguments to run. It appears that this is quite difficult to overcome as seen here as well.

The only suggestion I would think of is to build on top of the minio/minio Docker image with the arguments set in the Dockerfile and upload it to DockerHub so you could use it as the image instead.

Below is a sample Dockerfile you could use:

FROM minio/minio
ENTRYPOINT ["/usr/bin/docker-entrypoint.sh", "minio", "server", "/data"]
ahasbini
  • 6,761
  • 2
  • 29
  • 45
1

I don't recommend this solution, but want to leave it out there in case somebody else is banging their head against a brick wall and wants a quick but convoluted solution.


In our workflow we added:

    services:
      minio:
        # fixme: let's not depend on external unofficial image
        image: lazybit/minio
        ports:
          - 9000:9000
        env:
          MINIO_ROOT_USER: accesskey
          MINIO_ROOT_PASSWORD: password
        options: --name=minio --health-cmd "curl http://localhost:9000/minio/health/live"
    steps:
      - run: wget https://dl.min.io/client/mc/release/linux-amd64/mc
      - run: chmod +x ./mc
      - run: ./mc alias set minio http://127.0.0.1:9000 accesskey password
      - run: ./mc mb --ignore-existing minio/MY_BUCKET

I used the unofficial lazybit/minio image as it was the offical one would not run.

Basically, the github action create one image with all the other images "merged". So we knew we coud access the minio service at http://localhost:9000. Alas, there is no easy way to set a default bucket via env variable, but we had to create the bucket via mc.


A few gotchas:

  • Minio uses endpoint over url in its config
  • minio requires your use_path_style_endpoint to be set to true

In our case we used a laravel app so we had to define the filesystem config like this:

<?php


$envUsingMinIo = ['local', 'testing-local'];
$usesMinIo = in_array(
    needle: env('APP_ENV'),
    haystack: $envUsingMinIo,
    strict: true
);

return [
    'disks' => [
        ...,
        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION', 'eu-west-1'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
            // the below 'endpoint' url is actually used for minio:
            'endpoint' => env('AWS_URL'),
            // use older urls:
            'use_path_style_endpoint' => $usesMinIo,
        ],
    ],
];

It may differ for your client.

k0pernikus
  • 60,309
  • 67
  • 216
  • 347