Skip to content
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

Feature/streamline build process #111

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,20 @@
POSTGRES_PRISMA_URL=postgresql://postgres:1234@localhost
POSTGRES_URL_NON_POOLING=postgresql://postgres:1234@localhost
# db
POSTGRES_PASSWORD=1234

# app
POSTGRES_PRISMA_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db
POSTGRES_URL_NON_POOLING=postgresql://postgres:${POSTGRES_PASSWORD}@db
NEXT_PUBLIC_BASE_URL=http://localhost:3000

# app-minio
NEXT_PUBLIC_ENABLE_EXPENSE_DOCUMENTS=false
S3_UPLOAD_KEY=""
S3_UPLOAD_SECRET=""
S3_UPLOAD_BUCKET=spliit
S3_UPLOAD_REGION=eu-north-1
S3_UPLOAD_ENDPOINT=s3://minio.example.com

# app-openai
NEXT_PUBLIC_ENABLE_RECEIPT_EXTRACT=false
OPENAI_API_KEY=""
NEXT_PUBLIC_ENABLE_CATEGORY_EXTRACT=false
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

# production
/build
tmp/
dist/

# misc
.DS_Store
Expand Down
51 changes: 13 additions & 38 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,47 +1,22 @@
FROM node:21-alpine as base
ARG SPLIIT_NODE_VERSION="21-alpine"

WORKDIR /usr/app
COPY ./package.json \
./package-lock.json \
./next.config.js \
./tsconfig.json \
./reset.d.ts \
./tailwind.config.js \
./postcss.config.js ./
COPY ./scripts ./scripts
COPY ./prisma ./prisma
COPY ./src ./src

RUN apk add --no-cache openssl && \
npm ci --ignore-scripts && \
npx prisma generate

ENV NEXT_TELEMETRY_DISABLED=1

COPY scripts/build.env .env
RUN npm run build

RUN rm -r .next/cache
FROM node:${SPLIIT_NODE_VERSION}

FROM node:21-alpine as runtime-deps
ARG SPLIIT_APP_NAME="spliit2"
ARG SPLIIT_VERSION=""
ARG SPLIIT_DEST_DIR="./"

WORKDIR /usr/app
COPY --from=base /usr/app/package.json /usr/app/package-lock.json ./
COPY --from=base /usr/app/prisma ./prisma

RUN npm ci --omit=dev --omit=optional --ignore-scripts && \
npx prisma generate
COPY ${SPLIIT_DEST_DIR} ./
COPY ./scripts/container-entrypoint.sh ./

FROM node:21-alpine as runner
RUN apk add --no-cache openssl

EXPOSE 3000/tcp
WORKDIR /usr/app
ENV NEXT_TELEMETRY_DISABLED=1
ENV SPLIIT_APP_NAME=${SPLIIT_APP_NAME}
ENV SPLIIT_VERSION=${SPLIIT_VERSION}

COPY --from=base /usr/app/package.json /usr/app/package-lock.json ./
COPY --from=runtime-deps /usr/app/node_modules ./node_modules
COPY ./public ./public
COPY ./scripts ./scripts
COPY --from=base /usr/app/prisma ./prisma
COPY --from=base /usr/app/.next ./.next
EXPOSE 3000/tcp

ENTRYPOINT ["/bin/sh", "/usr/app/scripts/container-entrypoint.sh"]
ENTRYPOINT ["/bin/sh", "/usr/app/container-entrypoint.sh"]
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ If you want to contribute financially and help us keep the application free and
## Run locally

1. Clone the repository (or fork it if you intend to contribute)
2. Start a PostgreSQL server. You can run `./scripts/start-local-db.sh` if you don’t have a server already.
3. Copy the file `.env.example` as `.env`
4. Run `npm install` to install dependencies. This will also apply database migrations and update Prisma Client.
5. Run `npm run dev` to start the development server
2. `npm install`
3. Start a PostgreSQL server. You can run `./scripts/start-local-db.sh` if you don’t have a server already.
4. Copy the file `.env.example` as `.env`
5. `npm run prisma-init`
6. `npm run dev`

## Run in a container

1. Run `npm run build-image` to build the docker image from the Dockerfile
2. Copy the file `container.env.example` as `container.env`
2. Copy the file `.env.example` as `.env`
3. Run `npm run start-container` to start the postgres and the spliit2 containers
4. You can access the app by browsing to http://localhost:3000

Expand Down
4 changes: 2 additions & 2 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
ports:
- 3000:3000
env_file:
- container.env
- .env
depends_on:
db:
condition: service_healthy
Expand All @@ -14,7 +14,7 @@ services:
ports:
- 5432:5432
env_file:
- container.env
- .env
volumes:
- ./postgres-data:/var/lib/postgresql/data
healthcheck:
Expand Down
6 changes: 0 additions & 6 deletions container.env.example

This file was deleted.

1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"prebuild": "./scripts/pre-build.sh nightly",
"build": "./scripts/package.sh",
"postbuild": "./scripts/post-build.sh",
"prebuild-prod": "./scripts/pre-build.sh prod",
"build-prod": "./scripts/package.sh",
"postbuild-prod": "./scripts/post-build.sh",
"prebuild-image": "./scripts/pre-build.sh nightly",
"build-image": "./scripts/build-image.sh",
"postbuild-image": "./scripts/post-build.sh",
"prebuild-image-prod": "./scripts/pre-build.sh prod",
"build-image-prod": "./scripts/build-image.sh",
"postbuild-image-prod": "./scripts/post-build.sh",
"start": "next start",
"lint": "next lint",
"check-types": "tsc --noEmit",
"check-formatting": "prettier -c src",
"postinstall": "prisma migrate deploy && prisma generate",
"build-image": "./scripts/build-image.sh",
"start-container": "docker compose --env-file container.env up"
"prisma-init": "prisma migrate deploy && prisma generate",
"start-container": "docker compose --env-file .env up"
},
"dependencies": {
"@hookform/resolvers": "^3.3.2",
Expand Down
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}

datasource db {
Expand Down
26 changes: 18 additions & 8 deletions scripts/build-image.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
#!/bin/bash

SPLIIT_APP_NAME=$(node -p -e "require('./package.json').name")
SPLIIT_VERSION=$(node -p -e "require('./package.json').version")

# we need to set dummy data for POSTGRES env vars in order for build not to fail
docker buildx build \
-t ${SPLIIT_APP_NAME}:${SPLIIT_VERSION} \
-t ${SPLIIT_APP_NAME}:latest \
.
source scripts/set-env.sh

if [ ! -d "${SPLIIT_DEST_DIR}" ]; then
echo "Build folder ${SPLIIT_DEST_DIR} not found"
exit 1
fi

mkdir -p ${SPLIIT_DIST_FOLDER}

docker buildx build \
--no-cache \
--build-arg "SPLIIT_APP_NAME=${SPLIIT_APP_NAME}" \
--build-arg "SPLIIT_VERSION=${SPLIIT_VERSION}" \
--build-arg "SPLIIT_DEST_DIR=${SPLIIT_DEST_DIR}" \
--build-arg "SPLIIT_NODE_VERSION=${SPLIIT_NODE_VERSION}" \
-t ${SPLIIT_APP_NAME}:${SPLIIT_VERSION} \
-t ${SPLIIT_APP_NAME}:latest .
docker save ${SPLIIT_APP_NAME}:${SPLIIT_VERSION} > ./${SPLIIT_DIST_FOLDER}/${SPLIIT_APP_NAME}-${SPLIIT_VERSION}-docker.tar.gz

docker image prune -f
22 changes: 0 additions & 22 deletions scripts/build.env

This file was deleted.

6 changes: 4 additions & 2 deletions scripts/container-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
#!/bin/sh

set -euxo pipefail

echo ${SPLIIT_APP_NAME} v${SPLIIT_VERSION}

npx prisma migrate deploy
npm run start
npx next start
12 changes: 12 additions & 0 deletions scripts/package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

source scripts/set-env.sh

if [ ! -d "${SPLIIT_DEST_DIR}" ]; then
echo "Build folder ${SPLIIT_DEST_DIR} not found"
exit 1
fi

mkdir -p ${SPLIIT_DIST_FOLDER}

tar -zcvf ./${SPLIIT_DIST_FOLDER}/${SPLIIT_RELEASE_NAME}.tar.gz -C ./${SPLIIT_TMP_DIR} ${SPLIIT_APP_NAME}
5 changes: 5 additions & 0 deletions scripts/post-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

source scripts/set-env.sh

rm -rf ./${SPLIIT_TMP_DIR}
42 changes: 42 additions & 0 deletions scripts/pre-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

ENV_FILE=".env"
EXAMPLE_ENV_FILE=".env.example"
NEXT_BUILD_DIR=.next

export SPLIIT_RELEASE_TYPE=$1
source scripts/set-env.sh

# Create env file if not exists
if [ ! -f "${ENV_FILE}" ]; then
echo "Missing ${ENV_FILE} file, creating it from ${EXAMPLE_ENV_FILE}"
cat "${EXAMPLE_ENV_FILE}" > ${ENV_FILE}
fi

# Get dependencies and build
npm i
npx prisma generate
npx next build

# Package
if [ -d ${SPLIIT_DEST_DIR} ]; then
rm -rf ${SPLIIT_DEST_DIR}
else
mkdir -p ${SPLIIT_DEST_DIR}
fi

mv ./${NEXT_BUILD_DIR} ${SPLIIT_DEST_DIR}
rm -rf ${NEXT_BUILD_DIR}
rm -rf ${SPLIIT_DEST_DIR}/.next/cache
cp package.json package-lock.json ${SPLIIT_DEST_DIR}
if [ "${SPLIIT_RELEASE_TYPE}" = "nightly" ]; then
sed -i "s/\s*\"version\":.*/ \"version\":\"${SPLIIT_VERSION}\",/" ${SPLIIT_DEST_DIR}/package.json
fi
PROJECT_DIR=$(pwd)
cp -r ./prisma ${SPLIIT_DEST_DIR}
cp -r ./public ${SPLIIT_DEST_DIR}
cp LICENSE README.md ${SPLIIT_DEST_DIR}
cd ${SPLIIT_DEST_DIR}
npm ci --omit=dev --omit=optional --ignore-scripts
npx prisma generate
cd ${PROJECT_DIR}
29 changes: 29 additions & 0 deletions scripts/set-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

export SPLIIT_NODE_VERSION="21-alpine"

export SPLIIT_TMP_DIR=tmp
export SPLIIT_DIST_FOLDER=dist

export SPLIIT_APP_NAME=$(node -p -e "require('./package.json').name")
export SPLIIT_COMMIT_HASH=$(git rev-parse --short HEAD)

VERSION=$(node -p -e "require('./package.json').version")

export SPLIIT_DEST_DIR=./${SPLIIT_TMP_DIR}/${SPLIIT_APP_NAME}

# Get version based on release type
if [ ! -z ${SPLIIT_RELEASE_TYPE+x} ]; then
if [ "${SPLIIT_RELEASE_TYPE}" = "prod" ]; then
export SPLIIT_VERSION=${VERSION}
elif [ "${SPLIIT_RELEASE_TYPE}" = "nightly" ]; then
export SPLIIT_VERSION=${VERSION}-${SPLIIT_COMMIT_HASH}
else
echo "First argument must be either \"prod\" or \"nightly\""
exit 1
fi
elif [ -d ${SPLIIT_DEST_DIR} ]; then
export SPLIIT_VERSION=$(node -p -e "require('${SPLIIT_DEST_DIR}/package.json').version")
fi

export SPLIIT_RELEASE_NAME=${SPLIIT_APP_NAME}-${SPLIIT_VERSION}
Loading