Skip to content

Commit cde2fcc

Browse files
[#47] Add support for Dockerfiles + publishing.
- Added template Dockerfile and entrypoint.sh - Added test-docker.yml workflow (build + hadolint lint) - Added release-docker.yml workflow (multi-arch push to Docker Hub) - Added 'Use Docker' prompt to init.sh (defaults to No) - Added Docker image name prompt (defaults to namespace/project) - Added remove_docker() function for cleanup when Docker not selected - Added DOCKER token blocks to CLAUDE.md - Added 'docker' test case to InitTest.php - Updated test fixtures via snapshot auto-update - All 14 init tests passing
1 parent 38ab154 commit cde2fcc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+676
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Release Docker
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
push-release-to-registry:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v6
18+
19+
- name: Set up QEMU
20+
uses: docker/setup-qemu-action@v3
21+
22+
- name: Set up Docker Buildx
23+
uses: docker/setup-buildx-action@v3
24+
25+
- name: Log in to Docker Hub
26+
uses: docker/login-action@v3
27+
with:
28+
username: ${{ secrets.DOCKER_USER }}
29+
password: ${{ secrets.DOCKER_PASS }}
30+
31+
- name: Extract metadata (tags, labels) for Docker
32+
id: meta
33+
uses: docker/metadata-action@v5
34+
with:
35+
images: yournamespace/yourproject
36+
37+
- name: Build and push Docker image
38+
uses: docker/build-push-action@v6
39+
with:
40+
context: .
41+
push: true
42+
tags: ${{ steps.meta.outputs.tags }}
43+
labels: ${{ steps.meta.outputs.labels }}
44+
platforms: linux/x86_64,linux/arm64

.github/workflows/test-docker.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Test Docker
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
- 'feature/**'
11+
workflow_dispatch:
12+
inputs:
13+
enable_terminal:
14+
type: boolean
15+
description: 'Enable terminal session.'
16+
required: false
17+
default: false
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
test-docker:
24+
name: Docker
25+
runs-on: ubuntu-latest
26+
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v6
30+
31+
- name: Lint Dockerfile
32+
uses: hadolint/hadolint-action@v3.1.0
33+
with:
34+
dockerfile: Dockerfile
35+
continue-on-error: ${{ vars.CI_LINT_IGNORE_FAILURE == '1' }}
36+
37+
- name: Set up Docker Buildx
38+
uses: docker/setup-buildx-action@v3
39+
40+
- name: Build Docker image
41+
uses: docker/build-push-action@v6
42+
with:
43+
context: .
44+
push: false
45+
load: true
46+
tags: yournamespace/yourproject:test
47+
cache-from: type=gha
48+
cache-to: type=gha,mode=max
49+
50+
- name: Test Docker image
51+
run: docker run --rm yournamespace/yourproject:test
52+
53+
- name: Setup tmate session
54+
if: ${{ !cancelled() && github.event.inputs.enable_terminal }}
55+
uses: mxschmitt/action-tmate@v3
56+
timeout-minutes: 30
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: Docker
3+
sidebar_position: 6
4+
---
5+
6+
# Docker
7+
8+
This scaffold provides optional Docker support for building and publishing
9+
container images. When enabled during initialization, it includes a Dockerfile,
10+
an entrypoint script, and GitHub Actions workflows for testing and releasing
11+
Docker images.
12+
13+
## Dockerfile
14+
15+
The included `Dockerfile` uses a minimal Alpine Linux base image with Bash
16+
installed. It follows OCI image labeling conventions and uses a dedicated
17+
entrypoint script.
18+
19+
```dockerfile
20+
FROM alpine:3
21+
22+
RUN apk add --no-cache bash
23+
24+
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
25+
26+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
27+
```
28+
29+
## Entrypoint
30+
31+
The `entrypoint.sh` script enforces strict shell options (`set -euo pipefail`)
32+
and forwards arguments to the container command.
33+
34+
## Building and running
35+
36+
```bash
37+
# Build the image
38+
docker build -t yournamespace/yourproject .
39+
40+
# Run the container
41+
docker run --rm yournamespace/yourproject
42+
```
43+
44+
## Linting
45+
46+
The Dockerfile is linted using [Hadolint](https://github.com/hadolint/hadolint),
47+
a Dockerfile linter that helps enforce best practices.
48+
49+
```bash
50+
# Lint locally
51+
hadolint Dockerfile
52+
```
53+
54+
Linting also runs automatically in CI via the `test-docker.yml` workflow.
55+
56+
## CI/CD workflows
57+
58+
### Testing (`test-docker.yml`)
59+
60+
Runs on pushes to `main` and pull requests. This workflow:
61+
62+
1. Lints the Dockerfile with Hadolint
63+
2. Builds the Docker image using Docker Buildx
64+
3. Runs the container to verify it starts correctly
65+
66+
### Release (`release-docker.yml`)
67+
68+
Runs on tag pushes. This workflow:
69+
70+
1. Sets up QEMU and Docker Buildx for multi-architecture builds
71+
2. Authenticates with Docker Hub
72+
3. Builds and pushes multi-arch images (`linux/x86_64`, `linux/arm64`)
73+
74+
#### Docker Hub credentials
75+
76+
The release workflow requires the following repository secrets:
77+
78+
- `DOCKER_USER` — Docker Hub username
79+
- `DOCKER_PASS` — Docker Hub access token
80+
81+
Set these in your repository's **Settings > Secrets and variables > Actions**.

.scaffold/docs/cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"GHSA",
1212
"Terminalizer",
1313
"autoloader",
14+
"Buildx",
1415
"calver",
1516
"cobertura",
1617
"daemonized",

.scaffold/tests/phpunit/fixtures/init/_baseline/docs/cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"Cobertura",
1111
"Terminalizer",
1212
"autoloader",
13+
"Buildx",
1314
"calver",
1415
"cobertura",
1516
"daemonized",

.scaffold/tests/phpunit/fixtures/init/nodejs/-composer.lock renamed to .scaffold/tests/phpunit/fixtures/init/docker/-box.json

File renamed without changes.

.scaffold/tests/phpunit/fixtures/init/nodejs/.github/-FUNDING.yml renamed to .scaffold/tests/phpunit/fixtures/init/docker/-composer.json

File renamed without changes.

.scaffold/tests/phpunit/fixtures/init/php_command/.github/-release-drafter.yml renamed to .scaffold/tests/phpunit/fixtures/init/docker/-force-crystal

File renamed without changes.

.scaffold/tests/phpunit/fixtures/init/php_command/.github/workflows/-draft-release-notes.yml renamed to .scaffold/tests/phpunit/fixtures/init/docker/-force-crystal.sh

File renamed without changes.

.scaffold/tests/phpunit/fixtures/init/php_script/.github/-release-drafter.yml renamed to .scaffold/tests/phpunit/fixtures/init/docker/-package.json

File renamed without changes.

0 commit comments

Comments
 (0)