From 28027edade6e3f8d22d786663a6726f473c48204 Mon Sep 17 00:00:00 2001 From: ZerNico Date: Wed, 5 Mar 2025 14:35:46 +0100 Subject: [PATCH] ci: add docker build workflow for app --- .github/workflows/docker-build-app.yml | 60 ++++++++++++++++++++++++++ .github/workflows/tauri-build-game.yml | 4 +- apps/api/Dockerfile | 1 + apps/app/Dockerfile | 33 ++++++++++++++ apps/app/docker/entrypoint.sh | 5 +++ apps/app/docker/nginx.conf | 12 ++++++ apps/app/index.html | 5 ++- apps/app/package.json | 1 + apps/app/vite.config.ts | 12 +++++- bun.lock | 11 +++-- 10 files changed, 137 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/docker-build-app.yml create mode 100644 apps/app/Dockerfile create mode 100644 apps/app/docker/entrypoint.sh create mode 100644 apps/app/docker/nginx.conf diff --git a/.github/workflows/docker-build-app.yml b/.github/workflows/docker-build-app.yml new file mode 100644 index 0000000..09f2153 --- /dev/null +++ b/.github/workflows/docker-build-app.yml @@ -0,0 +1,60 @@ +name: Build and Publish App Docker Image + +on: + push: + branches: + - main + - 'feature/**' + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository_owner }}/tuneperfect-app + +jobs: + build-and-push-app: + 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 the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + type=ref,event=branch,enable=${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }} + type=sha,format=short + type=sha,format=long + type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} + type=semver,pattern={{major}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} + type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: apps/app/Dockerfile + 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 + platforms: linux/amd64,linux/arm64 \ No newline at end of file diff --git a/.github/workflows/tauri-build-game.yml b/.github/workflows/tauri-build-game.yml index 4e8f35d..9b9e616 100644 --- a/.github/workflows/tauri-build-game.yml +++ b/.github/workflows/tauri-build-game.yml @@ -30,7 +30,7 @@ jobs: if: matrix.platform.os == 'ubuntu-22.04' run: | sudo apt-get update - sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libglib2.0-dev + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libglib2.0-dev alsa-base alsa-utils - name: Setup Bun uses: oven-sh/setup-bun@v2 @@ -46,7 +46,7 @@ jobs: uses: swatinem/rust-cache@v2 with: workspaces: './apps/game/src-tauri -> target' - key: ${{ matrix.platform.target }} + key: ${{ matrix.platform.target }}-${{ matrix.platform.os }}-game - name: Install dependencies run: bun install diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index 7e6df22..b7d6da9 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -9,6 +9,7 @@ COPY ./package.json ./bun.lock ./turbo.json ./ RUN bun install RUN bun run build --filter @tuneperfect/api + FROM oven/bun:1 AS runner WORKDIR /usr/src/app diff --git a/apps/app/Dockerfile b/apps/app/Dockerfile new file mode 100644 index 0000000..f85b1ab --- /dev/null +++ b/apps/app/Dockerfile @@ -0,0 +1,33 @@ +FROM oven/bun:1 AS builder + +WORKDIR /usr/src/app + +COPY ./apps/api ./apps/api +COPY ./apps/app ./apps/app +COPY ./packages/email ./packages/email +COPY ./package.json ./bun.lock ./turbo.json ./ + +RUN bun install +RUN bun run build --filter @tuneperfect/app + + +FROM nginx:alpine AS runner + +RUN apk add --no-cache curl bash +RUN curl -fsSL https://bun.sh/install | bash +ENV BUN_INSTALL="/root/.bun" +ENV PATH="$BUN_INSTALL/bin:$PATH" + +WORKDIR /app +RUN bun install @import-meta-env/cli +COPY ./apps/app/.env.example ./ +COPY ./apps/app/docker/entrypoint.sh ./entrypoint.sh +RUN chmod +x ./entrypoint.sh + +WORKDIR /usr/share/nginx/html +COPY --from=builder /usr/src/app/apps/app/dist ./ +COPY ./apps/app/docker/nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["/app/entrypoint.sh"] \ No newline at end of file diff --git a/apps/app/docker/entrypoint.sh b/apps/app/docker/entrypoint.sh new file mode 100644 index 0000000..83b4243 --- /dev/null +++ b/apps/app/docker/entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +bun --bun /app/node_modules/.bin/import-meta-env -x /app/.env.example -p /usr/share/nginx/html/index.html + +nginx -g "daemon off;" \ No newline at end of file diff --git a/apps/app/docker/nginx.conf b/apps/app/docker/nginx.conf new file mode 100644 index 0000000..eef7721 --- /dev/null +++ b/apps/app/docker/nginx.conf @@ -0,0 +1,12 @@ +server { + listen 80; + + server_name localhost; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri /index.html; + } +} \ No newline at end of file diff --git a/apps/app/index.html b/apps/app/index.html index 45b0ccc..ee41783 100644 --- a/apps/app/index.html +++ b/apps/app/index.html @@ -1,4 +1,4 @@ - + @@ -6,6 +6,9 @@ Tune Perfect + diff --git a/apps/app/package.json b/apps/app/package.json index 3199867..5fa745c 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -12,6 +12,7 @@ "@iconify-json/circle-flags": "^1.2.6", "@iconify-json/logos": "^1.2.4", "@iconify-json/lucide": "^1.2.24", + "@import-meta-env/unplugin": "^0.6.2", "@tailwindcss/vite": "^4.0.0", "@tuneperfect/api": "*", "tailwindcss": "^4.0.0", diff --git a/apps/app/vite.config.ts b/apps/app/vite.config.ts index 5fdcf45..f55e844 100644 --- a/apps/app/vite.config.ts +++ b/apps/app/vite.config.ts @@ -1,3 +1,4 @@ +import importMetaEnv from "@import-meta-env/unplugin"; import tailwindcss from "@tailwindcss/vite"; import icons from "unplugin-icons/vite"; import { defineConfig } from "vite"; @@ -5,7 +6,16 @@ import pages from "vite-plugin-pages"; import solid from "vite-plugin-solid"; export default defineConfig({ - plugins: [solid(), tailwindcss(), pages(), icons({ compiler: "solid" })], + plugins: [ + importMetaEnv.vite({ + example: ".env.example", + env: ".env", + }), + solid(), + tailwindcss(), + pages(), + icons({ compiler: "solid" }), + ], server: { port: 3001, }, diff --git a/bun.lock b/bun.lock index ab218f0..f9abf23 100644 --- a/bun.lock +++ b/bun.lock @@ -53,6 +53,7 @@ "@iconify-json/circle-flags": "^1.2.6", "@iconify-json/logos": "^1.2.4", "@iconify-json/lucide": "^1.2.24", + "@import-meta-env/unplugin": "^0.6.2", "@tailwindcss/vite": "^4.0.0", "@tuneperfect/api": "*", "tailwindcss": "^4.0.0", @@ -64,7 +65,7 @@ }, }, "apps/game": { - "name": "game", + "name": "@tuneperfect/game", "dependencies": { "@fontsource/lato": "^5.1.1", "@nokijs/client": "^0.0.1-alpha.36", @@ -378,6 +379,8 @@ "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="], + "@import-meta-env/unplugin": ["@import-meta-env/unplugin@0.6.2", "", { "dependencies": { "dotenv": "^16.0.0", "magic-string": "^0.30.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", "unplugin": "^2.0.0" }, "peerDependencies": { "@import-meta-env/cli": "^0.7.0" }, "optionalPeers": ["@import-meta-env/cli"] }, "sha512-m8TEQTgWekSkhlT9lkHBKQ4TDf5l8+BWvO6q/cxcsv1AvyfsOXUOHbvjhKSiVDaz/CDDCbOWc/aOAiPFRzcXGA=="], + "@internationalized/date": ["@internationalized/date@3.7.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ=="], "@internationalized/number": ["@internationalized/number@3.6.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw=="], @@ -764,6 +767,8 @@ "@tuneperfect/email": ["@tuneperfect/email@workspace:packages/email"], + "@tuneperfect/game": ["@tuneperfect/game@workspace:apps/game"], + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], "@types/babel__generator": ["@types/babel__generator@7.6.8", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw=="], @@ -1288,8 +1293,6 @@ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], - "game": ["game@workspace:apps/game"], - "gel": ["gel@2.0.1", "", { "dependencies": { "@petamoriken/float16": "^3.8.7", "debug": "^4.3.4", "env-paths": "^3.0.0", "semver": "^7.6.2", "shell-quote": "^1.8.1", "which": "^4.0.0" }, "bin": { "gel": "dist/cli.mjs" } }, "sha512-gfem3IGvqKqXwEq7XseBogyaRwGsQGuE7Cw/yQsjLGdgiyqX92G1xENPCE0ltunPGcsJIa6XBOTx/PK169mOqw=="], "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], @@ -1636,6 +1639,8 @@ "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], "obuf": ["obuf@1.1.2", "", {}, "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="],