Skip to content

Commit

Permalink
Fix Docker build and improve checks #220
Browse files Browse the repository at this point in the history
This commit improves multiple aspects of Docker builds:

- Enable artifact output validation for Dockerfile.
- Correct the path references in Dockerfile for the distribution
  directory.
- Add Dockerfile specific indentation rules to `.editorconfig`.
- Use `npm run install-deps` for dependency installation, enhancing
  build reliability.
- Add automation script `verify-web-server-status.js` to verify running
  web server on given URL.
- Introduce automated build verification for Dockerfile:
  - On macOS, install Docker with colima as the container runtime
    because default agents do not include Docker and Docker runtime is
    not installed due to licensing issues (see actions/runner-images#17).
  - On Windows, there's no Linux container support (actions/runner#904,
    actions/runner-images#1143), so keep the checks for macOS and Ubuntu
    only.
  • Loading branch information
LarrMarburger authored and undergroundwires committed Sep 27, 2023
1 parent a6b6407 commit 2469413
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 12 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100

[{Dockerfile}]
indent_style = space
indent_size = 4
32 changes: 31 additions & 1 deletion .github/workflows/checks.build.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: build-checks
name: checks.build

on:
push:
Expand Down Expand Up @@ -68,3 +68,33 @@ jobs:
-
name: Verify bundled desktop build artifacts
run: npm run check:verify-build-artifacts -- --electron-bundled

build-docker:
strategy:
matrix:
os: [ macos, ubuntu ] # Windows runners do not support Linux containers
fail-fast: false # Allows to see results from other combinations
runs-on: ${{ matrix.os }}-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Install Docker on macOS
if: matrix.os == 'macos' # macOS runner is missing Docker
run: |-
# Install Docker
brew install docker
# Docker on macOS misses daemon due to licensing, so install colima as runtime
brew install colima
# Start the daemon
colima start
-
name: Build Docker image
run: docker build -t undergroundwires/privacy.sexy:latest .
-
name: Run Docker image on port 8080
run: docker run -d -p 8080:80 --rm --name privacy.sexy undergroundwires/privacy.sexy:latest
-
name: Check server is up and returns HTTP 200
run: node ./scripts/verify-web-server-status.js --url http://localhost:8080
17 changes: 10 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Build
FROM node:lts-alpine as build-stage
FROM node:lts-alpine AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
RUN npm run install-deps
RUN npm run build \
&& npm run check:verify-build-artifacts -- --web
RUN mkdir /dist \
&& dist_directory=$(node 'scripts/print-dist-dir.js' --web) \
&& cp -a "${dist_directory}/." '/dist'

# Production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
FROM nginx:stable-alpine AS production-stage
COPY --from=build-stage /dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
CMD ["nginx", "-g", "daemon off;"]
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
</a>
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.build.yaml" target="_blank" rel="noopener noreferrer">
<img
alt="Build checks status"
src="https://github.com/undergroundwires/privacy.sexy/workflows/build-checks/badge.svg"
alt="Status of build checks"
src="https://github.com/undergroundwires/privacy.sexy/workflows/checks.build/badge.svg"
/>
</a>
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.desktop-runtime-errors.yaml" target="_blank" rel="noopener noreferrer">
Expand Down
6 changes: 4 additions & 2 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ See [ci-cd.md](./ci-cd.md) for more information.

1. Build: `docker build -t undergroundwires/privacy.sexy:latest .`
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy undergroundwires/privacy.sexy:latest`
3. Application should be available at [`http://localhost:8080`](http://localhost:8080)

### Building

Expand All @@ -81,11 +82,12 @@ See [ci-cd.md](./ci-cd.md) for more information.

#### Automation scripts

- [**`node scripts/print-dist-dir.js [-- <options>]`**](../scripts/print-dist-dir.js):
- [**`node scripts/print-dist-dir.js [<options>]`**](../scripts/print-dist-dir.js):
- Determines the absolute path of a distribution directory based on CLI arguments and outputs its absolute path.
- Primarily used by automation scripts.
- [**`npm run check:verify-build-artifacts [-- <options>]`**](../scripts/verify-build-artifacts.js):
- Verifies the existence and content of build artifacts. Useful for ensuring that the build process is generating the expected output.
- [**`node scripts/verify-web-server-status.js --url [URL]`**](../scripts/verify-web-server-status.js):
- Checks if a specified server is up with retries and returns an HTTP 200 status code.

## Recommended extensions

Expand Down
62 changes: 62 additions & 0 deletions scripts/verify-web-server-status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Description:
* This script checks if a server, provided as a CLI argument, is up
* and returns an HTTP 200 status code.
* It is designed to provide easy verification of server availability
* and will retry a specified number of times.
*
* Usage:
* node ./scripts/verify-web-server-status.js --url [URL]
*
* Options:
* --url URL of the server to check
*/

import { get } from 'http';

const MAX_RETRIES = 30;
const RETRY_DELAY_IN_SECONDS = 3;
const URL_PARAMETER_NAME = '--url';

function checkServer(currentRetryCount = 1) {
const serverUrl = getServerUrl();
console.log(`Requesting ${serverUrl}...`);
get(serverUrl, (res) => {
if (res.statusCode === 200) {
console.log('🎊 Success: The server is up and returned HTTP 200.');
process.exit(0);
} else {
console.log(`Server returned HTTP status code ${res.statusCode}.`);
retry(currentRetryCount);
}
}).on('error', (err) => {
console.error('Error making the request:', err);
retry(currentRetryCount);
});
}

function retry(currentRetryCount) {
console.log(`Attempt ${currentRetryCount}/${MAX_RETRIES}:`);
console.log(`Retrying in ${RETRY_DELAY_IN_SECONDS} seconds.`);

const remainingTime = (MAX_RETRIES - currentRetryCount) * RETRY_DELAY_IN_SECONDS;
console.log(`Time remaining before timeout: ${remainingTime}s`);

if (currentRetryCount < MAX_RETRIES) {
setTimeout(() => checkServer(currentRetryCount + 1), RETRY_DELAY_IN_SECONDS * 1000);
} else {
console.log('Failure: The server at did not return HTTP 200 within the allocated time. Exiting.');
process.exit(1);
}
}

function getServerUrl() {
const urlIndex = process.argv.indexOf(URL_PARAMETER_NAME);
if (urlIndex === -1 || urlIndex === process.argv.length - 1) {
console.error(`Parameter "${URL_PARAMETER_NAME}" is not provided.`);
process.exit(1);
}
return process.argv[urlIndex + 1];
}

checkServer();

0 comments on commit 2469413

Please sign in to comment.