Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
# Dockerfiles
Dockerfile text eol=lf
*.dockerfile text eol=lf

# Front-end image files are copied verbatim into a Linux image and served from it
clients/*/docker/** text eol=lf
50 changes: 49 additions & 1 deletion .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,58 @@ jobs:
path: clients/${{ matrix.app }}/playwright-report
retention-days: 7

# The nginx image renders /config.json at every start. Restarting the same container
# has to bring it back: the entrypoint once deleted its own template after the first
# render, so any restart crash-looped, and nothing else here builds or runs the image.
container:
name: Container (${{ matrix.app }})
needs: changes
if: needs.changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
app: [admin, dashboard]
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Build image
run: docker build -t fsh-${{ matrix.app }}:ci clients/${{ matrix.app }}

- name: Smoke test start and restart
env:
IMAGE: fsh-${{ matrix.app }}:ci
run: |
set -euo pipefail
docker run -d --name smoke -p 8080:80 \
-e FSH_API_URL=http://api.example.test -e FSH_DEFAULT_TENANT=acme \
-e FSH_DASHBOARD_URL=http://app.example.test "$IMAGE"
check() {
rm -f config.json
for _ in $(seq 1 20); do
curl -fsS http://localhost:8080/config.json -o config.json && break
sleep 1
done
[ "$(docker inspect -f '{{.State.Running}} {{.RestartCount}}' smoke)" = "true 0" ]
jq -e '.apiBase == "http://api.example.test" and .defaultTenant == "acme"' config.json
}
check
if curl -fsS http://localhost:8080/config.json.template | grep -qF '${FSH_API_URL}'; then
echo "::error::config.json.template is served from the web root"
exit 1
fi
docker restart smoke
check

- name: Container logs
if: failure()
run: docker logs smoke

# Single required status check — see backend.yml for the rationale.
frontend-ci:
name: Frontend CI
needs: [changes, lint-build, e2e]
needs: [changes, lint-build, e2e, container]
if: always()
runs-on: ubuntu-latest
steps:
Expand Down
5 changes: 3 additions & 2 deletions clients/admin/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ RUN apk add --no-cache gettext
RUN rm -rf ./* /etc/nginx/conf.d/default.conf
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf

# Copy the built bundle, the runtime config template, and the entrypoint
# Copy the built bundle, the runtime config template (outside the web root so
# it is never served), and the entrypoint
COPY --from=build /app/dist/ ./
COPY docker/config.json.template ./config.json.template
COPY docker/config.json.template /etc/fsh/config.json.template
COPY docker/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

Expand Down
8 changes: 3 additions & 5 deletions clients/admin/docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ set -e

export FSH_API_URL FSH_DASHBOARD_URL FSH_DEFAULT_TENANT

# Render the runtime config from the template, writing into nginx's web root.
envsubst < /usr/share/nginx/html/config.json.template > /usr/share/nginx/html/config.json

# Drop the template so it isn't served accidentally.
rm /usr/share/nginx/html/config.json.template
# Render the runtime config into nginx's web root on every start. The template
# lives outside the web root, so it is never served and survives a restart.
envsubst < /etc/fsh/config.json.template > /usr/share/nginx/html/config.json

exec nginx -g 'daemon off;'
2 changes: 1 addition & 1 deletion clients/dashboard/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ RUN apk add --no-cache gettext
RUN rm -rf ./* /etc/nginx/conf.d/default.conf
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/ ./
COPY docker/config.json.template ./config.json.template
COPY docker/config.json.template /etc/fsh/config.json.template
COPY docker/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
EXPOSE 80
Expand Down
3 changes: 1 addition & 2 deletions clients/dashboard/docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ set -e

export FSH_API_URL FSH_DEFAULT_TENANT

envsubst < /usr/share/nginx/html/config.json.template \
envsubst < /etc/fsh/config.json.template \
> /usr/share/nginx/html/config.json
rm /usr/share/nginx/html/config.json.template

exec nginx -g 'daemon off;'
Loading