diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..427e82e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM node:20-alpine + +RUN apk add --no-cache python3 make g++ ffmpeg \ + && ln -sf python3 /usr/bin/python + +ENV FS_DIRECTORY=/data/ +ENV TEMP_DIRECTORY=/temp/ + +WORKDIR /usr/app-production + +COPY package*.json ./ + +RUN npm install + +COPY . . + +RUN npm run build + +# Default Ports +EXPOSE 8080 +EXPOSE 3000 + +CMD [ "npm", "run", "start"] \ No newline at end of file diff --git a/Dockerfile.production b/Dockerfile.production deleted file mode 100644 index 6451069..0000000 --- a/Dockerfile.production +++ /dev/null @@ -1,17 +0,0 @@ -FROM node:20 - -WORKDIR /usr/app-production - -COPY package*.json ./ - -RUN npm install - -COPY . . - -RUN npm run build - -# Default Ports -EXPOSE 8080 -EXPOSE 3000 - -CMD [ "npm", "run", "start"] \ No newline at end of file diff --git a/backend/config/.env.development.example b/backend/config/.env.development.example index 27cfd48..515ddca 100644 --- a/backend/config/.env.development.example +++ b/backend/config/.env.development.example @@ -1,6 +1,9 @@ # Either remove the .example from the end of this filename. # Or create a new file with the same name, but without the .example extension. +# NOTE: If you are using docker, you should provide these env variables during the docker run command instead. +# But you can still use this file as a guide. + # MongoDB URL: Connection string for your MongoDB database # example: mongodb://localhost:27017/mydrive MONGODB_URL= @@ -34,8 +37,7 @@ HTTP_PORT= HTTPS_PORT= # URL (optional): The URL to run the server on. -# Most likely not needed, but useful if you are running docker or such -# And need to bind to 0.0.0.0 instead. +# Most likely not needed, this changes the ip address/url express listens on. URL= # Email verifcation (optional): If you want to enable email verification configure as so. @@ -84,4 +86,11 @@ SECURE_COOKIES= # SSL=true # Place your SSL certificate files in the root directory of the project # With the names: certificate.crt, certificate.key, and certificate.ca-bundle; -SSL= \ No newline at end of file +SSL= + +# HTTPS cert paths (optional): If you need to change the paths of the https certs +# You can do so with these env variables. +# By default myDrive looks for certificate.crt, certificate.ca-bundle and certificate.key on the root of the project +HTTPS_KEY_PATH= +HTTPS_CA_PATH= +HTTPS_CRT_PATH= \ No newline at end of file diff --git a/backend/config/.env.production.example b/backend/config/.env.production.example index 27cfd48..515ddca 100644 --- a/backend/config/.env.production.example +++ b/backend/config/.env.production.example @@ -1,6 +1,9 @@ # Either remove the .example from the end of this filename. # Or create a new file with the same name, but without the .example extension. +# NOTE: If you are using docker, you should provide these env variables during the docker run command instead. +# But you can still use this file as a guide. + # MongoDB URL: Connection string for your MongoDB database # example: mongodb://localhost:27017/mydrive MONGODB_URL= @@ -34,8 +37,7 @@ HTTP_PORT= HTTPS_PORT= # URL (optional): The URL to run the server on. -# Most likely not needed, but useful if you are running docker or such -# And need to bind to 0.0.0.0 instead. +# Most likely not needed, this changes the ip address/url express listens on. URL= # Email verifcation (optional): If you want to enable email verification configure as so. @@ -84,4 +86,11 @@ SECURE_COOKIES= # SSL=true # Place your SSL certificate files in the root directory of the project # With the names: certificate.crt, certificate.key, and certificate.ca-bundle; -SSL= \ No newline at end of file +SSL= + +# HTTPS cert paths (optional): If you need to change the paths of the https certs +# You can do so with these env variables. +# By default myDrive looks for certificate.crt, certificate.ca-bundle and certificate.key on the root of the project +HTTPS_KEY_PATH= +HTTPS_CA_PATH= +HTTPS_CRT_PATH= \ No newline at end of file diff --git a/backend/config/.env.test.example b/backend/config/.env.test.example index 27cfd48..515ddca 100644 --- a/backend/config/.env.test.example +++ b/backend/config/.env.test.example @@ -1,6 +1,9 @@ # Either remove the .example from the end of this filename. # Or create a new file with the same name, but without the .example extension. +# NOTE: If you are using docker, you should provide these env variables during the docker run command instead. +# But you can still use this file as a guide. + # MongoDB URL: Connection string for your MongoDB database # example: mongodb://localhost:27017/mydrive MONGODB_URL= @@ -34,8 +37,7 @@ HTTP_PORT= HTTPS_PORT= # URL (optional): The URL to run the server on. -# Most likely not needed, but useful if you are running docker or such -# And need to bind to 0.0.0.0 instead. +# Most likely not needed, this changes the ip address/url express listens on. URL= # Email verifcation (optional): If you want to enable email verification configure as so. @@ -84,4 +86,11 @@ SECURE_COOKIES= # SSL=true # Place your SSL certificate files in the root directory of the project # With the names: certificate.crt, certificate.key, and certificate.ca-bundle; -SSL= \ No newline at end of file +SSL= + +# HTTPS cert paths (optional): If you need to change the paths of the https certs +# You can do so with these env variables. +# By default myDrive looks for certificate.crt, certificate.ca-bundle and certificate.key on the root of the project +HTTPS_KEY_PATH= +HTTPS_CA_PATH= +HTTPS_CRT_PATH= \ No newline at end of file diff --git a/backend/enviroment/env.ts b/backend/enviroment/env.ts index dcfbc46..305d661 100644 --- a/backend/enviroment/env.ts +++ b/backend/enviroment/env.ts @@ -31,6 +31,9 @@ export default { ? +process.env.TEMP_VIDEO_THUMBNAIL_LIMIT : 0, docker: process.env.DOCKER === "true", + httpsKeyPath: process.env.HTTPS_KEY_PATH, + httpsCaPath: process.env.HTTPS_CA_PATH, + httpsCrtPath: process.env.HTTPS_CRT_PATH, }; module.exports = { @@ -66,4 +69,7 @@ module.exports = { ? +process.env.TEMP_VIDEO_THUMBNAIL_LIMIT : 0, docker: process.env.DOCKER === "true", + httpsKeyPath: process.env.HTTPS_KEY_PATH, + httpsCaPath: process.env.HTTPS_CA_PATH, + httpsCrtPath: process.env.HTTPS_CRT_PATH, }; diff --git a/backend/models/user-model.ts b/backend/models/user-model.ts index 0b47274..2881e59 100644 --- a/backend/models/user-model.ts +++ b/backend/models/user-model.ts @@ -1,7 +1,7 @@ import mongoose, { Document } from "mongoose"; import validator from "validator"; import crypto from "crypto"; -import bcrypt from "bcrypt"; +import bcrypt from "bcryptjs"; import jwt from "jsonwebtoken"; import env from "../enviroment/env"; import NotAuthorizedError from "../utils/NotAuthorizedError"; diff --git a/backend/server/server-start.ts b/backend/server/server-start.ts index 579f1ef..94b64e2 100644 --- a/backend/server/server-start.ts +++ b/backend/server/server-start.ts @@ -10,25 +10,24 @@ const serverStart = async () => { console.log("ENV", process.env.NODE_ENV); + const httpPort = process.env.HTTP_PORT || process.env.PORT || 3000; + const httpsPort = process.env.HTTPS_PORT || 8080 + if (process.env.NODE_ENV === "production" && process.env.SSL === "true") { - server.listen(process.env.HTTP_PORT, process.env.URL, () => { - console.log("Http Server Running On Port:", process.env.HTTP_PORT); + server.listen(httpPort, process.env.URL, () => { + console.log("Http Server Running On Port:", httpPort); }); - serverHttps.listen(process.env.HTTPS_PORT, function () { - console.log("Https Server Running On Port:", process.env.HTTPS_PORT); + serverHttps.listen(httpsPort, function () { + console.log("Https Server Running On Port:", httpsPort); }); } else if (process.env.NODE_ENV === "production") { - const port = process.env.HTTP_PORT || process.env.PORT; - - server.listen(port, process.env.URL, () => { - console.log("Http Server (No-SSL) Running On Port:", port); + server.listen(httpPort, process.env.URL, () => { + console.log("Http Server (No-SSL) Running On Port:", httpPort); }); } else { - const port = process.env.HTTP_PORT || process.env.PORT; - - server.listen(port, process.env.URL, () => { - console.log("\nDevelopment Backend Server Running On :", port); + server.listen(httpPort, process.env.URL, () => { + console.log("\nDevelopment Backend Server Running On :", httpPort); }); } }; diff --git a/backend/server/server.ts b/backend/server/server.ts index 10dc59d..49d31f5 100755 --- a/backend/server/server.ts +++ b/backend/server/server.ts @@ -23,9 +23,12 @@ let server: any; let serverHttps: any; if (process.env.SSL === "true") { - const cert = fs.readFileSync("certificate.crt"); - const ca = fs.readFileSync("certificate.ca-bundle"); - const key = fs.readFileSync("certificate.key"); + const certPath = env.httpsCrtPath || "certificate.crt" + const caPath = env.httpsCaPath || "certificate.ca-bundle" + const keyPath = env.httpsKeyPath || "certificate.key" + const cert = fs.readFileSync(certPath); + const ca = fs.readFileSync(caPath); + const key = fs.readFileSync(keyPath); const options = { cert, diff --git a/backend/services/user-service/user-service.ts b/backend/services/user-service/user-service.ts index be6560a..114ada8 100644 --- a/backend/services/user-service/user-service.ts +++ b/backend/services/user-service/user-service.ts @@ -1,5 +1,5 @@ import User, { UserInterface } from "../../models/user-model"; -import bcrypt from "bcrypt"; +import bcrypt from "bcryptjs"; import NotFoundError from "../../utils/NotFoundError"; import InternalServerError from "../../utils/InternalServerError"; import sendEmailVerification from "../../utils/sendVerificationEmail"; diff --git a/backend/utils/getFSStoragePath.ts b/backend/utils/getFSStoragePath.ts index 296d8eb..cc98539 100644 --- a/backend/utils/getFSStoragePath.ts +++ b/backend/utils/getFSStoragePath.ts @@ -1,9 +1,5 @@ import env from "../enviroment/env"; export const getFSStoragePath = () => { - if (env.docker) { - return "/data/"; - } else { - return env.fsDirectory; - } + return env.fsDirectory }; diff --git a/docker-compose-production.yml b/docker-compose-production.yml deleted file mode 100644 index 084e8e3..0000000 --- a/docker-compose-production.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: "3.8" -services: - app: - build: - context: . - dockerfile: Dockerfile.production - container_name: mydrive_production - env_file: - - ./backend/config/.env.production - volumes: - - .:/usr/app-production - - /usr/app-production/node_modules - - ${FS_DIRECTORY}:/data - ports: - - "${HTTP_PORT:-3000}:3000" - - "${HTTPS_PORT:-8080}:8080" - environment: - - DOCKER=true diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4efca9b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +version: "3.8" +services: + app: + build: + context: . + dockerfile: Dockerfile + container_name: mydrive + image: mydrive-image + volumes: + - /user/example/:/data + ports: + - "${HTTP_PORT:-3000}:3000" + - "${HTTPS_PORT:-8080}:8080" + environment: + - DOCKER=true + - MONGODB_URL= + - DB_TYPE= + - FS_DIRECTORY=/data # Change this if you change the volume + - S3_ID= + - S3_KEY= + - S3_BUCKET= + - KEY= + - HTTP_PORT= + - HTTPS_PORT= + - URL= + - EMAIL_VERIFICATION= + - EMAIL_DOMAIN= + - EMAIL_ADDRESS= + - EMAIL_API_KEY= + - EMAIL_HOST= + - REMOTE_URL= + - PASSWORD_ACCESS= + - PASSWORD_REFRESH= + - PASSWORD_COOKIE= + - VIDEO_THUMBNAILS_ENABLED= + - TEMP_DIRECTORY= + - TEMP_VIDEO_THUMBNAIL_LIMIT= + - SECURE_COOKIES= + - SSL= diff --git a/package.json b/package.json index 2d4a77c..0582ce4 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mydrive", - "version": "4.0.0", + "version": "4.0.1", "main": "index.js", "license": "GNU General Public License v3.0", "engines": { @@ -38,7 +38,6 @@ "@babel/preset-react": "^7.8.3", "@babel/types": "^7.9.5", "@reduxjs/toolkit": "^2.2.5", - "@types/bcrypt": "^3.0.0", "@types/compression": "^1.7.0", "@types/concat-stream": "^1.6.0", "@types/connect-busboy": "0.0.2", @@ -61,7 +60,7 @@ "aws-sdk": "^2.657.0", "axios": "^1.7.2", "babel-polyfill": "^6.26.0", - "bcrypt": "^5.1.1", + "bcryptjs": "^3.0.2", "body-parser": "^1.20.2", "bytes": "^3.1.0", "classnames": "^2.5.1", diff --git a/readme.md b/readme.md index 81ba699..771f136 100755 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# ![MyDrive Homepage](github_images/homepage.png) +# ![MyDrive Homepage](https://github.com/subnub/myDrive/blob/master/github_images/homepage.png?raw=true) # ☁️ MyDrive @@ -12,8 +12,8 @@ MyDrive is an Open Source cloud file storage server (Similar To Google Drive). H - [Features](#features) - [Tech stack](#tech-stack) -- [Installation (non docker)](#installation) -- [Docker installation](#docker) +- [Docker image](#docker) +- [Manual installation](#installation) - [Common installation issues](#common-installation-issues) - [Screenshots](#screenshots) - [Video](#video) @@ -56,7 +56,55 @@ MyDrive is an Open Source cloud file storage server (Similar To Google Drive). H -## 💻 Installation +## 🐳 Docker image + +Required: + +- Docker +- MongoDB (Unless using a service like Atlas) +
+ +Run the following command to download the latest docker image: + +```javascript +docker pull kylehoell/mydrive:latest +``` + +You must provide enviroment variables for the docker image to work. You can supply these during the docker run command instead of creating the env file.
+ +> [backend/config](backend/config) -> Backend Enviroment Variables + +You must also provide a volume for the image if you are using a filesystem database or if you want to use the generate video thumbnails feature. Volumes should be mounted to /data/ and /temp/ For example: + +```javascript +-v /path/example/mydrive/data/:/data/ -v /path/example/mydrive/temp/:/temp/ +``` + +/data/: This is where the encrypted files will be stored. +/temp/: Where files will temporary be stored to generate video thumbnails as a fallback. + +The docker image will by default run on port 3000. + +Here is an example of the full docker command: + +```bash +docker run -d \ + -p 3000:3000 \ + -e MONGODB_URL=mongodb://127.0.0.1:27017/mydrive \ + -e DB_TYPE=fs \ + -e PASSWORD_ACCESS=secretaccesspassword \ + -e PASSWORD_REFRESH=secretrefreshpassword \ + -e PASSWORD_COOKIE=secretcookiepassword \ + -e KEY=encryptionkey \ + -e VIDEO_THUMBNAILS_ENABLED=true \ + -e TEMP_VIDEO_THUMBNAIL_LIMIT=5000000000 \ + -v /path/example/mydrive/data/:/data/ \ + -v /path/example/mydrive/temp/:/temp/ \ + --name mydrive \ + kylehoell/mydrive:latest +``` + +## 💻 Manual Installation Required: @@ -136,72 +184,45 @@ You can read more about this issue [here](https://stackoverflow.com/questions/38 -## 🐳 Docker - -Setup: - -> Create Environment Variables: - -> You can find enviroment variable examples under:
-> [backend/config](backend/config) -> Backend Enviroment Variables -> [src/config](src/config) -> Frontend Enviroment Variables - -> Simply remove the .example from the end of the filename, and fill in the values. -> Note: In most cases you will only have to change FE enviroment variables for development purposes. - -
- -> Start the Docker image - -```javascript -npm run docker:production -``` - -NOTE: I made an oversight in the docker command, since it requires npm to be installed in order to run the above command, I am working on a fix for this, but here is the command itself that npm runs for now. - -```javascript -docker-compose -p mydrive-production -f docker-compose-production.yml --env-file ./backend/config/.env.production up -``` - ## 📸 Screenshots Modern and colorful design -![MyDrive Design](github_images/homepage.png) +![MyDrive Design](https://github.com/subnub/myDrive/blob/master/github_images/homepage.png?raw=true) Upload Files -![MyDrive Upload](github_images/upload.png) +![MyDrive Upload](https://github.com/subnub/myDrive/blob/master/github_images/upload.png?raw=true) Download Files -![MyDrive Upload](github_images/download.png) +![MyDrive Upload](https://github.com/subnub/myDrive/blob/master/github_images/download.png?raw=true) Image Viewer -![Image Viewer](github_images/image-viewer.png) +![Image Viewer](https://github.com/subnub/myDrive/blob/master/github_images/image-viewer.png?raw=true) Video Viewer -![Video Viewer](github_images/video-viewer.png) +![Video Viewer](https://github.com/subnub/myDrive/blob/master/github_images/video-viewer.png?raw=true) Media Gallery -![Search](github_images/media-viewer.png) +![Search](https://github.com/subnub/myDrive/blob/master/github_images/media-viewer.png?raw=true) Share Files -![Share](github_images/share.png) +![Share](https://github.com/subnub/myDrive/blob/master/github_images/share.png?raw=true) Search For Files/Folders -![Search](github_images/search.png) +![Search](https://github.com/subnub/myDrive/blob/master/github_images/search.png?raw=true) Move File/Folders -![Move](github_images/move.png) +![Move](https://github.com/subnub/myDrive/blob/master/github_images/move.png?raw=true) Multi-select -![Multi-select](github_images/multiselect.png) +![Multi-select](https://github.com/subnub/myDrive/blob/master/github_images/multiselect.png?raw=true) Custom context menu -![Context menu](github_images/context.png) +![Context menu](https://github.com/subnub/myDrive/blob/master/github_images/context.png?raw=true) Trash -![Trash](github_images/trash.png) +![Trash](https://github.com/subnub/myDrive/blob/master/github_images/trash.png?raw=true) @@ -210,7 +231,7 @@ Trash I created a short YouTube video, showing off myDrives design and features: [![myDrive 4 (open source Google Drive alternative) - UI and feature overview -](github_images/youtube-video.jpeg)](https://www.youtube.com/watch?v=IqmTvAFBszg "myDrive 4 (open source Google Drive alternative) - UI and feature overview +](https://github.com/subnub/myDrive/blob/master/github_images/youtube-video.jpeg?raw=true)](https://www.youtube.com/watch?v=IqmTvAFBszg "myDrive 4 (open source Google Drive alternative) - UI and feature overview ")