diff --git a/Dockerfile b/Dockerfile index 621472736ef..22dd3ccd3d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,11 @@ FROM node:20.5-slim WORKDIR /app +ARG UID=1001 +ARG GID=1001 +RUN groupadd -g $GID homarr-group +RUN useradd -r -u $UID -g $GID homarr + # Define node.js environment variables ARG PORT=7575 @@ -18,17 +23,30 @@ COPY .next/standalone ./ COPY .next/static ./.next/static COPY ./scripts/run.sh ./scripts/run.sh COPY ./drizzle ./drizzle + +COPY ./drizzle/migrate ./migrate +COPY ./tsconfig.json ./migrate/tsconfig.json + RUN mkdir /data -COPY ./src/migrate.ts ./src/migrate.ts +RUN chown -R homarr:homarr-group /data # Install dependencies RUN apt-get update -y && apt-get install -y openssl wget -# Required for migration +# Move node_modules to temp location to avoid overwriting RUN mv node_modules _node_modules RUN rm package.json -RUN yarn add typescript ts-node dotenv drizzle-orm@0.28.6 better-sqlite3@8.6.0 @types/better-sqlite3 -RUN mv node_modules node_modules_migrate + +# Install dependencies for migration +RUN cp ./migrate/package.json ./package.json +RUN yarn + +# Copy better_sqlite3 build for current platform +RUN cp /app/node_modules/better-sqlite3/build/Release/better_sqlite3.node /app/_node_modules/better-sqlite3/build/Release/better_sqlite3.node + +# Copy node_modules for migration to migrate folder for migration script +RUN mv node_modules ./migrate/node_modules +# Copy temp node_modules of app to app folder RUN mv _node_modules node_modules # Expose the default application port @@ -43,4 +61,6 @@ ENV NEXTAUTH_SECRET NOT_IN_USE_BECAUSE_JWTS_ARE_UNUSED HEALTHCHECK --interval=10s --timeout=5s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:${PORT} || exit 1 -CMD ["sh", "./scripts/run.sh"] +USER homarr + +CMD ["sh", "./scripts/run.sh"] \ No newline at end of file diff --git a/src/migrate.ts b/drizzle/migrate/migrate.ts similarity index 83% rename from src/migrate.ts rename to drizzle/migrate/migrate.ts index 5c4abeb88f4..cacf32fe82c 100644 --- a/src/migrate.ts +++ b/drizzle/migrate/migrate.ts @@ -5,6 +5,8 @@ import dotenv from 'dotenv'; import { drizzle } from 'drizzle-orm/better-sqlite3'; import { migrate } from 'drizzle-orm/better-sqlite3/migrator'; +const migrationsFolder = process.argv[2] ?? '../drizzle'; + dotenv.config({ path: __dirname + '/../.env' }); const sqlite = new Database(process.env.DATABASE_URL!.replace('file:', '')); @@ -12,7 +14,7 @@ const sqlite = new Database(process.env.DATABASE_URL!.replace('file:', '')); const db = drizzle(sqlite); const migrateDatabase = async () => { - await migrate(db, { migrationsFolder: './drizzle' }); + await migrate(db, { migrationsFolder }); }; migrateDatabase(); diff --git a/drizzle/migrate/package.json b/drizzle/migrate/package.json new file mode 100644 index 00000000000..35772f2169e --- /dev/null +++ b/drizzle/migrate/package.json @@ -0,0 +1,14 @@ +{ + "description": "This package.json is used for the migration script the dependencies are only installed within the Dockerfile.", + "scripts": { + "db:migrate": "ts-node ./migrate.ts" + }, + "dependencies": { + "@types/better-sqlite3": "^7.6.7", + "better-sqlite3": "8.6.0", + "drizzle-orm": "^0.28.6", + "dotenv": "^16.3.1", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + } +} \ No newline at end of file diff --git a/package.json b/package.json index 9a480b3dad5..6881f60418c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test:coverage": "SKIP_ENV_VALIDATION=1 vitest run --coverage", "docker:build": "turbo build && docker build . -t homarr:local-dev", "docker:start": "docker run -p 7575:7575 --name homarr-development homarr:local-dev", - "db:migrate": "ts-node src/migrate.ts" + "db:migrate": "dotenv ts-node drizzle/migrate/migrate.ts ./drizzle" }, "dependencies": { "@auth/drizzle-adapter": "^0.3.2", @@ -127,6 +127,7 @@ "@vitest/coverage-c8": "^0.33.0", "@vitest/coverage-v8": "^0.34.5", "@vitest/ui": "^0.34.4", + "dotenv-cli": "^7.3.0", "eslint": "^8.0.1", "eslint-config-next": "^13.4.5", "eslint-plugin-promise": "^6.0.0", diff --git a/scripts/run.sh b/scripts/run.sh index 61deab8013b..01e80d0e824 100644 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -2,28 +2,11 @@ echo "Exporting hostname..." export NEXTAUTH_URL_INTERNAL="http://$HOSTNAME:7575" -rm -rf _node_modules -mv node_modules _node_modules -rm -rf node_modules -mv node_modules_migrate node_modules echo "Migrating database..." -yarn ts-node src/migrate.ts & PID=$! +cd ./migrate; yarn db:migrate & PID=$! # Wait for migration to finish wait $PID -echo "Reverting to production node_modules..." -# Copy specific sqlite3 binary to node_modules -cp /app/node_modules/better-sqlite3/build/Release/better_sqlite3.node /app/_node_modules/better-sqlite3/build/Release/better_sqlite3.node - -# Remove node_modules and copy cached node_modules -rm -rf node_modules_migrate -mv node_modules node_modules_migrate -rm -rf node_modules -mv _node_modules node_modules - -cp ./temp_package.json package.json -cp ./temp_yarn.lock yarn.lock - echo "Starting production server..." node /app/server.js \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 0979a03e74e..e000ebb4e8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4754,7 +4754,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -5346,7 +5346,28 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^16.3.1": +"dotenv-cli@npm:^7.3.0": + version: 7.3.0 + resolution: "dotenv-cli@npm:7.3.0" + dependencies: + cross-spawn: ^7.0.3 + dotenv: ^16.3.0 + dotenv-expand: ^10.0.0 + minimist: ^1.2.6 + bin: + dotenv: cli.js + checksum: bc48e9872ed451aa7633cfde0079f5e4b40837d49dca4eab947682c80f524bd1e63ec31ff69b7cf955ff969185a05a343dd5d754dd5569e4ae31f8e9a790ab1b + languageName: node + linkType: hard + +"dotenv-expand@npm:^10.0.0": + version: 10.0.0 + resolution: "dotenv-expand@npm:10.0.0" + checksum: 2a38b470efe0abcb1ac8490421a55e1d764dc9440fd220942bce40965074f3fb00b585f4346020cb0f0f219966ee6b4ee5023458b3e2953fe5b3214de1b314ee + languageName: node + linkType: hard + +"dotenv@npm:^16.3.0, dotenv@npm:^16.3.1": version: 16.3.1 resolution: "dotenv@npm:16.3.1" checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd @@ -7120,6 +7141,7 @@ __metadata: dayjs: ^1.11.7 dockerode: ^3.3.2 dotenv: ^16.3.1 + dotenv-cli: ^7.3.0 drizzle-kit: ^0.19.13 drizzle-orm: ^0.28.6 eslint: ^8.0.1