From e88c5f3fd063cebcbb638a04d8a95002de7df8b2 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Sat, 6 Apr 2024 20:13:09 -1000 Subject: [PATCH] Finally make the Docker build work --- .github/workflows/docker-publish.yml | 166 ++++++++++++------- Dockerfile | 40 ++--- bun.lockb | Bin 330080 -> 330080 bytes docker-compose.yml | 13 +- package.json | 230 +++++++++++++-------------- 5 files changed, 251 insertions(+), 198 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 21377659..ca63a0a8 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -1,96 +1,152 @@ -name: Build and publish Docker image - -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +name: Docker on: - schedule: - - cron: "22 5 * * *" push: branches: ["main"] - # Publish semver tags as releases. tags: ["v*.*.*"] pull_request: - branches: ["main"] + branches: ["*"] + workflow_dispatch: + inputs: + tag: + description: "Tag" + required: false + default: "v0.0.0" env: - # Use docker.io for Docker Hub if empty REGISTRY: ghcr.io - # github.repository as / - IMAGE_NAME: ${{ github.repository }} jobs: build: - runs-on: ubuntu-latest + name: Build for ${{ matrix.platform }} + runs-on: ${{ matrix.os }} + environment: + name: Production + strategy: + fail-fast: false + matrix: + include: + - os: [self-hosted] + platform: linux/arm64 + - os: ubuntu-latest + platform: linux/amd64 permissions: contents: read packages: write - # This is used to complete the identity challenge - # with sigstore/fulcio when running outside of PRs. id-token: write steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}" >> $GITHUB_ENV + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - # Install the cosign tool except on PR - # https://github.com/sigstore/cosign-installer - - name: Install cosign - if: github.event_name != 'pull_request' - uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 - with: - cosign-release: "v2.1.1" + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 - # Set up BuildKit Docker container builder to be able to build - # multi-platform images and export cache - # https://github.com/docker/setup-buildx-action - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 - # Login against a Docker registry except on PR - # https://github.com/docker/login-action - name: Log into registry ${{ env.REGISTRY }} if: github.event_name != 'pull_request' - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # Extract metadata (tags, labels) for Docker - # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta - uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 + uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - # Build and push Docker image with Buildx (don't push on PR) - # https://github.com/docker/build-push-action - name: Build and push Docker image - id: build-and-push - uses: docker/build-push-action@v5.1.0 + id: build + uses: docker/build-push-action@v5 with: context: . - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} + file: Dockerfile labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max + platforms: ${{ matrix.platform }} + outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true - # Sign the resulting Docker image digest except on PRs. - # This will only write to the public Rekor transparency log when the Docker - # repository is public to avoid leaking data. If you would like to publish - # transparency data even for private images, pass --force to cosign below. - # https://github.com/sigstore/cosign - - name: Sign the published Docker image - if: ${{ github.event_name != 'pull_request' }} - env: - # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable - TAGS: ${{ steps.meta.outputs.tags }} - DIGEST: ${{ steps.build-and-push.outputs.digest }} - # This step uses the identity token to provision an ephemeral certificate - # against the sigstore community Fulcio instance. - run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + name: Merge digests + runs-on: ubuntu-latest + environment: + name: Production + needs: + - build + steps: + - name: Prepare + run: | + echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}" >> $GITHUB_ENV + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} +# deploy: +# name: Deploy +# runs-on: ubuntu-latest +# environment: +# name: Production +# needs: +# - merge +# steps: +# - name: Pull and restart container +# uses: appleboy/ssh-action@v1.0.3 +# with: +# host: ${{ secrets.HOST }} +# username: ${{ secrets.USERNAME }} +# key: ${{ secrets.KEY }} +# passphrase: ${{ secrets.PASSPHRASE }} +# script: docker compose -f /home/jessew/docker/lysand/docker-compose.yml pull && docker compose -f /home/jessew/docker/lysand/docker-compose.yml down && docker compose -f /home/jessew/docker/lysand/docker-compose.yml up -d \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 51b9eb58..637cc13a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,37 +1,39 @@ -# use the official Bun image -# see all versions at https://hub.docker.com/r/oven/bun/tags -FROM oven/bun:1.0.30-alpine as base -WORKDIR /usr/src/app +# Use the official Bun image (Bun doesn't run well on Musl but this seems to work) +# See all versions at https://hub.docker.com/r/oven/bun/tags +FROM oven/bun:1.1.2-alpine as base + +# Install dependencies into temp directory +# This will cache them and speed up future builds +FROM base AS install + +# Install with --production (exclude devDependencies) +RUN mkdir -p /temp +COPY . /temp +WORKDIR /temp +RUN bun install --frozen-lockfile + +FROM base as build # Required for Prisma to work # COPY --from=node:18-alpine /usr/local/bin/node /usr/local/bin/node -# install dependencies into temp directory -# this will cache them and speed up future builds -FROM base AS install - -# install with --production (exclude devDependencies) +# Copy the project RUN mkdir -p /temp COPY . /temp -WORKDIR /temp -RUN bun install --frozen-lockfile --production - -# Build Vite in pages -RUN bunx --bun vite build pages - +# Copy dependencies +COPY --from=install /temp/node_modules /temp/node_modules # Build the project -RUN bun run build.ts -WORKDIR /temp/dist +WORKDIR /temp +RUN bun run prod-build # copy production dependencies and source code into final image FROM base AS release # Create app directory RUN mkdir -p /app -COPY --from=install /temp/dist /app/dist +COPY --from=build /temp/dist /app/dist COPY entrypoint.sh /app - LABEL org.opencontainers.image.authors "Gaspard Wierzbinski (https://cpluspatch.dev)" LABEL org.opencontainers.image.source "https://github.com/lysand-org/lysand" LABEL org.opencontainers.image.vendor "Lysand Org" diff --git a/bun.lockb b/bun.lockb index 2170054d2d574e1e52985ed6b8aef02eef45750f..92ed051270324090fb6c78b76e07a4cbc60a6b6d 100755 GIT binary patch delta 33 pcmaDbN#wyKk%kt=7N#xC%D(K3ai)4kdKT?kzRcUTd|Ax)006>C3Pk__ delta 33 pcmaDbN#wyKk%kt=7N#xC%D(JOIf*5y#U<@pzRcUTd|Ax)007bn3wi(m diff --git a/docker-compose.yml b/docker-compose.yml index 4e66749e..1898fede 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,22 +1,17 @@ --- -# Run `docker network create lysand-net` before running docker-compose up -version: "3" services: lysand: image: ghcr.io/lysand-org/lysand:main volumes: - #- ./logs:/app/logs + - ./logs:/app/logs - ./config:/app/config - - ./.env:/app/.env - ./uploads:/app/uploads restart: unless-stopped container_name: lysand networks: - lysand-net db: - build: - context: . - dockerfile: Postgres.Dockerfile + image: ghcr.io/lysand-org/postgres:main container_name: lysand-db restart: unless-stopped environment: @@ -28,7 +23,7 @@ services: volumes: - ./db-data:/var/lib/postgresql/data redis: - image: "redis:latest" + image: redis:latest container_name: lysand-redis volumes: - ./redis-data:/data @@ -50,4 +45,4 @@ services: networks: lysand-net: - external: true + internal: true diff --git a/package.json b/package.json index 4d7aef87..9b0b7b93 100644 --- a/package.json +++ b/package.json @@ -1,118 +1,118 @@ { - "name": "lysand", - "module": "index.ts", - "type": "module", - "version": "0.3.0", - "description": "A project to build a federated social network", - "author": { - "email": "contact@cpluspatch.com", - "name": "CPlusPatch", - "url": "https://cpluspatch.com" - }, - "bugs": { - "url": "https://github.com/lysand-org/lysand/issues" - }, - "icon": "https://github.com/lysand-org/lysand", - "license": "AGPL-3.0", - "keywords": ["federated", "activitypub", "bun"], - "workspaces": ["packages/*"], - "maintainers": [ - { - "email": "contact@cpluspatch.com", - "name": "CPlusPatch", - "url": "https://cpluspatch.com" - } - ], - "repository": { - "type": "git", - "url": "git+https://github.com/lysand-org/lysand.git" - }, - "private": true, - "scripts": { - "dev": "bun run --watch index.ts", - "vite:dev": "bunx --bun vite pages", - "vite:build": "bunx --bun vite build pages", - "start": "NODE_ENV=production bun run dist/index.js --prod", - "migrate-dev": "bun prisma migrate dev", - "migrate": "bun prisma migrate deploy", - "lint": "bunx --bun eslint --config .eslintrc.cjs --ext .ts .", - "prod-build": "bunx --bun vite build pages && bun run build.ts", - "prisma": "DATABASE_URL=$(bun run prisma.ts) bunx prisma", - "generate": "bun prisma generate", - "benchmark:timeline": "bun run benchmarks/timelines.ts", - "cloc": "cloc . --exclude-dir node_modules,dist", - "cli": "bun run cli.ts" - }, - "trustedDependencies": [ - "@biomejs/biome", - "@prisma/client", - "@prisma/engines", - "esbuild", - "prisma", - "sharp" - ], - "devDependencies": { - "@biomejs/biome": "1.6.4", - "@julr/unocss-preset-forms": "^0.1.0", - "@types/cli-table": "^0.3.4", - "@types/html-to-text": "^9.0.4", - "@types/ioredis": "^5.0.0", - "@types/jsonld": "^1.5.13", - "@typescript-eslint/eslint-plugin": "latest", - "@unocss/cli": "latest", - "@vitejs/plugin-vue": "latest", - "@vueuse/head": "^2.0.0", - "activitypub-types": "^1.0.3", - "bun-types": "latest", - "typescript": "latest", - "unocss": "latest", - "untyped": "^1.4.2", - "vite": "latest", - "vite-ssr": "^0.17.1", - "vue": "^3.3.9", - "vue-router": "^4.2.5", - "vue-tsc": "latest" - }, - "peerDependencies": { - "typescript": "^5.3.2" - }, - "dependencies": { - "@aws-sdk/client-s3": "^3.461.0", - "@iarna/toml": "^2.2.5", - "@json2csv/plainjs": "^7.0.6", - "@prisma/client": "^5.6.0", - "blurhash": "^2.0.5", - "bullmq": "latest", - "c12": "^1.10.0", - "chalk": "^5.3.0", - "cli-parser": "workspace:*", - "cli-table": "^0.3.11", - "config-manager": "workspace:*", - "eventemitter3": "^5.0.1", - "extract-zip": "^2.0.1", - "html-to-text": "^9.0.5", - "ioredis": "^5.3.2", - "ip-matching": "^2.1.2", - "iso-639-1": "^3.1.0", - "isomorphic-dompurify": "latest", - "jsonld": "^8.3.1", - "linkify-html": "^4.1.3", - "linkify-string": "^4.1.3", - "linkifyjs": "^4.1.3", - "log-manager": "workspace:*", - "marked": "latest", - "media-manager": "workspace:*", - "megalodon": "^10.0.0", - "meilisearch": "latest", - "merge-deep-ts": "^1.2.6", - "next-route-matcher": "^1.0.1", - "oauth4webapi": "^2.4.0", - "prisma": "^5.6.0", - "prisma-json-types-generator": "^3.0.4", - "prisma-redis-middleware": "^4.8.0", - "request-parser": "workspace:*", - "semver": "^7.5.4", - "sharp": "^0.33.0-rc.2", - "strip-ansi": "^7.1.0" + "name": "lysand", + "module": "index.ts", + "type": "module", + "version": "0.3.0", + "description": "A project to build a federated social network", + "author": { + "email": "contact@cpluspatch.com", + "name": "CPlusPatch", + "url": "https://cpluspatch.com" + }, + "bugs": { + "url": "https://github.com/lysand-org/lysand/issues" + }, + "icon": "https://github.com/lysand-org/lysand", + "license": "AGPL-3.0", + "keywords": ["federated", "activitypub", "bun"], + "workspaces": ["packages/*"], + "maintainers": [ + { + "email": "contact@cpluspatch.com", + "name": "CPlusPatch", + "url": "https://cpluspatch.com" } + ], + "repository": { + "type": "git", + "url": "git+https://github.com/lysand-org/lysand.git" + }, + "private": true, + "scripts": { + "dev": "bun run --watch index.ts", + "vite:dev": "bunx --bun vite pages", + "vite:build": "bunx --bun vite build pages", + "start": "NODE_ENV=production bun run dist/index.js --prod", + "migrate-dev": "bun prisma migrate dev", + "migrate": "bun prisma migrate deploy", + "lint": "bunx --bun eslint --config .eslintrc.cjs --ext .ts .", + "prod-build": "bunx --bun vite build pages && bun run build.ts", + "prisma": "DATABASE_URL=$(bun run prisma.ts) bunx prisma", + "generate": "bun prisma generate", + "benchmark:timeline": "bun run benchmarks/timelines.ts", + "cloc": "cloc . --exclude-dir node_modules,dist", + "cli": "bun run cli.ts" + }, + "trustedDependencies": [ + "@biomejs/biome", + "@prisma/client", + "@prisma/engines", + "esbuild", + "prisma", + "sharp" + ], + "devDependencies": { + "@biomejs/biome": "1.6.4", + "@julr/unocss-preset-forms": "^0.1.0", + "@types/cli-table": "^0.3.4", + "@types/html-to-text": "^9.0.4", + "@types/ioredis": "^5.0.0", + "@types/jsonld": "^1.5.13", + "@typescript-eslint/eslint-plugin": "latest", + "@unocss/cli": "latest", + "@vitejs/plugin-vue": "latest", + "@vueuse/head": "^2.0.0", + "activitypub-types": "^1.0.3", + "bun-types": "latest", + "typescript": "latest", + "unocss": "latest", + "untyped": "^1.4.2", + "vite": "^5.2.8", + "vite-ssr": "^0.17.1", + "vue": "^3.3.9", + "vue-router": "^4.2.5", + "vue-tsc": "latest" + }, + "peerDependencies": { + "typescript": "^5.3.2" + }, + "dependencies": { + "@aws-sdk/client-s3": "^3.461.0", + "@iarna/toml": "^2.2.5", + "@json2csv/plainjs": "^7.0.6", + "@prisma/client": "^5.6.0", + "blurhash": "^2.0.5", + "bullmq": "latest", + "c12": "^1.10.0", + "chalk": "^5.3.0", + "cli-parser": "workspace:*", + "cli-table": "^0.3.11", + "config-manager": "workspace:*", + "eventemitter3": "^5.0.1", + "extract-zip": "^2.0.1", + "html-to-text": "^9.0.5", + "ioredis": "^5.3.2", + "ip-matching": "^2.1.2", + "iso-639-1": "^3.1.0", + "isomorphic-dompurify": "latest", + "jsonld": "^8.3.1", + "linkify-html": "^4.1.3", + "linkify-string": "^4.1.3", + "linkifyjs": "^4.1.3", + "log-manager": "workspace:*", + "marked": "latest", + "media-manager": "workspace:*", + "megalodon": "^10.0.0", + "meilisearch": "latest", + "merge-deep-ts": "^1.2.6", + "next-route-matcher": "^1.0.1", + "oauth4webapi": "^2.4.0", + "prisma": "^5.6.0", + "prisma-json-types-generator": "^3.0.4", + "prisma-redis-middleware": "^4.8.0", + "request-parser": "workspace:*", + "semver": "^7.5.4", + "sharp": "^0.33.0-rc.2", + "strip-ansi": "^7.1.0" + } }