-
Notifications
You must be signed in to change notification settings - Fork 3
Add Docker image build and publish pipeline #108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7d5059e
b827861
46317b2
3ec22c2
7fbe7ce
71915d9
a81f148
eff30fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| node_modules | ||
| .nuxt | ||
| .output | ||
| .git | ||
| .env | ||
| .env.* | ||
| !.env.example | ||
| *.log | ||
| .DS_Store | ||
| tests | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,52 @@ | ||||||||||||||||||||||||||||||||||||||||||
| name: Build and Publish Docker Image | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||
| push: | ||||||||||||||||||||||||||||||||||||||||||
| branches: | ||||||||||||||||||||||||||||||||||||||||||
| - dev | ||||||||||||||||||||||||||||||||||||||||||
| release: | ||||||||||||||||||||||||||||||||||||||||||
| types: [published] | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||
| build: | ||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||
| packages: write | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout code | ||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Set up Docker Buildx | ||||||||||||||||||||||||||||||||||||||||||
| uses: docker/setup-buildx-action@v3 | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Log in to GitHub Container Registry | ||||||||||||||||||||||||||||||||||||||||||
| uses: docker/login-action@v3 | ||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current workflow duplicates build logic and lacks layer caching. Consolidating into a single build step using
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
| registry: ghcr.io | ||||||||||||||||||||||||||||||||||||||||||
| username: ${{ github.actor }} | ||||||||||||||||||||||||||||||||||||||||||
| password: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Resolve short commit SHA | ||||||||||||||||||||||||||||||||||||||||||
| id: meta | ||||||||||||||||||||||||||||||||||||||||||
| if: ${{ github.event_name == 'push' }} | ||||||||||||||||||||||||||||||||||||||||||
| run: echo "sha=${GITHUB_SHA:0:7}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Build and push commit image | ||||||||||||||||||||||||||||||||||||||||||
| if: ${{ github.event_name == 'push' }} | ||||||||||||||||||||||||||||||||||||||||||
| uses: docker/build-push-action@v6 | ||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||
| context: . | ||||||||||||||||||||||||||||||||||||||||||
| push: true | ||||||||||||||||||||||||||||||||||||||||||
| tags: ghcr.io/trakli/webui:${{ steps.meta.outputs.sha }} | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Build and push latest | ||||||||||||||||||||||||||||||||||||||||||
| if: ${{ github.event_name == 'release' }} | ||||||||||||||||||||||||||||||||||||||||||
| uses: docker/build-push-action@v6 | ||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||
| context: . | ||||||||||||||||||||||||||||||||||||||||||
| push: true | ||||||||||||||||||||||||||||||||||||||||||
| tags: | | ||||||||||||||||||||||||||||||||||||||||||
| ghcr.io/trakli/webui:latest | ||||||||||||||||||||||||||||||||||||||||||
| ghcr.io/trakli/webui:${{ github.event.release.tag_name }} | ||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # Trakli web UI — multi-stage build for production | ||
| # | ||
| # Nuxt 3 bakes runtimeConfig.public values into the .output/ at build time. | ||
| # We build with a placeholder and replace it at container start via entrypoint, | ||
| # so a single image works across deployments with different API URLs. | ||
|
|
||
| # ── Stage 1: Build ────────────────────────────────────────────────────────── | ||
| FROM node:lts AS builder | ||
|
|
||
|
|
||
| WORKDIR /app | ||
|
|
||
| COPY package*.json ./ | ||
| RUN npm ci | ||
|
|
||
| COPY . . | ||
|
|
||
| # Placeholder — replaced at runtime by docker/entrypoint.sh | ||
| ENV NUXT_PUBLIC_API_BASE_URL=http://__NUXT_PUBLIC_API_BASE_URL__ | ||
| RUN npm run build | ||
|
|
||
| # ── Stage 2: Runtime ──────────────────────────────────────────────────────── | ||
| FROM node:lts-alpine | ||
|
|
||
|
|
||
| LABEL org.opencontainers.image.source=https://github.com/trakli/webui | ||
| LABEL org.opencontainers.image.description="Trakli web dashboard" | ||
| LABEL org.opencontainers.image.vendor="WhileSmart LLC" | ||
| LABEL org.opencontainers.image.licenses=MIT | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| COPY --from=builder /app/.output .output | ||
| COPY --from=builder /app/docker/entrypoint.sh /entrypoint.sh | ||
| RUN chmod +x /entrypoint.sh | ||
|
|
||
| EXPOSE 3000 | ||
|
|
||
| HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \ | ||
| CMD wget -qO- http://localhost:3000/ || exit 1 | ||
|
Comment on lines
+37
to
+38
|
||
|
|
||
| ENTRYPOINT ["/entrypoint.sh"] | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||||||||
| #!/bin/sh | ||||||||||||||||
| set -e | ||||||||||||||||
|
|
||||||||||||||||
| # Replace the build-time placeholder with the actual runtime value. | ||||||||||||||||
| # This is how a single Docker image serves deployments with different API URLs | ||||||||||||||||
| # without rebuilding — Nuxt 3 bakes runtimeConfig.public into .output/ at | ||||||||||||||||
| # build time, so we patch the built files before starting the server. | ||||||||||||||||
| if [ -n "$NUXT_PUBLIC_API_BASE_URL" ]; then | ||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||||
| find /app/.output -type f \( -name '*.mjs' -o -name '*.js' -o -name '*.cjs' \) \ | ||||||||||||||||
| -exec sed -i "s|http://__NUXT_PUBLIC_API_BASE_URL__|${NUXT_PUBLIC_API_BASE_URL}|g" {} + | ||||||||||||||||
| fi | ||||||||||||||||
|
Comment on lines
+8
to
+11
|
||||||||||||||||
|
|
||||||||||||||||
| exec node .output/server/index.mjs | ||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excluding the
Dockerfileand the.githubdirectory from the build context is a best practice. It prevents meta-files from being included in layers and avoids unnecessary cache invalidation if only repository metadata changes.