diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..0570e87e8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,83 @@ +name: ๐Ÿณ Create and publish a Docker image + +on: + push: + branches: + - main + - dev + +permissions: + actions: write + contents: read + packages: write + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + name: ๐Ÿณ Build + if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' }} + runs-on: ubuntu-latest + steps: + - name: ๐Ÿ›‘ Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.12.1 + + - name: โฌ‡๏ธ Checkout repo + uses: actions/checkout@v4.1.1 + + - name: ๐Ÿฅก Set up QEMU + uses: docker/setup-qemu-action@v3.0.0 + + - name: โœ–๏ธ Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 + + - name: โšก๏ธ Cache Docker layers + uses: actions/cache@v4.0.0 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: ๐Ÿ‘‹ Log in to the Container registry + uses: docker/login-action@v3.0.0 + 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.5.1 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} + type=ref,enable=${{ github.ref_type != 'tag' }},suffix=-{{sha}},event=branch + type=ref,event=tag + + - name: ๐Ÿ›  Build and push Docker image + uses: docker/build-push-action@v5.1.0 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + # Note: provenance fixes unknown/unknown platform to be generated on build + # https://github.com/orgs/community/discussions/45969#discussioncomment-8170787 + # https://github.com/docker/build-push-action/issues/820#issuecomment-1445131521 + provenance: false + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} + REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} + COMMIT_SHA=${{ github.sha }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,mode=max,dest=/tmp/.buildx-cache-new + + - name: ๐Ÿšš Move cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c9647a73d..26a60d689 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,11 @@ name: ๐Ÿš€ Deploy + on: push: branches: - main - dev + permissions: actions: write contents: read @@ -22,7 +24,7 @@ jobs: build: name: ๐Ÿณ Build # only build/deploy main branch on pushes - if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'}} + if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' }} runs-on: ubuntu-latest steps: - name: ๐Ÿ›‘ Cancel Previous Runs diff --git a/.github/workflows/ghcr_cleanup.yml b/.github/workflows/ghcr_cleanup.yml new file mode 100644 index 000000000..4a6c44409 --- /dev/null +++ b/.github/workflows/ghcr_cleanup.yml @@ -0,0 +1,39 @@ +# https://github.com/Koenkk/zigbee2mqtt/blob/fe0742a628fb782692f9679367e2ab1b11139dd6/.github/workflows/ghcr_cleanup.yml + +name: ๐Ÿงน ghcr.io Cleanup + +on: + workflow_dispatch: + +permissions: + actions: write + contents: read + packages: write + +env: + PACKAGE_NAME: shelf.nu + PER_PAGE: 2000 + +jobs: + clean: + runs-on: ubuntu-latest + + steps: + - name: ๐Ÿ—‘ Delete untagged images + uses: actions/github-script@v7.0.1 + with: + script: | + const response = await github.request("GET /user/packages/container/${{ env.PACKAGE_NAME }}/versions", + { per_page: ${{ env.PER_PAGE }} + }); + for(version of response.data) { + if (version.metadata.container.tags.length == 0) { + try { + console.log("delete " + version.id) + const deleteResponse = await github.request("DELETE /user/packages/container/${{ env.PACKAGE_NAME }}/versions/" + version.id, { }); + console.log("status " + deleteResponse.status) + } catch (e) { + console.log("failed") + } + } + } diff --git a/Dockerfile b/Dockerfile index 90700a2c6..259d515c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,5 +52,6 @@ COPY --from=build /myapp/build /myapp/build COPY --from=build /myapp/public /myapp/public COPY --from=build /myapp/package.json /myapp/package.json COPY --from=build /myapp/start.sh /myapp/start.sh +RUN chmod +x /myapp/start.sh -ENTRYPOINT [ "./start.sh" ] \ No newline at end of file +ENTRYPOINT [ "./start.sh" ] diff --git a/docs/README.md b/docs/README.md index fbe34c835..6a426be90 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,4 +8,5 @@ Here you can find the documentation for shelf. with Shelf. - [Shelf Config file](../shelf-config.md) - Shelf configuration file - [Asset Search](./asset-search.md) - Asset search via Prisma Full text search +- [Docker](./docker.md) - Run shelf via docker - [Contributing](../CONTRIBUTING.md) - Contributing to Shelf. diff --git a/docs/docker.md b/docs/docker.md new file mode 100644 index 000000000..630a3b52d --- /dev/null +++ b/docs/docker.md @@ -0,0 +1,47 @@ +# Docker + +If you prefer using docker for running shelf locally or self hosting your live app, we have a Docker image ready for you thanks to [@anatolinicolae](https://github.com/anatolinicolae) + +## Instructions + +1. Make sure you have docker installed on your machine +2. Use the docker run command and replace your env varibales: + +```sh +docker run -d \ + --name "shelf" \ + -e "DATABASE_URL=postgres://{USER}:{PASSWORD}@{HOST}:6543/{DB_NAME}?pgbouncer=true" \ + -e "DIRECT_URL=postgres://{USER}:{PASSWORD}@{HOST}:5432/{DB_NAME}" \ + -e 'SUPABASE_ANON_PUBLIC=ANON_PUBLIC' \ + -e 'SUPABASE_SERVICE_ROLE=SERVICE_ROLE' \ + -e 'SUPABASE_URL=https://{YOUR_INSTANCE_NAME}.supabase.co' \ + -e 'SESSION_SECRET=super-duper-s3cret' \ + -e 'SERVER_URL=http://localhost:3000' \ + -e 'MAPTILER_TOKEN=maptiler-token' \ + -e 'SMTP_HOST=mail.example.com' \ + -e 'SMTP_USER=some-email@example.com' \ + -e 'SMTP_PWD=super-safe-passw0rd' \ + -p 3000:8080 \ + --restart unless-stopped \ + ghcr.io/Shelf-nu/shelf.nu:latest +``` + +### ARM processors + +You can also run shelf on ARM64 processors. + +1. Linux / Pine A64 + +```shell +root@DietPi:~# +docker run -it --rm --entrypoint /usr/bin/uname ghcr.io/thundersquared/shelf:latest -a +Linux 77ae434f8fe9 6.1.63-current-sunxi64 #1 SMP Mon Nov 20 10:52:19 UTC 2023 aarch64 GNU/Linux +``` + +2. MacOS / M1 Max + +```shell +โฏ ~ +docker run -it --rm --platform linux/arm64 --entrypoint /usr/bin/uname ghcr.io/thundersquared/shelf:latest -a +Linux 7a9dff819847 6.5.13-orbstack-00122-g57b8027e2387 #1 SMP Tue Feb 6 07:48:26 UTC 2024 aarch64 GNU/Linux +``` diff --git a/docs/get-started.md b/docs/get-started.md index 73f22c235..c9a64b7dd 100644 --- a/docs/get-started.md +++ b/docs/get-started.md @@ -19,6 +19,12 @@ Shelf's basic setup is based on a Remix stack by [rphlmr](https://github.com/rph - Linting with [ESLint](https://eslint.org) - Static Types with [TypeScript](https://typescriptlang.org) +## Docker + +If you prefer to run shelf locally or host your live app via docker, please check our [Docker](./docker.md) documentation. + +_**Note**: Currently we dont have a docker setup that also includes self hositng supabase. Once released the docker documentation will be updated to include it as well._ + ## Development - Create a [Supabase Database](https://supabase.com/) (free tier gives you 2 databases) diff --git a/start.sh b/start.sh index 760710193..ba509a8de 100644 --- a/start.sh +++ b/start.sh @@ -1,7 +1,8 @@ +#!/bin/sh -ex + # This file is how Fly starts the server (configured in fly.toml). Before starting # the server though, we need to run any prisma migrations that haven't yet been # run, which is why this file exists in the first place. # Learn more: https://community.fly.io/t/sqlite-not-getting-setup-properly/4386 -set -ex npm run start