diff --git a/.env.example b/.env.example
index eff33e5..3a40463 100644
--- a/.env.example
+++ b/.env.example
@@ -2,7 +2,8 @@
DOCKER=true
# MongoDB URL: Connection string for your MongoDB database
-MONGODB_URL=mongodb://127.0.0.1:27017/mydrive
+# Note: if using the compose file provided, the connection string should be as follows:
+MONGODB_URL=mongodb://username:password@mongo:27017/mydrive?authSource=admin
# Database Type: Choose between "fs" and "s3", this specifies where the files will be stored.
# fs = Filesystem
diff --git a/Dockerfile b/Dockerfile
index 427e82e..02a7baa 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,23 +1,32 @@
-FROM node:20-alpine
+FROM node:20-alpine AS builder
-RUN apk add --no-cache python3 make g++ ffmpeg \
- && ln -sf python3 /usr/bin/python
-
-ENV FS_DIRECTORY=/data/
-ENV TEMP_DIRECTORY=/temp/
+# Install build dependencies
+RUN apk add --no-cache python3 make g++ ffmpeg && \
+ ln -sf python3 /usr/bin/python
WORKDIR /usr/app-production
-
COPY package*.json ./
RUN npm install
COPY . .
-
RUN npm run build
-# Default Ports
+# Remove dev dependencies
+RUN npm prune --production
+
+FROM node:20-alpine
+
+ENV FS_DIRECTORY=/data/
+ENV TEMP_DIRECTORY=/temp/
+
+# Install runtime dependencies
+RUN apk add --no-cache ffmpeg
+
+WORKDIR /usr/app-production
+COPY --from=builder /usr/app-production .
+
EXPOSE 8080
EXPOSE 3000
-CMD [ "npm", "run", "start"]
\ No newline at end of file
+CMD ["npm", "run", "start"]
diff --git a/README.md b/README.md
index ec12a97..cc383a3 100755
--- a/README.md
+++ b/README.md
@@ -1,19 +1,30 @@
# 
-# ☁️ MyDrive
-MyDrive is an Open Source cloud file storage server (Similar To Google Drive). Host myDrive on your own server or trusted platform and then access myDrive through your web browser. MyDrive uses mongoDB to store file/folder metadata, and supports multiple databases to store the file chunks, such as Amazon S3, or the Filesystem.
+
-[Main myDrive website](https://mydrive-storage.com/)
+
+
☁️ MyDrive
+
Open Source cloud file storage server (Similar To Google Drive)
+
Host myDrive on your own server or trusted platform and then access myDrive through your web browser. MyDrive uses mongoDB to store file/folder metadata, and supports multiple databases to store the file chunks, such as Amazon S3, or the Filesystem.
-[Live demo](http://143.244.181.219:3000/)
+
Website
+
|
+
Live demo
+
## 🔍 Index
- [Features](#features)
- [Tech stack](#tech-stack)
-- [Docker image](#docker)
-- [Manual installation](#installation)
+- [Running](#running)
+ - [Docker](#docker)
+ - [Non-Docker](#non-docker)
- [Common installation issues](#common-installation-issues)
- [Screenshots](#screenshots)
- [Video](#video)
@@ -54,40 +65,58 @@ MyDrive is an Open Source cloud file storage server (Similar To Google Drive). H
- Vite
- Jest
+
+
+## Running
+
-## 🐳 Docker image
+### 🐳 Docker
-Required:
+> [!IMPORTANT]
+> Requirements
+> - Docker
+> - MongoDB (optional, comes with `docker-compose.yml`)
-- Docker
-- MongoDB (Unless using a service like Atlas)
-
+#### **Docker Compose**
-Run the following command to download the latest docker image:
+1. Make folder for docker-compose.yml and env file.
+2. Copy [`docker-compose.yml`](./docker-compose.yml) and [`.env.example`](./.env.example) to your directory.
+3. Rename `.env.example` to `.env` and fill in / change the values.
+4. Run the following command:
-```javascript
+```sh
+docker compose up -d
+```
+5. Access the app at `http://localhost:3000`
+
+---
+
+#### **Docker Run**
+
+1. Pull the image
+
+```sh
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.
+2. Run the image
-> [backend/config](backend/config) -> Backend Enviroment Variables
+Using `.env` file. Copy the `.env.example` file and fill in the values.
-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/
+```sh
+docker run -d \
+ -p 3000:3000 \
+ --env-file ./.env \
+ -v /path/example/mydrive/data/:/data/ \
+ -v /path/example/mydrive/temp/:/temp/ \
+ --name mydrive \
+ kylehoell/mydrive:latest
```
-/data/: This is where the encrypted files will be stored.
-/temp/: Where files will temporary be stored to generate video thumbnails as a fallback.
+Or directly pass in the environment variables
-The docker image will by default run on port 3000.
-
-Here is an example of the full docker command:
-
-```bash
+```sh
docker run -d \
-p 3000:3000 \
-e MONGODB_URL=mongodb://127.0.0.1:27017/mydrive \
@@ -104,51 +133,43 @@ docker run -d \
kylehoell/mydrive:latest
```
-
+3. Access the app at `http://localhost:3000`
-## 💻 Manual Installation
+
-Required:
+### 💻 Non - Docker
-- Node.js (20 Recommended)
-- MongoDB (Unless using a service like Atlas)
-- FFMPEG (Optional, used for video thumbnails)
-- build-essential package (If using linux)
+> [!IMPORTANT]
+> Requirements
+> - Node.js (20 Recommended)
+> - MongoDB (Unless using a service like Atlas)
+> - FFMPEG (Optional, used for video thumbnails)
+> - build-essential package (If using linux)
-
+1. Install dependencies
-Setup (Non Docker Method):
-
-> Install Node Modules
-
-```javascript
+```sh
npm install
```
-
+2. Create Environment Variables
-> Create Environment Variables:
+You can find enviroment variable examples under:
+[`backend/config`](backend/config) -> Backend Enviroment Variables
+[`src/config`](src/config) -> Frontend Enviroment 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.
+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.
-
+3. Run the build command
-> Run the build command
-
-```javascript
+```sh
npm run build
```
-
+4. Start the server
-> Start the server
-
-```javascript
+```sh
npm run start
```
@@ -158,27 +179,25 @@ npm run start
Make issue
-```javascript
+```sh
npm error gyp ERR! stack Error: not found: make
```
This is because you do not have the build essentials installed which is required for Linux. You can install them by running the following command:
-```javascript
+```sh
sudo apt-get install build-essential
```
-
-
Memory issue
-```javascript
+```sh
Aborted (core dumped)
```
When running the `npm run build` command it may take more memory than node allows by default. You will get the above error in such a case. To fix this, you can run the following command instead when building:
-```javascript
+```sh
NODE_OPTIONS="--max-old-space-size=4096" npm run build
```
@@ -263,14 +282,14 @@ If you are upgrading from myDrive 3 there is some data migration and scripts you
> Run the migration script
> Note: Make sure you have env variables set
-```javascript
+```sh
npm run migrate-to-mydrive4
```
Also, if you are updating from myDrive 3, or if you did not have video thumbnails enabled and would like to enable them now you can do so by running the following command:
Note: Make sure you have video thumbnails enabled in your env variables and FFMPEG installed.
-```javascript
+```sh
npm run create-video-thumbnails
```
@@ -280,7 +299,6 @@ npm run create-video-thumbnails
#### Issues
-- The docker compose command is currently setup incorrectly since it requires npm to be installed, I am working on a fix for this. (Top priority)
- Video streaming does not always work, especially on Safari.
- PWA downloads does not work on iOS (This may be a current iOS limitation and not a myDrive issue).
- Upload folder will sometimes fail on complex folder structures.
@@ -288,7 +306,6 @@ npm run create-video-thumbnails
#### Future improvments
-- Docker image (Top priority)
- OIDC Support (Top priority)
- Option to disable encryption
- File sync from a local device
diff --git a/backend/config/.env.development.example b/backend/config/.env.development.example
index e2c7a4c..b5a32fe 100644
--- a/backend/config/.env.development.example
+++ b/backend/config/.env.development.example
@@ -1,9 +1,6 @@
# 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=
diff --git a/backend/config/.env.production.example b/backend/config/.env.production.example
index e2c7a4c..b5a32fe 100644
--- a/backend/config/.env.production.example
+++ b/backend/config/.env.production.example
@@ -1,9 +1,6 @@
# 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=
diff --git a/backend/config/.env.test.example b/backend/config/.env.test.example
index e2c7a4c..b5a32fe 100644
--- a/backend/config/.env.test.example
+++ b/backend/config/.env.test.example
@@ -1,9 +1,6 @@
# 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=
diff --git a/docker-compose-test.yml b/docker-compose-test.yml
index 85073fe..ffe0e6a 100644
--- a/docker-compose-test.yml
+++ b/docker-compose-test.yml
@@ -1,25 +1,49 @@
-version: "3.8"
services:
- app:
- build:
- context: .
- dockerfile: Dockerfile
- container_name: mydrive
- volumes:
- # Use the following volumes section if you want to use bind mounts:
- # - /path/to/data:/data/
- # - /path/to/temp:/temp/
+ app:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ container_name: mydrive
+ volumes:
+ # Use the following volumes section if you want to use bind mounts:
+ # - /path/to/data:/data/
+ # - /path/to/temp:/temp/
- # Use the following volumes section if you want to use named volumes:
- - mydrive-data:/data/
- - mydrive-temp:/temp/
- ports:
- - "${HTTP_PORT:-3000}:3000"
- - "${HTTPS_PORT:-8080}:8080"
- env_file:
- - .env.test # Copy .env.example to .env.test or .env and fill in the values
+ # Use the following volumes section if you want to use named volumes:
+ - mydrive-data:/data/
+ - mydrive-temp:/temp/
+ ports:
+ - "${HTTP_PORT:-3000}:3000"
+ # Optional: Uncomment the following line if you want to use HTTPS
+ # - "${HTTPS_PORT:-8080}:8080"
+
+ # Use expose: if using a reverse proxy
+ # expose:
+ # - 3000
+ # - 8080
+ env_file:
+ - .env.test # Copy .env.example to .env.test or .env and fill in the values
+
+ mongo:
+ image: mongo:8
+ container_name: mongo
+ restart: always
+ environment:
+ MONGO_INITDB_ROOT_USERNAME: username
+ MONGO_INITDB_ROOT_PASSWORD: password
+ expose:
+ - 27017
+ volumes:
+ - db-data:/data/db
+ healthcheck:
+ test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
+ timeout: 10s
+ interval: 10s
+ retries: 10
+ start_period: 10s
# Use the following volumes section if you want to use named volumes. Useful for development.
volumes:
- mydrive-data:
- mydrive-temp:
\ No newline at end of file
+ mydrive-data:
+ mydrive-temp:
+ db-data:
diff --git a/docker-compose.yml b/docker-compose.yml
index 5f5f195..170ab3c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,13 +1,47 @@
-version: "3.8"
services:
- app:
- container_name: mydrive
- image: kylehoell/mydrive:latest
- volumes:
- - /path/to/data:/data/
- - /path/to/temp:/temp/
- ports:
- - "${HTTP_PORT:-3000}:3000"
- - "${HTTPS_PORT:-8080}:8080"
- env_file:
- - .env # Copy .env.example to .env and fill in the values
\ No newline at end of file
+ app:
+ container_name: mydrive
+ image: kylehoell/mydrive:latest
+ volumes:
+ # Use the following volumes section if you want to use bind mounts:
+ # - /path/to/data:/data/
+ # - /path/to/temp:/temp/
+
+ # Use the following volumes section if you want to use named volumes:
+ - mydrive-data:/data/
+ - mydrive-temp:/temp/
+ ports:
+ - "${HTTP_PORT:-3000}:3000"
+ # Optional: Uncomment the following line if you want to use HTTPS
+ #- "${HTTPS_PORT:-8080}:8080"
+
+ # Use expose: if using a reverse proxy
+ # expose:
+ # - 3000
+ # - 8080
+ env_file:
+ - .env # Copy .env.example to .env and fill in the values
+
+ mongo:
+ image: mongo:8
+ container_name: mongo
+ restart: always
+ environment:
+ MONGO_INITDB_ROOT_USERNAME: username
+ MONGO_INITDB_ROOT_PASSWORD: password
+ expose:
+ - 27017
+ volumes:
+ - db-data:/data/db
+ healthcheck:
+ test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
+ timeout: 10s
+ interval: 10s
+ retries: 10
+ start_period: 10s
+
+# Use the following volumes section if you want to use named volumes.
+volumes:
+ mydrive-data:
+ mydrive-temp:
+ db-data:
diff --git a/package.json b/package.json
index f30605a..932a185 100755
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"main": "index.js",
"license": "GNU General Public License v3.0",
"engines": {
- "node": "20.14.0"
+ "node": ">=20.14.0"
},
"scripts": {
"dev": "concurrently \"vite\" \"tsc -w -p ./backend/tsconfig.json\" \"npm run dev:backend\"",
@@ -21,37 +21,11 @@
"test": "NODE_ENV=test jest"
},
"dependencies": {
- "@babel/core": "^7.8.4",
- "@babel/parser": "^7.9.4",
- "@babel/plugin-proposal-class-properties": "^7.8.3",
- "@babel/plugin-proposal-object-rest-spread": "^7.8.3",
- "@babel/polyfill": "^7.12.1",
- "@babel/preset-env": "^7.8.4",
- "@babel/preset-react": "^7.8.3",
- "@babel/types": "^7.9.5",
"@reduxjs/toolkit": "^2.2.5",
- "@types/compression": "^1.7.0",
- "@types/concat-stream": "^1.6.0",
- "@types/connect-busboy": "0.0.2",
- "@types/cookie-parser": "^1.4.2",
- "@types/express": "^4.17.21",
- "@types/helmet": "0.0.45",
- "@types/jsonwebtoken": "^8.3.9",
- "@types/node": "^20.14.2",
- "@types/react": "^18.3.3",
- "@types/react-dom": "^18.3.0",
- "@types/request": "^2.48.5",
- "@types/request-ip": "0.0.35",
- "@types/sharp": "^0.25.0",
- "@types/uuid": "^7.0.2",
- "@types/validator": "^13.0.0",
- "@vitejs/plugin-react": "^4.3.0",
"archiver": "^7.0.1",
"async": "^3.2.6",
- "autoprefixer": "^10.4.19",
"aws-sdk": "^2.657.0",
"axios": "^1.7.2",
- "babel-polyfill": "^6.26.0",
"bcryptjs": "^3.0.2",
"body-parser": "^1.20.2",
"bytes": "^3.1.0",
@@ -67,7 +41,6 @@
"dayjs": "^1.11.13",
"diskusage": "^1.1.3",
"dotenv": "^8.2.0",
- "eslint-plugin-react-hooks": "^4.6.2",
"express": "^4.19.2",
"express-validator": "^7.1.0",
"fluent-ffmpeg": "^2.1.3",
@@ -76,12 +49,10 @@
"jsonwebtoken": "^9.0.2",
"lodash.debounce": "^4.0.8",
"mongodb": "^6.7.0",
- "mongodb-memory-server": "^10.1.3",
"mongoose": "^8.4.1",
"nodemailer": "^6.9.14",
"normalize.css": "^8.0.1",
"password-prompt": "^1.1.2",
- "postcss": "^8.4.38",
"progress-stream": "^2.0.0",
"prompts": "^2.4.2",
"raf": "^3.4.1",
@@ -95,41 +66,70 @@
"redux": "^5.0.1",
"regenerator-runtime": "^0.13.3",
"sharp": "^0.33.4",
- "supertest-session": "^4.1.0",
"sweetalert2": "^11.15.10",
"temp": "^0.9.1",
- "typescript": "^5.4.5",
"uuid": "^3.4.0",
- "validator": "^13.12.0",
- "vite": "^5.2.13"
+ "validator": "^13.12.0"
},
"devDependencies": {
+ "@babel/core": "^7.8.4",
+ "@babel/parser": "^7.9.4",
+ "@babel/plugin-proposal-class-properties": "^7.8.3",
+ "@babel/plugin-proposal-object-rest-spread": "^7.8.3",
+ "@babel/polyfill": "^7.12.1",
+ "@babel/preset-env": "^7.8.4",
+ "@babel/preset-react": "^7.8.3",
+ "@babel/types": "^7.9.5",
"@eslint/js": "^9.6.0",
"@types/archiver": "^6.0.3",
"@types/async": "^3.2.24",
"@types/bytes": "^3.1.4",
+ "@types/compression": "^1.7.0",
+ "@types/concat-stream": "^1.6.0",
+ "@types/connect-busboy": "0.0.2",
+ "@types/cookie-parser": "^1.4.2",
"@types/cors": "^2.8.17",
+ "@types/express": "^4.17.21",
"@types/fluent-ffmpeg": "^2.1.24",
+ "@types/helmet": "0.0.45",
"@types/jest": "^29.5.14",
+ "@types/jsonwebtoken": "^8.3.9",
"@types/lodash": "^4.17.5",
+ "@types/node": "^20.14.2",
"@types/nodemailer": "^6.4.15",
"@types/prompts": "^2.4.9",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
+ "@types/request": "^2.48.5",
+ "@types/request-ip": "0.0.35",
+ "@types/sharp": "^0.25.0",
"@types/supertest": "^6.0.2",
+ "@types/uuid": "^7.0.2",
+ "@types/validator": "^13.0.0",
+ "@vitejs/plugin-react": "^4.3.0",
+ "autoprefixer": "^10.4.19",
+ "babel-polyfill": "^6.26.0",
"concurrently": "^8.2.2",
"cross-env": "^6.0.3",
"dart-sass": "^1.25.0",
"env-cmd": "^10.1.0",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.3",
+ "eslint-plugin-react-hooks": "^4.6.2",
"globals": "^15.7.0",
"jest": "^29.7.0",
+ "mongodb-memory-server": "^10.1.3",
"nodemon": "^3.1.3",
+ "postcss": "^8.4.38",
"rollup-plugin-visualizer": "^5.14.0",
"sass": "^1.77.4",
"superagent-binary-parser": "^1.0.1",
"supertest": "^6.3.4",
+ "supertest-session": "^4.1.0",
"tailwindcss": "^3.4.4",
+ "typescript": "^5.4.5",
"typescript-eslint": "^7.14.1",
+ "vite": "^5.2.13",
"vite-plugin-pwa": "^0.21.1"
}
}