From a2465057edf17426c30d650b74bed2ca90e2a452 Mon Sep 17 00:00:00 2001 From: Ryan Welch Date: Fri, 26 Sep 2025 15:31:54 +0000 Subject: [PATCH 1/3] Docker --- .github/workflows/docker-build.yml | 50 ++++++++++++++++++++++++++++++ Dockerfile | 50 ++++++++++++++++++++++++++++++ bin/docker-build.sh | 15 +++++++++ 3 files changed, 115 insertions(+) create mode 100644 .github/workflows/docker-build.yml create mode 100644 Dockerfile create mode 100755 bin/docker-build.sh diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..bb127ea --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,50 @@ +name: Build and Push Docker Images + +on: [push] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=sha,format=long + type=semver,pattern={{version}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..549e06d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,50 @@ +# Stage 1: build node assets +FROM node:22 AS node-build +WORKDIR /app + +# Install packages first; need to install here to be cached in earlier layer +# and not trigger re-compiles if only source code changes +COPY package.json package-lock.json /app +RUN npm ci + +# Copy the source code into the container +COPY \ + .browserslistrc \ + .nvmrc \ + .editorconfig \ + jsconfig.json \ + vite.config.mjs \ + index.html \ + /app/ + +COPY public /app/public +COPY src /app/src + +# Run build +ENV NODE_ENV=production +RUN npm run build + +# Stage 2: nginx +# This copies built assets from previous stage +# nginxinc/nginx-unprivileged is a docker image that allows running nginx w/o root +FROM nginxinc/nginx-unprivileged:mainline-bookworm +COPY --from=node-build /app/dist /usr/share/nginx/html/ + +LABEL org.label-schema.name="colocus-ui" +LABEL org.label-schema.description="Vue frontend for Colocus browser" +LABEL org.label-schema.vendor="University of Michigan, Center for Statistical Genetics" +LABEL org.label-schema.url="https://github.com/statgen/colocus-ui-vue3" +LABEL org.label-schema.usage="https://github.com/statgen/colocus-ui-vue3#docker" +LABEL org.label-schema.vcs-url="https://github.com/statgen/colocus-ui-vue3" +LABEL org.label-schema.schema-version="1.0" + +ARG BUILD_DATE +ARG GIT_SHA +ARG COLOCUS_UI_VERSION + +LABEL org.label-schema.version=$COLOCUS_UI_VERSION \ + org.label-schema.vcs-ref=$GIT_SHA \ + org.label-schema.build-date=$BUILD_DATE + +# Start NGINX in the foreground +CMD ["nginx", "-g", "daemon off;"] diff --git a/bin/docker-build.sh b/bin/docker-build.sh new file mode 100755 index 0000000..70fe782 --- /dev/null +++ b/bin/docker-build.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -euxo pipefail + +COLOCUS_UI_VERSION=`git describe --tags --abbrev=11 | sed 's/^v//' | sed 's/-g/-/'` +GIT_SHA=`git rev-parse HEAD` +BUILD_DATE=`date -u +'%Y-%m-%dT%H:%M:%SZ'` + +docker build --pull -t colocus-ui:${COLOCUS_UI_VERSION} \ + --build-arg BUILD_DATE=${BUILD_DATE} \ + --build-arg GIT_SHA=${GIT_SHA} \ + --build-arg COLOCUS_UI_VERSION=${COLOCUS_UI_VERSION} \ + --progress plain \ + "$@" . + +docker tag colocus-ui:${COLOCUS_UI_VERSION} colocus-ui:latest From 45863f6640872153e95c5bef6400279c337681ab Mon Sep 17 00:00:00 2001 From: Ryan Welch Date: Fri, 24 Oct 2025 20:14:05 +0000 Subject: [PATCH 2/3] Fix permissions; add dev docker image The `Dockerfile.dev` runs the vite dev server instead --- Dockerfile | 2 ++ Dockerfile.dev | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 Dockerfile.dev diff --git a/Dockerfile b/Dockerfile index 549e06d..676490f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,8 @@ COPY src /app/src # Run build ENV NODE_ENV=production RUN npm run build +RUN find /app/dist -type f -print0 | xargs -0 chmod 644 +RUN find /app/dist -type d -print0 | xargs -0 chmod 755 # Stage 2: nginx # This copies built assets from previous stage diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..c795d47 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,38 @@ +FROM node:22 AS node-build +WORKDIR /app + +# Install packages first; need to install here to be cached in earlier layer +# and not trigger re-compiles if only source code changes +COPY package.json package-lock.json /app/ +RUN npm ci + +# Copy the source code into the container +COPY \ + .browserslistrc \ + .nvmrc \ + .editorconfig \ + jsconfig.json \ + vite.config.mjs \ + index.html \ + /app/ + +COPY public /app/public +COPY src /app/src + +LABEL org.label-schema.name="colocus-ui" +LABEL org.label-schema.description="Development image for Colocus UI" +LABEL org.label-schema.vendor="University of Michigan, Center for Statistical Genetics" +LABEL org.label-schema.url="https://github.com/statgen/colocus-ui-vue3" +LABEL org.label-schema.usage="https://github.com/statgen/colocus-ui-vue3#docker" +LABEL org.label-schema.vcs-url="https://github.com/statgen/colocus-ui-vue3" +LABEL org.label-schema.schema-version="1.0" + +ARG BUILD_DATE +ARG GIT_SHA +ARG COLOCUS_UI_VERSION + +LABEL org.label-schema.version=$COLOCUS_UI_VERSION \ + org.label-schema.vcs-ref=$GIT_SHA \ + org.label-schema.build-date=$BUILD_DATE + +CMD ["sh", "-c", "node --no-warnings ./node_modules/.bin/vite --host 0.0.0.0 --port ${VITE_PORT:-5173} --strictPort"] From d9e3e39afb47142341ac1a1e3bdff21b005ca498 Mon Sep 17 00:00:00 2001 From: Ryan Welch Date: Fri, 24 Oct 2025 20:14:33 +0000 Subject: [PATCH 3/3] Fix vite config for proxying API to django container --- vite.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vite.config.mjs b/vite.config.mjs index 86e2dab..1f2de27 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -107,7 +107,7 @@ export default defineConfig({ server: { proxy: { '/api/': { - target: 'http://127.0.0.1:8000', + target: process.env.VITE_API_URL || 'http://127.0.0.1:8000', changeOrigin: true, }, },