From bd5c14242e40a53be80be4f66188d00829c9d987 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Wed, 15 Jun 2022 17:12:44 -0500 Subject: [PATCH] Make sure container is able to start up (#23) Follow-up to https://github.com/matrix-org/matrix-public-archive/pull/22 --- .github/workflows/containerize.yaml | 21 +++++++++++++++++++++ Dockerfile | 8 +++++++- docker-health-check.js | 22 ++++++++++++++++++++++ server/lib/fetch-endpoint.js | 6 +++--- server/routes/install-routes.js | 4 ++++ 5 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 docker-health-check.js diff --git a/.github/workflows/containerize.yaml b/.github/workflows/containerize.yaml index 1bb5e48..f6b6113 100644 --- a/.github/workflows/containerize.yaml +++ b/.github/workflows/containerize.yaml @@ -73,3 +73,24 @@ jobs: file: 'Dockerfile' tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + + # Just make sure the container can start-up and responds to the health check + test-image: + needs: [build-image] + runs-on: ubuntu-latest + + services: + matrix-public-archive: + image: ${{ needs.build-image.outputs.docker_image_name }}:sha-${{ github.sha }} + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + ports: + - 3050:3050 + env: + matrixServerUrl: http://FAKE_SERVER/ + matrixAccessToken: FAKE_TOKEN + + steps: + - name: See if the container will respond to a request + run: curl http://localhost:3050/health-check diff --git a/Dockerfile b/Dockerfile index d40ec7c..ae3c9b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,12 +6,16 @@ WORKDIR /app RUN npm install npm@^8 --location=global +# Copy the health-check script +COPY docker-health-check.js /app/ + # Copy just what we need to install the dependencies so this layer can be cached # in the Docker build COPY package.json package-lock.json /app/ RUN npm install # Copy what we need for the client-side build +COPY config /app/config/ COPY public /app/public/ COPY shared /app/shared/ COPY vite.config.js /app/ @@ -21,4 +25,6 @@ RUN npm run build # Copy the rest of the app COPY server /app/server/ -ENTRYPOINT ["npm" "start"] +HEALTHCHECK CMD node docker-health-check.js + +ENTRYPOINT ["/bin/bash", "-c", "npm start"] diff --git a/docker-health-check.js b/docker-health-check.js new file mode 100644 index 0000000..fb17bf8 --- /dev/null +++ b/docker-health-check.js @@ -0,0 +1,22 @@ +'use strict'; + +const assert = require('assert'); + +const { fetchEndpointAsJson } = require('./server/lib/fetch-endpoint'); + +const config = require('./server/lib/config'); +const basePort = config.get('basePort'); +assert(basePort); + +const healthCheckUrl = `http://localhost:${basePort}/health-check`; + +(async () => { + try { + await fetchEndpointAsJson(healthCheckUrl); + process.exit(0); + } catch (err) { + // eslint-disable-next-line no-console + console.log(`Health check error: ${healthCheckUrl}`, err); + process.exit(1); + } +})(); diff --git a/server/lib/fetch-endpoint.js b/server/lib/fetch-endpoint.js index cc25dad..158e2c4 100644 --- a/server/lib/fetch-endpoint.js +++ b/server/lib/fetch-endpoint.js @@ -48,15 +48,15 @@ async function fetchEndpointAsText(endpoint, options) { async function fetchEndpointAsJson(endpoint, options) { const opts = { - ...options, + ...(options || {}), headers: { Accept: 'application/json', 'Content-Type': 'application/json', - ...(options.headers || {}), + ...(options?.headers || {}), }, }; - if (options.body) { + if (options?.body) { opts.body = JSON.stringify(options.body); } diff --git a/server/routes/install-routes.js b/server/routes/install-routes.js index cef798b..9755d89 100644 --- a/server/routes/install-routes.js +++ b/server/routes/install-routes.js @@ -63,6 +63,10 @@ function parseArchiveRangeFromReq(req) { } function installRoutes(app) { + app.get('/health-check', async function (req, res) { + res.send('{ "ok": true }'); + }); + // We have to disable no-missing-require lint because it doesn't take into // account `package.json`. `exports`, see // https://github.com/mysticatea/eslint-plugin-node/issues/255