diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..8aa4daa --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,9 @@ +{ + "name": "JetKVM Cloud API", + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "21.1.0" + } + } +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9ed3f18 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.github +.env* +.prettierrc +.gitignore +.dockerignore +*.md +Dockerfile +node_modules +publish_source.sh \ No newline at end of file diff --git a/.env.example b/.env.example index 86ac439..a58cd3f 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -DATABASE_URL="postgresql://jetkvm:jetkvm@localhost:5432/jetkvm?schema=public" +DATABASE_URL="postgresql://jetkvm:mysecretpassword@localhost:5432/jetkvm?schema=public" GOOGLE_CLIENT_ID=XXX # Google OIDC Client ID GOOGLE_CLIENT_SECRET=XXX # Google OIDC Client Secret @@ -20,4 +20,9 @@ R2_CDN_URL=XXX # Any S3 compatible CDN URL CORS_ORIGINS=https://app.jetkvm.com,http://localhost:5173 # Allowed CORS Origins, split by comma REAL_IP_HEADER=XXX # Real IP Header for the reverse proxy (e.g. X-Real-IP), leave empty if not needed -ICE_SERVERS=XXX # ICE Servers for WebRTC, split by comma (e.g. stun:stun.l.google.com:19302,stun:stun1.l.google.com:19302) \ No newline at end of file +ICE_SERVERS=XXX # ICE Servers for WebRTC, split by comma (e.g. stun:stun.l.google.com:19302,stun:stun1.l.google.com:19302) + +# Uncomment these for development +#POSTGRES_USER=jetkvm +#POSTGRES_PASSWORD=mysecretpassword +#POSTGRES_DB=jetkvm \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1af2f6e..184e8d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .idea -.env \ No newline at end of file +.env +.env.development \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1545ef2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,52 @@ + FROM node:21.1.0-alpine AS base + + ARG NODE_ENV=production + ENV NODE_ENV=${NODE_ENV} + + WORKDIR /app + + RUN apk add --no-cache libc6-compat + + COPY package.json package-lock.json ./ + + # Development Stage + FROM base AS dev + + RUN npm install + + COPY . . + + RUN npx prisma generate + + RUN chown -R node:node /app + + USER node + + EXPOSE 3000 + + # Run development server + CMD ["sh", "-c", "npx prisma migrate dev && npm run dev"] + + #Production Stage + FROM base AS prod + + ENV NODE_ENV=production + + RUN npm ci --omit=dev + + COPY --from=dev /app/node_modules ./node_modules + COPY --from=dev /app/prisma ./prisma + COPY --from=dev /app/src ./src + COPY --from=dev /app/package.json ./ + + RUN npx prisma generate + + RUN chown -R node:node /app + + USER node + + EXPOSE 3000 + + # Run Prisma migrations & start the app in production mode + CMD ["sh", "-c", "npx prisma migrate deploy && exec npm run start"] + \ No newline at end of file diff --git a/README.md b/README.md index aca5f03..a2e7ab5 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,6 @@ The best place to search for answers is our [Documentation](https://jetkvm.com/d If you've found an issue and want to report it, please check our [Issues](https://github.com/jetkvm/cloud-api/issues) page. Make sure the description contains information about the firmware version you're using, your platform, and a clear explanation of the steps to reproduce the issue. - ## Development This project is built with Node.JS, Prisma and Express. @@ -31,17 +30,25 @@ This project is built with Node.JS, Prisma and Express. To start the development server, run: ```bash -# For local development, you can use the following command to start a postgres instanc +# Copy the .env.example file to a new file .env.development and populate it with the correct values +cp .env.example .env.development + +# For local development you can use docker compose to bring up your environment + +# this will run docker-compose.yml with docker-compose.override.yml applied + +docker compose up --build + +# Or you can run a postgres container only + # Don't use in production docker run --name jetkvm-cloud-db \ -e POSTGRES_USER=jetkvm \ -e POSTGRES_PASSWORD=mysecretpassword \ -e POSTGRES_DB=jetkvm \ + -p 5432:5432 \ -d postgres -# Copy the .env.example file to .env and populate it with the correct values -cp .env.example .env - # Install dependencies npm install diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..732bfad --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,30 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + target: dev + args: + NODE_ENV: development + ports: + - "3000:3000" + env_file: + - .env.development + depends_on: + - postgres + volumes: + - .:/app + command: ["sh", "-c", "npm install && npx prisma migrate dev && npm run dev"] + develop: + watch: + - action: sync + path: ./src + target: /app/src + ignore: + - node_modules/ + - action: rebuild + path: package.json + + postgres: + env_file: + - .env.development diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4ea6935 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +services: + postgres: + image: postgres:15 + restart: always + env_file: + - .env + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U jetkvm"] + interval: 5s + retries: 5 + timeout: 3s + + app: + build: + context: . + dockerfile: Dockerfile + args: + NODE_ENV: production + env_file: + - .env + depends_on: + postgres: + condition: service_healthy + expose: + - "3000:3000" + command: ["sh", "-c", "until pg_isready -h postgres -U jetkvm; do sleep 2; done && npx prisma migrate deploy && exec node -r ts-node/register ./src/index.ts"] + +volumes: + pgdata: