Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docker mirrors support #653

Open
JSBmanD opened this issue May 30, 2024 · 5 comments
Open

Add docker mirrors support #653

JSBmanD opened this issue May 30, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@JSBmanD
Copy link

JSBmanD commented May 30, 2024

Context

Currently there's no possibility to change list of docker mirrors

Suggested solution

Will be nice to have variable to set list of mirrors for docker

@JSBmanD JSBmanD added the enhancement New feature or request label May 30, 2024
@GabLeRoux
Copy link
Member

Hi,
I did not know about this before reading this issue. Here is a Stack Overflow post requesting for Docker registry mirrors

Can you elaborate on why we should implement this?

  • Do you have any use case or specific reasons that makes it better?
  • Have you encountered problems because of the lack of mirrors so far?

These are honest questions by the way, I am mostly curious to know how having mirrors could benefit the different actions. I suppose that this feature would probably have to reach the different other related github actions too.

Possible Implementation details

In the case where someone would be interested in implementing this, my understanding is that we would have to update these files:

class Input {
  // ... existing code ...

  static get dockerRegistryMirrors(): string[] {
    const input = Input.getInput('dockerRegistryMirrors');
    if (!input) {
      return [];
    }
    
    try {
      return yaml.load(input) as string[];
    } catch (e) {
      core.error(`Failed to parse dockerRegistryMirrors input: ${e}`);
      return [];
    }
  }

  // ... existing code ...
}

Somewhere in here:

static getLinuxCommand(
image: string,
parameters: DockerParameters,
overrideCommands: string = '',
additionalVariables: StringKeyValuePair[] = [],
entrypointBash: boolean = false,
): string {
const {
workspace,
actionFolder,
runnerTempPath,
sshAgent,
sshPublicKeysDirectoryPath,
gitPrivateToken,
dockerWorkspacePath,
dockerCpuLimit,
dockerMemoryLimit,
} = parameters;
const githubHome = path.join(runnerTempPath, '_github_home');
if (!existsSync(githubHome)) mkdirSync(githubHome);
const githubWorkflow = path.join(runnerTempPath, '_github_workflow');
if (!existsSync(githubWorkflow)) mkdirSync(githubWorkflow);
const commandPrefix = image === `alpine` ? `/bin/sh` : `/bin/bash`;
return `docker run \
--workdir ${dockerWorkspacePath} \
--rm \
${ImageEnvironmentFactory.getEnvVarString(parameters, additionalVariables)} \
--env GITHUB_WORKSPACE=${dockerWorkspacePath} \
--env GIT_CONFIG_EXTENSIONS \
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
--volume "${githubHome}":"/root:z" \
--volume "${githubWorkflow}":"/github/workflow:z" \
--volume "${workspace}":"${dockerWorkspacePath}:z" \
--volume "${actionFolder}/default-build-script:/UnityBuilderAction:z" \
--volume "${actionFolder}/platforms/ubuntu/steps:/steps:z" \
--volume "${actionFolder}/platforms/ubuntu/entrypoint.sh:/entrypoint.sh:z" \
--volume "${actionFolder}/unity-config:/usr/share/unity3d/config/:z" \
--volume "${actionFolder}/BlankProject":"/BlankProject:z" \
--cpus=${dockerCpuLimit} \
--memory=${dockerMemoryLimit} \
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
${
sshAgent && !sshPublicKeysDirectoryPath
? '--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro'
: ''
} \
${sshPublicKeysDirectoryPath ? `--volume ${sshPublicKeysDirectoryPath}:/root/.ssh:ro` : ''} \
${entrypointBash ? `--entrypoint ${commandPrefix}` : ``} \
${image} \
${entrypointBash ? `-c` : `${commandPrefix} -c`} \
"${overrideCommands !== '' ? overrideCommands : `/entrypoint.sh`}"`;
}
:

We would have to add something like this:

    const registryMirrors = Input.dockerRegistryMirrors.map(mirror => `--registry-mirror=${mirror}`).join(' ');

    return `docker run \
            ${registryMirrors} \
            // ...

And maybe for the windows based docker run command too?

docker.ts

And then, could be used with something like this in the workflow file:

      - name: Build with Docker
        run: |
          # Your build steps here
        with:
          dockerRegistryMirrors: |
            - https://mirror1.example.com
            - https://mirror2.example.com

If this is absolutely necessary, don't forget that you can fork the repository, update the code and try it 👍

@JSBmanD
Copy link
Author

JSBmanD commented May 31, 2024

Hi! @GabLeRoux

Do you have any use case or specific reasons that makes it better?

Sure, as the first use case - recently some political games happened and docker hub restricted access to machines from Russia where my runner is located. For sure it doesn't anyhow restrict the access as I can enable proxy/vpn on it. Outside of the game-ci people using mirrors like Google's one or any other but here it's not much flexibility so it will be great to see it. Another reason if someone needs custom docker registry.

Have you encountered problems because of the lack of mirrors so far?

Yes, as my runner is located in Russia.

@webbertakken
Copy link
Member

webbertakken commented May 31, 2024

Instead of "dockerRegistryMirrors" we should probably consider naming this "dockerRegistry", as the protocol is the same across registries, and I'm assuming the mirror is a custom registry and not an actual mirror (correct me if I'm wrong).

Have you encountered problems because of the lack of mirrors so far?

Yes, as my runner is located in Russia.

That seems like a good enough reason to support this to me.

By the way, have you considered using customImage parameter? Any reason why that wouldn't work as expected?

@JSBmanD
Copy link
Author

JSBmanD commented May 31, 2024

@webbertakken as I understood, customImage is only for specifying images not full url?

@GabLeRoux
Copy link
Member

GabLeRoux commented May 31, 2024

Technically speaking, we can use customImage to specify an image with the registry url. It is not the same as a mirror, but it does allow you to use a different registry. This is indeed a good alternative which already works right now.

I'm not exactly sure how we could use images on a private registry as a login must happen prior to running docker commands, but there's probably a way for that too.

Here are some examples to illustrate how this can be done:

Registry Image Name Format
Docker Hub unityci/editor:ubuntu-2023.2.20f1-base-3.1.0
GitHub Container Registry (ghcr.io) ghcr.io/unityci/editor:ubuntu-2023.2.20f1-base-3.1.0

Examples using command line

  • Docker Hub:

    docker pull unityci/editor:ubuntu-2023.2.20f1-base-3.1.0
  • GitHub Container Registry (ghcr.io):

    docker pull ghcr.io/unityci/editor:ubuntu-2023.2.20f1-base-3.1.0

Note: this is only an example, we do not have images hosted on ghcr.io.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants