11#! /bin/bash
22
3+ set -e
4+
35# Handle symlinks here as we tend to be executed as an npm binary
46SCRIPT_PATH=$( readlink -f " $0 " )
57SCRIPT_DIR=$( dirname " $SCRIPT_PATH " )
@@ -24,6 +26,20 @@ build_image() {
2426 docker build -t " $IMAGE_NAME " --build-arg " PLAYWRIGHT_VERSION=$PW_VERSION " " $SCRIPT_DIR "
2527}
2628
29+ # Find the docker socket on the host
30+ case " $DOCKER_HOST " in
31+ unix://* )
32+ docker_sock=" ${DOCKER_HOST: 7} "
33+ ;;
34+ " " )
35+ docker_sock=" /var/run/docker.sock"
36+ ;;
37+ * )
38+ echo " $0 : unsupported DOCKER_HOST setting '${DOCKER_HOST} '" >&2
39+ exit 1;
40+ ;;
41+ esac
42+
2743RUN_ARGS=(
2844 --rm
2945 --network host
@@ -33,7 +49,7 @@ RUN_ARGS=(
3349 # Bind mount the working directory into the container
3450 -v $( pwd) :/work/
3551 # Bind mount the docker socket so we can run docker commands from the container
36- -v /var/run/docker.sock :/var/run/docker.sock
52+ -v " ${docker_sock} " :/var/run/docker.sock
3753 # Bind mount /tmp so we can store temporary files
3854 -v /tmp/:/tmp/
3955 -it
6985build_image
7086
7187# Ensure we pass all symlinked node_modules to the container
72- pushd node_modules || exit > /dev/null
88+ pushd node_modules > /dev/null
7389SYMLINKS=$( find . -maxdepth 2 -type l -not -path " ./.bin/*" )
74- popd || exit > /dev/null
90+ popd > /dev/null
7591for LINK in $SYMLINKS ; do
76- TARGET=$( readlink -f " node_modules/$LINK " )
92+ TARGET=$( readlink -f " node_modules/$LINK " ) || true
7793 if [ -d " $TARGET " ]; then
94+ if docker --version | grep -q podman; then
95+ echo -e " \033[31m" >&2
96+ cat << 'EOF ' >&2
97+ WARNING: `node_modules` contains symlinks, and the support for this in
98+ `playwright-screenshots.sh` is broken under podman due to
99+ https://github.com/containers/podman/issues/25947.
100+
101+ If you get errors such as 'Error: crun: creating `<path>`', then retry this
102+ having `yarn unlink`ed the relevant node modules.
103+ EOF
104+ echo -e " \033[0m" >&2
105+ fi
78106 echo " mounting linked package ${LINK: 2} in container"
79107 RUN_ARGS+=( " -v" " $TARGET :/work/node_modules/${LINK: 2} " )
80108 fi
81109done
82110
111+ # Our Playwright fixtures use Testcontainers [1], which uses a docker image
112+ # called Ryuk [2], which will clean up any dangling containers/networks/etc
113+ # after a timeout, if the parent process dies unexpectedly.
114+ #
115+ # To do this, Ryuk requires access to the docker socket, so Testcontainers
116+ # starts the Ryuk container with a bind-mount of `/var/run/docker.sock`.
117+ # However, we're going to be running Playwright (and hence Testcontainers)
118+ # itself in a container, but talking to the Docker daemon on the *host*, which
119+ # means that bind mounts will be relative to the *host* filesystem. In short,
120+ # it will try to bind-mount the *host's* `/var/run/docker.sock` rather than
121+ # that from inside the element-web-playwright-common container.
122+ #
123+ # To solve this problem, we start Ryuk ourselves (with the correct docker
124+ # socket) rather than waiting for Testcontainers to do so. Testcontainers will
125+ # find the running Ryuk instance and connect to it rather than start a new one.
126+ #
127+ # [1] https://testcontainers.com/
128+ # [2] https://github.com/testcontainers/moby-ryuk
129+ docker run -d --rm --label org.testcontainers.ryuk=true -v " ${docker_sock} " :/var/run/docker.sock -p 8080 --name=" playwright-ryuk" testcontainers/ryuk:0.14.0
130+
83131docker run " ${RUN_ARGS[@]} " " $IMAGE_NAME " " ${DEFAULT_ARGS[@]} " " $@ "
0 commit comments