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

[WIP, draft] Improve Docker support #234

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,14 @@ jobs:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test

test-docker:
name: test on base Docker image 'node:${{ matrix.node-version }}-alpine'
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- run: docker build . --build-arg BASE_IMAGE=node:${{ matrix.node-version }}-alpine -t pa11y-ci-on-node-${{ matrix.node-version }}-alpine
31 changes: 31 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ARG BASE_IMAGE=node:20-alpine
FROM $BASE_IMAGE

# Install Chromium
RUN apk add --no-cache \
chromium

# Install Chromium's dependencies
RUN apk add --no-cache \
ca-certificates \
freetype \
harfbuzz \
nss \
ttf-freefont

# Switch user from 'root' to 'node' (inherited from node:alpine)
USER node

# Let's install global dependencies somewhere visitable by user 'node'
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin

# Avoid downloading Chromium again
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Install Pa11y CI and our config into the container
RUN npm install --global pa11y-ci
# COPY ./config.json /usr/config.json

ENTRYPOINT ["pa11y-ci", "--config", "/usr/config.json"]
84 changes: 60 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,36 +342,72 @@ module.exports = function (options) {

### Docker

If you want to run `pa11y-ci` in a Docker container then you can use the [`buildkite/puppeteer`](https://github.com/buildkite/docker-puppeteer) image as this installs Chrome and all the required libs to run headless chrome on Linux.
We could use [Puppeteer's official Docker image](https://pptr.dev/guides/docker) as the base of a Pa11y CI image. However, this would require the `SYS_ADMIN` capability, which will increase the security surface of the container. We can avoid this by installing Puppeteer and Chromium afresh at the cost of a more complex Dockerfile. This will also reduce the size of the Puppeteer-related layers from over 2GB to ~750MB.

You will need a `config.json` that sets the `--no-sandbox` Chromium launch arguments:
1. Create a `Dockerfile`. Install `pa11y-ci` within and supply `config.json`.

```json
{
"defaults": {
"chromeLaunchConfig": {
"args": [
"--no-sandbox"
]
}
},
"urls": [
"https://pa11y.org/",
"https://pa11y.org/contributing"
]
}
```
```Dockerfile
FROM node:20-alpine

And then a Dockerfile that installs `pa11y-ci` and adds the `config.json`
# Install Chromium
RUN apk add --no-cache \
chromium

```Dockerfile
FROM buildkite/puppeteer:v1.15.0
# Install Chromium's dependencies
RUN apk add --no-cache \
ca-certificates \
freetype \
harfbuzz \
nss \
ttf-freefont

RUN npm install --global --unsafe-perm pa11y-ci
ADD config.json /usr/config.json
# Switch user from 'root' to 'node' (inherited from node:alpine)
USER node

ENTRYPOINT ["pa11y-ci", "-c", "/usr/config.json"]
```
# Let's install global dependencies somewhere visitable by user 'node'
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin

# Avoid downloading Chromium again
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Install Pa11y CI and our config into the container
RUN npm install --global pa11y-ci
COPY ./config.json /usr/config.json

ENTRYPOINT ["pa11y-ci", "--config", "/usr/config.json"]
```

1. Create a `./config.json`. Use the `--no-sandbox` argument for Chromium.

```json
{
"defaults": {
"chromeLaunchConfig": {
"args": [
"--no-sandbox"
]
}
},
"urls": [
"https://pa11y.org/",
"https://pa11y.org/contributing"
]
}
```

1. Build our configured image.

```sh
docker build -t pa11y-ci-for-some-project .
```

1. Create and run a container from the image.

```sh
docker run pa11y-ci-for-some-project
```

## Tutorials and articles

Expand Down
Loading