Skip to content

Commit 9da44d6

Browse files
authored
dev images (#10)
* docs: update README to clarify the status and architecture support of the Docker image * feat: add GitHub Actions workflow for building amd64 and arm64 Docker images * feat: add GitHub Actions workflow for testing amd64 and arm64 Docker builds * feat: specify platform for source, dependencies, and assets stages in Dockerfile.arm64 * feat: remove pull request trigger from build workflow * feat: update workflow triggers to ignore all branches except main * feat: update test-arm64 job to use correct runner for arm64 architecture * feat: update test-arm64 job to use standard ubuntu-24.04 runner --------- Co-authored-by: Alex Justesen <[email protected]>
1 parent d09ffb1 commit 9da44d6

File tree

5 files changed

+312
-19
lines changed

5 files changed

+312
-19
lines changed

.github/workflows/build-dev.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: Build Dev Images
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
env:
10+
REGISTRY: ghcr.io
11+
IMAGE_NAME: ${{ github.repository }}
12+
13+
jobs:
14+
build-amd64:
15+
runs-on: ubuntu-24.04
16+
permissions:
17+
contents: read
18+
packages: write
19+
id-token: write
20+
attestations: write
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Docker Buildx
27+
uses: docker/setup-buildx-action@v3
28+
29+
- name: Log in to Container Registry
30+
uses: docker/login-action@v3
31+
with:
32+
registry: ${{ env.REGISTRY }}
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Extract metadata
37+
id: meta
38+
uses: docker/metadata-action@v5
39+
with:
40+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
41+
tags: |
42+
type=raw,value=dev-amd64
43+
44+
- name: Build and push amd64 Docker image
45+
id: build-amd64
46+
uses: docker/build-push-action@v5
47+
with:
48+
context: .
49+
file: ./Dockerfile
50+
platforms: linux/amd64
51+
push: true
52+
tags: ${{ steps.meta.outputs.tags }}
53+
labels: ${{ steps.meta.outputs.labels }}
54+
build-args: |
55+
RELEASE_TAG=latest
56+
cache-from: type=gha,scope=amd64
57+
cache-to: type=gha,mode=max,scope=amd64
58+
59+
- name: Generate artifact attestation
60+
if: github.repository_visibility == 'public' || github.repository_owner_type == 'Organization'
61+
uses: actions/attest-build-provenance@v1
62+
with:
63+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
64+
subject-digest: ${{ steps.build-amd64.outputs.digest }}
65+
push-to-registry: true
66+
67+
build-arm64:
68+
runs-on: ubuntu-24.04
69+
permissions:
70+
contents: read
71+
packages: write
72+
id-token: write
73+
attestations: write
74+
75+
steps:
76+
- name: Checkout repository
77+
uses: actions/checkout@v4
78+
79+
- name: Set up Docker Buildx
80+
uses: docker/setup-buildx-action@v3
81+
82+
- name: Log in to Container Registry
83+
uses: docker/login-action@v3
84+
with:
85+
registry: ${{ env.REGISTRY }}
86+
username: ${{ github.actor }}
87+
password: ${{ secrets.GITHUB_TOKEN }}
88+
89+
- name: Extract metadata
90+
id: meta
91+
uses: docker/metadata-action@v5
92+
with:
93+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
94+
tags: |
95+
type=raw,value=dev-arm64
96+
97+
- name: Build and push arm64 Docker image
98+
id: build-arm64
99+
uses: docker/build-push-action@v5
100+
with:
101+
context: .
102+
file: ./Dockerfile.arm64
103+
platforms: linux/arm64
104+
push: true
105+
tags: ${{ steps.meta.outputs.tags }}
106+
labels: ${{ steps.meta.outputs.labels }}
107+
build-args: |
108+
RELEASE_TAG=latest
109+
cache-from: type=gha,scope=arm64
110+
cache-to: type=gha,mode=max,scope=arm64
111+
112+
- name: Generate artifact attestation
113+
if: github.repository_visibility == 'public' || github.repository_owner_type == 'Organization'
114+
uses: actions/attest-build-provenance@v1
115+
with:
116+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
117+
subject-digest: ${{ steps.build-arm64.outputs.digest }}
118+
push-to-registry: true

.github/workflows/test-build.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Test Docker Builds
2+
3+
on:
4+
push:
5+
branches-ignore:
6+
- main
7+
pull_request:
8+
branches-ignore:
9+
- main
10+
workflow_dispatch:
11+
12+
jobs:
13+
test-amd64:
14+
runs-on: ubuntu-24.04
15+
permissions:
16+
contents: read
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Docker Buildx
23+
uses: docker/setup-buildx-action@v3
24+
25+
- name: Test build amd64 Dockerfile
26+
uses: docker/build-push-action@v5
27+
with:
28+
context: .
29+
file: ./Dockerfile
30+
platforms: linux/amd64
31+
push: false
32+
build-args: |
33+
RELEASE_TAG=latest
34+
cache-from: type=gha,scope=test-amd64
35+
cache-to: type=gha,mode=max,scope=test-amd64
36+
37+
test-arm64:
38+
runs-on: ubuntu-24.04
39+
permissions:
40+
contents: read
41+
42+
steps:
43+
- name: Checkout repository
44+
uses: actions/checkout@v4
45+
46+
- name: Set up Docker Buildx
47+
uses: docker/setup-buildx-action@v3
48+
49+
- name: Test build arm64 Dockerfile
50+
uses: docker/build-push-action@v5
51+
with:
52+
context: .
53+
file: ./Dockerfile.arm64
54+
platforms: linux/arm64
55+
push: false
56+
build-args: |
57+
RELEASE_TAG=latest
58+
cache-from: type=gha,scope=test-arm64
59+
cache-to: type=gha,mode=max,scope=test-arm64

Dockerfile

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#############################
22
# Download source code (platform-independent)
33
#############################
4-
FROM --platform=$BUILDPLATFORM alpine:latest AS source
4+
FROM alpine:latest AS source
55

66
ARG RELEASE_TAG="latest"
77

@@ -30,7 +30,7 @@ RUN set -e; \
3030
#############################
3131
# Install Composer dependencies (platform-independent)
3232
#############################
33-
FROM --platform=$BUILDPLATFORM serversideup/php:8.4-fpm-nginx-alpine-v4.2.1 AS dependencies
33+
FROM serversideup/php:8.4-fpm-nginx-alpine-v4.2.1 AS dependencies
3434

3535
USER root
3636

@@ -56,7 +56,7 @@ USER www-data
5656
#############################
5757
# Build assets (platform-independent)
5858
#############################
59-
FROM --platform=$BUILDPLATFORM node:24-alpine AS assets
59+
FROM node:24-alpine AS assets
6060

6161
WORKDIR /app
6262

@@ -66,15 +66,14 @@ RUN --mount=type=cache,target=/root/.npm \
6666
npm ci && npm run build
6767

6868
#############################
69-
# Base image (platform-specific)
69+
# Base image (amd64-specific)
7070
#############################
71-
FROM serversideup/php:8.4-fpm-nginx-alpine-v4.2.1 AS base
71+
FROM --platform=linux/amd64 serversideup/php:8.4-fpm-nginx-alpine-v4.2.1 AS base
7272

7373
LABEL org.opencontainers.image.title="speedtest-tracker-docker" \
7474
org.opencontainers.image.authors="Alex Justesen (@alexjustesen)"
7575

76-
ARG TARGETARCH \
77-
LIBRESPEED_CLI_VERSION="1.0.12" \
76+
ARG LIBRESPEED_CLI_VERSION="1.0.12" \
7877
OOKLA_CLI_VERSION="1.2.0"
7978

8079
ENV AUTORUN_ENABLED="true" \
@@ -90,18 +89,12 @@ USER root
9089
RUN apk add --no-cache jq iperf3 iputils \
9190
&& rm -rf /var/cache/apk/*
9291

93-
# Install CLI tools in a single layer
92+
# Install CLI tools for amd64
9493
RUN set -e; \
95-
# Map TARGETARCH to architecture naming conventions \
96-
case "${TARGETARCH}" in \
97-
amd64) LIBRESPEED_ARCH="amd64"; OOKLA_ARCH="x86_64" ;; \
98-
arm64) LIBRESPEED_ARCH="arm64"; OOKLA_ARCH="aarch64" ;; \
99-
*) echo "Unsupported architecture: ${TARGETARCH}"; exit 1 ;; \
100-
esac; \
10194
curl -o /tmp/librespeed-cli.tgz -L \
102-
"https://github.com/librespeed/speedtest-cli/releases/download/v${LIBRESPEED_CLI_VERSION}/librespeed-cli_${LIBRESPEED_CLI_VERSION}_linux_${LIBRESPEED_ARCH}.tar.gz" \
95+
"https://github.com/librespeed/speedtest-cli/releases/download/v${LIBRESPEED_CLI_VERSION}/librespeed-cli_${LIBRESPEED_CLI_VERSION}_linux_amd64.tar.gz" \
10396
&& curl -o /tmp/speedtest-cli.tgz -L \
104-
"https://install.speedtest.net/app/cli/ookla-speedtest-${OOKLA_CLI_VERSION}-linux-${OOKLA_ARCH}.tgz" \
97+
"https://install.speedtest.net/app/cli/ookla-speedtest-${OOKLA_CLI_VERSION}-linux-x86_64.tgz" \
10598
&& tar xzf /tmp/librespeed-cli.tgz -C /usr/bin \
10699
&& tar xzf /tmp/speedtest-cli.tgz -C /usr/bin \
107100
&& rm /tmp/librespeed-cli.tgz /tmp/speedtest-cli.tgz

Dockerfile.arm64

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#############################
2+
# Download source code (platform-independent)
3+
#############################
4+
FROM --platform=$BUILDPLATFORM alpine:latest AS source
5+
6+
ARG RELEASE_TAG="latest"
7+
8+
WORKDIR /src
9+
10+
# Install wget and jq for downloading
11+
RUN apk add --no-cache wget jq
12+
13+
# Fetch the appropriate release
14+
RUN set -e; \
15+
if [ "${RELEASE_TAG}" = "current" ]; then \
16+
wget https://github.com/alexjustesen/speedtest-tracker/archive/refs/heads/main.tar.gz \
17+
&& tar -xzvf main.tar.gz --strip-components=1 \
18+
&& rm main.tar.gz; \
19+
elif [ "${RELEASE_TAG}" = "latest" ]; then \
20+
LATEST_RELEASE=$(wget -q -O - https://api.github.com/repos/alexjustesen/speedtest-tracker/releases/latest | jq -r .tag_name) \
21+
&& wget https://github.com/alexjustesen/speedtest-tracker/archive/refs/tags/${LATEST_RELEASE}.tar.gz \
22+
&& tar -xzvf ${LATEST_RELEASE}.tar.gz --strip-components=1 \
23+
&& rm ${LATEST_RELEASE}.tar.gz; \
24+
else \
25+
wget https://github.com/alexjustesen/speedtest-tracker/archive/refs/tags/${RELEASE_TAG}.tar.gz \
26+
&& tar -xzvf ${RELEASE_TAG}.tar.gz --strip-components=1 \
27+
&& rm ${RELEASE_TAG}.tar.gz; \
28+
fi
29+
30+
#############################
31+
# Install Composer dependencies (platform-independent)
32+
#############################
33+
FROM --platform=$BUILDPLATFORM serversideup/php:8.4-fpm-nginx-alpine-v4.2.1 AS dependencies
34+
35+
USER root
36+
37+
# Install the intl extension required by Composer dependencies
38+
RUN install-php-extensions intl \
39+
&& rm -rf /tmp/*
40+
41+
WORKDIR /app
42+
43+
COPY --from=source /src/composer.json /src/composer.lock /app/
44+
45+
RUN --mount=type=cache,target=/tmp/cache,uid=0,gid=0 \
46+
COMPOSER_CACHE_DIR=/tmp/cache COMPOSER_ALLOW_SUPERUSER=1 composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev --no-scripts
47+
48+
COPY --from=source /src /app
49+
50+
RUN --mount=type=cache,target=/tmp/cache,uid=0,gid=0 \
51+
COMPOSER_CACHE_DIR=/tmp/cache COMPOSER_ALLOW_SUPERUSER=1 composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev \
52+
&& chown -R www-data:www-data /app
53+
54+
USER www-data
55+
56+
#############################
57+
# Build assets (platform-independent)
58+
#############################
59+
FROM --platform=$BUILDPLATFORM node:24-alpine AS assets
60+
61+
WORKDIR /app
62+
63+
COPY --from=dependencies /app /app
64+
65+
RUN --mount=type=cache,target=/root/.npm \
66+
npm ci && npm run build
67+
68+
#############################
69+
# Base image (arm64-specific)
70+
#############################
71+
FROM --platform=linux/arm64 serversideup/php:8.4-fpm-nginx-alpine-v4.2.1 AS base
72+
73+
LABEL org.opencontainers.image.title="speedtest-tracker-docker" \
74+
org.opencontainers.image.authors="Alex Justesen (@alexjustesen)"
75+
76+
ARG LIBRESPEED_CLI_VERSION="1.0.12" \
77+
OOKLA_CLI_VERSION="1.2.0"
78+
79+
ENV AUTORUN_ENABLED="true" \
80+
AUTORUN_LARAVEL_MIGRATION="true" \
81+
AUTORUN_LARAVEL_MIGRATION_ISOLATION="true" \
82+
PHP_OPCACHE_ENABLE="1" \
83+
SHOW_WELCOME_MESSAGE="false"
84+
85+
# Switch to root so we can do root things
86+
USER root
87+
88+
# Install system dependencies and clean up in the same layer
89+
RUN apk add --no-cache jq iperf3 iputils \
90+
&& rm -rf /var/cache/apk/*
91+
92+
# Install CLI tools for arm64
93+
RUN set -e; \
94+
curl -o /tmp/librespeed-cli.tgz -L \
95+
"https://github.com/librespeed/speedtest-cli/releases/download/v${LIBRESPEED_CLI_VERSION}/librespeed-cli_${LIBRESPEED_CLI_VERSION}_linux_arm64.tar.gz" \
96+
&& curl -o /tmp/speedtest-cli.tgz -L \
97+
"https://install.speedtest.net/app/cli/ookla-speedtest-${OOKLA_CLI_VERSION}-linux-aarch64.tgz" \
98+
&& tar xzf /tmp/librespeed-cli.tgz -C /usr/bin \
99+
&& tar xzf /tmp/speedtest-cli.tgz -C /usr/bin \
100+
&& rm /tmp/librespeed-cli.tgz /tmp/speedtest-cli.tgz
101+
102+
# Install the intl extension with root permissions
103+
RUN install-php-extensions intl \
104+
&& rm -rf /tmp/*
105+
106+
# Copy s6 service definitions for Laravel scheduler and queue worker
107+
COPY --chmod=755 root /
108+
109+
# Drop back to our unprivileged user
110+
USER www-data
111+
112+
# Set working directory
113+
WORKDIR /var/www/html
114+
115+
# Copy source code and Composer dependencies from the dependencies stage
116+
COPY --chown=www-data:www-data --from=dependencies /app /var/www/html
117+
118+
#############################
119+
# Production image
120+
#############################
121+
FROM base AS production
122+
123+
COPY --chown=www-data:www-data --from=assets /app/public/build /var/www/html/public/build

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# 🐋 Speedtest Tracker Docker
22

3-
> [!INFO]
4-
> **Work in Progress** - This is a custom Docker image build based on [ServerSideUp's Docker PHP](https://serversideup.net/open-source/docker-php/).
3+
> [!WARNING]
4+
> These Docker images are under construction, use at your own risk..
55
6-
This build supports both `amd64` and `arm64`, 32-bit images are not supported.
6+
This image is based on [ServerSideUp's Docker PHP](https://serversideup.net/open-source/docker-php/) which is the gold standard for containerized PHP applications. These builds supports both `x86-64` and `arm64` architectures, 32-bit images are not and will not be supported.
77

88
### Using
99

0 commit comments

Comments
 (0)