Add Docker to macOS installation

docker
#1

Description of the feature request

Add Docker as a default installation to all VMs running macOS/Xcode.

Use case / for what or how I would use it

Allows easy use of supporting services that are used in testing an application. Will cut down on installations that might be involved and expensive (due to installation time). This will also negate the possible challenges of trying to run the same services in different environments.

0 Likes

How to use your own Docker image for your builds
#2

Hi @aroswell,

Thanks for the #feature-request!

For now we don’t plan to preinstall docker on the Mac stacks, but if this request gets enough votes we’ll definitely consider it.

Why we don’t plan to preinstall it (for now): as discussed in How to use your own Docker image for your builds Docker for Mac, which is the current preferred official solution, doesn’t really work in a virtualized environment and has some other issues too.

The older Docker Toolkit does work, but it’s marked as semi-deprecated, although there are still quite a few docker tools which only work with that (e.g. docker-machine) and does not with Docker for Mac.

Other than the stability / deprecation issue resource constraints are also a factor. If an iOS build doesn’t need Docker, the resources consumed by Docker are a waste. Why does docker consume resources? Because Docker on the Mac uses a virtualized Linux to run the docker commands, as there is no native Mac support in docker. The standard Docker is built on Linux (kernel) technologies.

That said, if you need Docker on the Mac stacks, it’s definitely possible to install and use it. It takes about 30 seconds to install with brew and another ~80 seconds to boot the required host (linux virtual machine).

An example configuration using Script steps to install and start docker-toolkit:

---
format_version: 3
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
trigger_map:
- push_branch: "*"
  workflow: primary
- pull_request_source_branch: "*"
  workflow: primary
workflows:
  primary:
    steps:
    - script@1.1.4:
        title: brew cask install docker-toolbox
        inputs:
        - content: |-
            #!/bin/bash
            set -ex

            brew cask install docker-toolbox
    - script@1.1.4:
        title: docker-machine create
        inputs:
        - content: |-
            #!/bin/bash
            set -ex

            docker-machine create --driver "virtualbox" default
    - script@1.1.4:
        title: use docker
        inputs:
        - content: |-
            #!/bin/bash
            set -ex

            eval $(docker-machine env default)

            docker version
            docker run hello-world

Note: you have to run the eval $(docker-machine env default) command in every Script where you want to use docker, as it only sets the environments for the script it was invoked in!

0 Likes

How to use your own Docker image for your builds
#3

Thanks. I was trying with brew cask install docker, but hit a wall when launching docker because the docker app needs root permission after it’s initial installation.
I’ve taken your suggestion and it seems to work (slowly but surely).

1 Like

#4

Root permission shouldn’t be an issue (passwordless sudo is enabled on all stacks), but indeed Docker for Mac can’t be used right now on the Mac stacks it seems. We’ll try to find a solution for it eventually, if they don’t fix the related issues, but in the meantime docker-toolbox should be a suitable solution :slight_smile:

0 Likes

#5

The docker installation as per your instructions worked like a charm. However, I’ve not been able to connect to the service inside the container. I’ve posted this in the slack channel but also thought it would benefit others here as well. If I find a solution or you come up with one, I will make it known here.

+ docker run -d -p 8888:8888 -p 8500:8500 --name hoverfly azohra/hoverfly
36a154bae98b8c2eafd71542f26b602aa66527c939245e3a09450d15ef775331
+ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED                  STATUS                  PORTS                                            NAMES
36a154bae98b        azohra/hoverfly     "/go/bin/hoverfly ..."   Less than a second ago   Up Less than a second   0.0.0.0:8500->8500/tcp, 0.0.0.0:8888->8888/tcp   hoverfly
+ docker logs hoverfly
INFO[2017-07-26T15:40:17Z] Using memory backend                         
INFO[2017-07-26T15:40:17Z] Webserver prepared...                         Destination=. Mode=simulate WebserverPort=8500
INFO[2017-07-26T15:40:17Z] current proxy configuration                   destination=. mode=simulate port=8500
INFO[2017-07-26T15:40:17Z] Admin interface is starting...                AdminPort=8888
INFO[2017-07-26T15:40:17Z] serving proxy                                
+ curl http://0.0.0.0:8888/api/v2/logs
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to 0.0.0.0 port 8888: Connection refused

Simple curl command using localhost and 0.0.0.0 returns with a connection error.

0 Likes

#6

@aroswell it seems that Docker Toolbox does not expose the port for localhost automatically (technically, there’s no automatic port forwarding set up from the host (macOS) to the VM docker is running inside (a Linux VM in VirtualBox)).

You can get the IP of the docker host VM with:

docker_host_ip="$(docker-machine ip default)"

(default is the name of the VM created with docker-machine in the example at Add Docker to macOS installation - if you use another name you should change it to that)

Then you can curl it like in the same Script:

curl "$docker_host_ip"

If you need it in another script you should export it as an env var with envman (http://devcenter.bitrise.io/tips-and-tricks/expose-environment-variable/):

envman add --key DOCKER_HOST_IP --value "$docker_host_ip"

Note: the “default” machine’s IP seems to be a predefined IP, 192.168.99.100, so you can use that directly too in most cases. (See e.g. https://forums.docker.com/t/using-localhost-for-to-access-running-container/3148/6 and I also tested docker-machine ip default in a quick Bitrise.io build and returned the same IP). You can of course set up a port forwarding for the IP too, so that you can just “localhost:IP” to address it.

0 Likes

#7

@viktorbenei This worked well. No issues. Thanks.

1 Like

#8

I’m using macOS to get access to both Android and iOS toolbox to build React Native project. This project as multiple facets as a website and backend is also being built in it.

As such, having Docker pre-installed to at least build images would be a nice gain of time. Voted +1 :slight_smile:

Cheers,
Matt

2 Likes

#9

Keep the votes coming! :wink: We definitely do keep this in mind, just waiting for more votes & to see how the Docker on Mac story evolves (e.g. whether Docker Toolkit remains or will be deprecated/removed).

0 Likes

#10

Would be great to have docker toolbox and the virtualbox VM pre-installed. Would shave a couple minutes off our build with docker times. E.g.:

brew cask install docker-toolbox
docker-machine create --driver “virtualbox” default

Added my up-vote. Thanks!

1 Like

#11

Hello!

I am trying to access a docker service for testing purposes and unfortunately i am not able to access it through localhost. The script i am using is:

docker-machine create --driver "virtualbox" default
eval $(docker-machine env default)
docker run --privileged --env CI=false -d -p 4040:8080 --name wiremock rodolpheche/wiremock:latest

docker exec -i $(docker ps | awk 'END {print $1}') bash -c "curl localhost:8080/__admin/mappings"

I am getting the following error:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to localhost port 8080: Connection refused

I have tried also

docker-machine create --driver "virtualbox" default
eval $(docker-machine env default)
docker run --privileged --env CI=false -d -p 4040:8080 --name wiremock rodolpheche/wiremock:latest
curl http://localhost:4040/__admin/mappings

I have tried also:

brew cask install docker-toolbox
docker-machine create --driver "virtualbox" default
# docker_host_ip="$(docker-machine ip default)"
eval $(docker-machine env default)
docker pull rodolpheche/wiremock:latest
docker run --privileged --env CI=false  -d -p 4040:8080 --name wiremock rodolpheche/wiremock:latest
vboxmanage controlvm default natpf1 "tcp-port4040,tcp,127.0.0.1,4040,,4040"
docker-machine ip
curl http://localhost:4040/__admin/mappings

I have tried also:

brew cask install docker-toolbox
docker-machine create --driver "virtualbox" default
docker_host_ip="$(docker-machine ip default)"
eval $(docker-machine env default)
docker pull rodolpheche/wiremock:latest
docker run --privileged --env CI=false  -d -p 4040:4040 -p 8080:8080 --name wiremock rodolpheche/wiremock:latest
vboxmanage controlvm default natpf1 "tcp-port4040,tcp,127.0.0.1,4040,,4040"
docker ps -a
docker-machine ip
docker-machine ls

curl "$docker_host_ip":4040/__admin/mappings

Nothing seems to work.

Could you please advice?

0 Likes