diff --git a/Makefile b/Makefile index 68ef6cccad..edfd924762 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ push: docker-compose -f docker-compose.yml push up-dev: - docker-compose -f docker-compose.dev.yml up + docker-compose -f docker-compose.dev.yml up --build up-prod: - docker-compose -f docker-compose.yml up + docker-compose -f docker-compose.yml up --build down: docker-compose down \ No newline at end of file diff --git a/backend/environment.d.ts b/backend/environment.d.ts index 52f2764325..33827fb2b6 100644 --- a/backend/environment.d.ts +++ b/backend/environment.d.ts @@ -21,6 +21,7 @@ declare global { PRIVATE_KEY: string; PUBLIC_KEY: string; SENTRY_DSN: string; + SITE_URL: string; SMTP_HOST: string; SMTP_NAME: string; SMTP_PASSWORD: string; @@ -31,7 +32,6 @@ declare global { STRIPE_PUBLISHABLE_KEY: string; STRIPE_SECRET_KEY: string; STRIPE_WEBHOOK_SECRET: string; - WEBSITE_URL: string; } } } diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 371049eed5..736e933751 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -17,6 +17,7 @@ const POSTHOG_PROJECT_API_KEY = process.env.POSTHOG_PROJECT_API_KEY!; const PRIVATE_KEY = process.env.PRIVATE_KEY!; const PUBLIC_KEY = process.env.PUBLIC_KEY!; const SENTRY_DSN = process.env.SENTRY_DSN!; +const SITE_URL = process.env.SITE_URL!; const SMTP_HOST = process.env.SMTP_HOST! || 'smtp.gmail.com'; const SMTP_NAME = process.env.SMTP_NAME!; const SMTP_USERNAME = process.env.SMTP_USERNAME!; @@ -27,7 +28,8 @@ const STRIPE_PRODUCT_STARTER = process.env.STRIPE_PRODUCT_STARTER!; const STRIPE_PUBLISHABLE_KEY = process.env.STRIPE_PUBLISHABLE_KEY!; const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY!; const STRIPE_WEBHOOK_SECRET = process.env.STRIPE_WEBHOOK_SECRET!; -const WEBSITE_URL = 'http://frontend:3000'; + +console.log('New SITE_URL: ', SITE_URL); export { PORT, @@ -49,6 +51,7 @@ export { PRIVATE_KEY, PUBLIC_KEY, SENTRY_DSN, + SITE_URL, SMTP_HOST, SMTP_NAME, SMTP_USERNAME, @@ -58,6 +61,5 @@ export { STRIPE_PRODUCT_STARTER, STRIPE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, - STRIPE_WEBHOOK_SECRET, - WEBSITE_URL + STRIPE_WEBHOOK_SECRET }; diff --git a/backend/src/controllers/membershipController.ts b/backend/src/controllers/membershipController.ts index 375ce54305..f2ed3db6ed 100644 --- a/backend/src/controllers/membershipController.ts +++ b/backend/src/controllers/membershipController.ts @@ -6,7 +6,7 @@ import { deleteMembership as deleteMember } from '../helpers/membership'; import { sendMail } from '../helpers/nodemailer'; -import { WEBSITE_URL } from '../config'; +import { SITE_URL } from '../config'; import { ADMIN, MEMBER, GRANTED, ACCEPTED } from '../variables'; /** @@ -217,11 +217,10 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => { inviterFirstName: req.user.firstName, inviterEmail: req.user.email, workspaceName: req.membership.workspace.name, - callback_url: WEBSITE_URL + '/login' + callback_url: SITE_URL + '/login' } }); } catch (err) { - console.error(err); Sentry.setUser({ email: req.user.email }); Sentry.captureException(err); return res.status(400).send({ diff --git a/backend/src/controllers/membershipOrgController.ts b/backend/src/controllers/membershipOrgController.ts index 6bd9a66844..bc28049966 100644 --- a/backend/src/controllers/membershipOrgController.ts +++ b/backend/src/controllers/membershipOrgController.ts @@ -1,7 +1,7 @@ import { Request, Response } from 'express'; import * as Sentry from '@sentry/node'; import crypto from 'crypto'; -import { WEBSITE_URL, JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET } from '../config'; +import { SITE_URL, JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET } from '../config'; import { MembershipOrg, Organization, User, Token } from '../models'; import { deleteMembershipOrg as deleteMemberFromOrg } from '../helpers/membershipOrg'; import { checkEmailVerification } from '../helpers/signup'; @@ -186,7 +186,7 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { organizationName: organization.name, email: inviteeEmail, token, - callback_url: WEBSITE_URL + '/signupinvite' + callback_url: SITE_URL + '/signupinvite' } }); } diff --git a/backend/src/controllers/organizationController.ts b/backend/src/controllers/organizationController.ts index b29d2dfa12..bce757d0a7 100644 --- a/backend/src/controllers/organizationController.ts +++ b/backend/src/controllers/organizationController.ts @@ -1,11 +1,11 @@ import { Request, Response } from 'express'; import * as Sentry from '@sentry/node'; import { + SITE_URL, STRIPE_SECRET_KEY, STRIPE_PRODUCT_STARTER, STRIPE_PRODUCT_PRO, - STRIPE_PRODUCT_CARD_AUTH, - WEBSITE_URL + STRIPE_PRODUCT_CARD_AUTH } from '../config'; import Stripe from 'stripe'; const stripe = new Stripe(STRIPE_SECRET_KEY, { @@ -350,13 +350,13 @@ export const createOrganizationPortalSession = async ( customer: req.membershipOrg.organization.customerId, mode: 'setup', payment_method_types: ['card'], - success_url: WEBSITE_URL + '/dashboard', - cancel_url: WEBSITE_URL + '/dashboard' + success_url: SITE_URL + '/dashboard', + cancel_url: SITE_URL + '/dashboard' }); } else { session = await stripe.billingPortal.sessions.create({ customer: req.membershipOrg.organization.customerId, - return_url: WEBSITE_URL + '/dashboard' + return_url: SITE_URL + '/dashboard' }); } diff --git a/backend/src/index.ts b/backend/src/index.ts index 464f9c9aa9..e25e18f59c 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -6,7 +6,7 @@ import mongoose from 'mongoose'; import dotenv from 'dotenv'; dotenv.config(); import * as Sentry from '@sentry/node'; -import { PORT, SENTRY_DSN, NODE_ENV, MONGO_URL, WEBSITE_URL } from './config'; +import { PORT, SENTRY_DSN, NODE_ENV, MONGO_URL, SITE_URL } from './config'; import { apiLimiter } from './helpers/rateLimiter'; const app = express(); @@ -38,7 +38,6 @@ import { } from './routes'; const connectWithRetry = () => { - console.log('MONGO_URL', MONGO_URL); mongoose.connect(MONGO_URL) .then(() => console.log('Successfully connected to DB')) .catch((e) => { @@ -55,7 +54,7 @@ app.enable('trust proxy'); app.use(cookieParser()); app.use(cors({ credentials: true, - origin: WEBSITE_URL + origin: SITE_URL })); if (NODE_ENV === 'production') { diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 95a226b2f6..944d7a56fe 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -4,6 +4,7 @@ services: nginx: container_name: infisical-dev-nginx image: nginx + restart: always ports: - 8080:80 volumes: @@ -47,6 +48,8 @@ services: - ./frontend/styles:/app/styles - ./frontend/components:/app/components env_file: .env + environment: + - NEXT_PUBLIC_WEBSITE_URL=${SITE_URL} networks: - infisical-dev @@ -55,6 +58,9 @@ services: container_name: infisical-dev-mongo restart: always env_file: .env + environment: + - MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME} + - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD} volumes: - mongo-data:/data/db networks: @@ -65,6 +71,10 @@ services: image: mongo-express restart: always env_file: .env + environment: + - ME_CONFIG_MONGODB_ADMINUSERNAME=${MONGO_USERNAME} + - ME_CONFIG_MONGODB_ADMINPASSWORD=${MONGO_PASSWORD} + - ME_CONFIG_MONGODB_URL=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongo:27017/ ports: - 8081:8081 networks: diff --git a/docker-compose.yml b/docker-compose.yml index d8f7f2a2a2..741d60c050 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,7 @@ services: nginx: container_name: infisical-nginx image: nginx + restart: always ports: - 80:80 - 443:443 @@ -16,34 +17,28 @@ services: - infisical backend: - platform: linux/amd64 container_name: infisical-backend restart: unless-stopped depends_on: - mongo + build: + context: ./backend + dockerfile: Dockerfile image: infisical/backend - volumes: - - ./backend/src:/app/src - - ./backend/nodemon.json:/app/nodemon.json - - /app/node_modules command: npm run start env_file: .env networks: - infisical frontend: - platform: linux/amd64 container_name: infisical-frontend restart: unless-stopped depends_on: - backend + build: + context: ./frontend + dockerfile: Dockerfile.prod image: infisical/frontend - volumes: - - ./frontend/pages:/app/pages - - ./frontend/public:/app/public - - ./frontend/styles:/app/styles - - ./frontend/components:/app/components - - ./frontend/next.config.js:/app/next.config.js env_file: .env networks: - infisical @@ -52,15 +47,14 @@ services: container_name: infisical-mongo image: mongo restart: always + env_file: .env + environment: + - MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME} + - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD} volumes: - mongo-data:/data/db networks: - infisical - - watchtower: - image: containrrr/watchtower - volumes: - - /var/run/docker.sock:/var/run/docker.sock volumes: mongo-data: diff --git a/docs/self-hosting/configuration/envars.mdx b/docs/self-hosting/configuration/envars.mdx index 3a22d627be..376df85fe4 100644 --- a/docs/self-hosting/configuration/envars.mdx +++ b/docs/self-hosting/configuration/envars.mdx @@ -7,29 +7,27 @@ description: "" Configuring Infisical requires setting some environment variables. There is a file called `.env.example` at the root directory of our main repo that you can use to create a `.env` before you start the server. -| Variable | Description | Default Value | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------- | -| `PRIVATE_KEY` | ❗️ NaCl-generated server secret key | `None` | -| `PUBLIC_KEY` | ❗️ NaCl-generated server public key | `None` | -| `ENCRYPTION_KEY` | ❗️ Strong hex encryption key | `None` | -| `JWT_SIGNUP_SECRET` | ❗️JWT token secret | `None` | -| `JWT_REFRESH_SECRET` | ❗️ JWT token secret | `None` | -| `JWT_AUTH_SECRET` | ❗️ JWT token secret | `None` | -| `JWT_SIGNUP_LIFETIME` | JWT token lifetime expressed in seconds or a string describing a time span (e.g. 60, "2 days", "10h", "7d") | `15m` | -| `JWT_REFRESH_LIFETIME` | JWT token lifetime expressed in seconds or a string describing a time span (e.g. 60, "2 days", "10h", "7d") | `90d` | -| `JWT_AUTH_LIFETIME` | JWT token lifetime expressed in seconds or a string describing a time span (e.g. 60, "2 days", "10h", "7d") | `10d` | -| `EMAIL_TOKEN_LIFETIME` | Email OTP/magic-link lifetime expressed in seconds | `86400` | -| `MONGO_URL` | ❗️ MongoDB instance connection string either to container instance or MongoDB Cloud | `None` | -| `MONGO_INITDB_ROOT_USERNAME` | MongoDB container username | `None` | -| `MONGO_INITDB_ROOT_PASSWORD` | MongoDB container password | `None` | -| `ME_CONFIG_MONGODB_ADMINUSERNAME` | Same as `MONGO_USERNAME` for mongo-express in development | `None` | -| `ME_CONFIG_MONGODB_ADMINPASSWORD` | Same as `MONGO_PASSWORD` for mongo-express in development | `None` | -| `NODE_ENV` | ❗️ `production` or `development` | `None` | -| `NEXT_PUBLIC_WEBSITE_URL` | ❗️ Site URL - should be an absolute URL including the protocol (e.g. `https://infisical.com`) | `None` | -| `SMT_HOST` | Whether the user joined the community | `smtp.gmail.com` | -| `SMTP_NAME` | ❗️ Whether the user joined the community | `None` | -| `SMTP_USERNAME` | ❗️ Whether the user joined the community | `None` | -| `SMTP_PASSWORD` | ❗️ Whether the user joined the community | `None` | -| `OAUTH_CLIENT_SECRET_HEROKU` | OAuth client secret for Heroku integration | `None` | -| `OAUTH_TOKEN_URL_HEROKU` | OAuth token URL for Heroku integration | `None` | -| `SENTRY_DSN` | DSN for error-monitoring with Sentry | `None` | +| Variable | Description | Default Value | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------- | +| `PRIVATE_KEY` | ❗️ NaCl-generated server secret key | `None` | +| `PUBLIC_KEY` | ❗️ NaCl-generated server public key | `None` | +| `ENCRYPTION_KEY` | ❗️ Strong hex encryption key | `None` | +| `JWT_SIGNUP_SECRET` | ❗️JWT token secret | `None` | +| `JWT_REFRESH_SECRET` | ❗️ JWT token secret | `None` | +| `JWT_AUTH_SECRET` | ❗️ JWT token secret | `None` | +| `JWT_SIGNUP_LIFETIME` | JWT token lifetime expressed in seconds or a string describing a time span (e.g. 60, "2 days", "10h", "7d") | `15m` | +| `JWT_REFRESH_LIFETIME` | JWT token lifetime expressed in seconds or a string describing a time span (e.g. 60, "2 days", "10h", "7d") | `90d` | +| `JWT_AUTH_LIFETIME` | JWT token lifetime expressed in seconds or a string describing a time span (e.g. 60, "2 days", "10h", "7d") | `10d` | +| `EMAIL_TOKEN_LIFETIME` | Email OTP/magic-link lifetime expressed in seconds | `86400` | +| `MONGO_URL` | ❗️ MongoDB instance connection string either to container instance or MongoDB Cloud | `None` | +| `MONGO_USERNAME` | MongoDB username if using container | `None` | +| `MONGO_PASSWORD` | MongoDB password if using container | `None` | +| `NODE_ENV` | ❗️ `production` or `development` | `None` | +| `SITE_URL` | ❗️ Site URL - should be an absolute URL including the protocol (e.g. `https://app.infisical.com`) | `None` | +| `SMT_HOST` | Whether the user joined the community | `smtp.gmail.com` | +| `SMTP_NAME` | ❗️ Whether the user joined the community | `None` | +| `SMTP_USERNAME` | ❗️ Whether the user joined the community | `None` | +| `SMTP_PASSWORD` | ❗️ Whether the user joined the community | `None` | +| `OAUTH_CLIENT_SECRET_HEROKU` | OAuth client secret for Heroku integration | `None` | +| `OAUTH_TOKEN_URL_HEROKU` | OAuth token URL for Heroku integration | `None` | +| `SENTRY_DSN` | DSN for error-monitoring with Sentry | `None` | diff --git a/frontend/Dockerfile.dev b/frontend/Dockerfile.dev index ae9776e888..2bae23823f 100644 --- a/frontend/Dockerfile.dev +++ b/frontend/Dockerfile.dev @@ -7,10 +7,9 @@ WORKDIR /app # Copy over dependency files COPY package.json ./ COPY package-lock.json ./ -COPY yarn.lock ./ # Install -RUN yarn install +RUN npm install # Copy over next.js config COPY next.config.js ./next.config.js @@ -18,4 +17,4 @@ COPY next.config.js ./next.config.js # Copy all files COPY . . -CMD ["yarn", "dev"] \ No newline at end of file +CMD ["npm", "run", "dev"] \ No newline at end of file diff --git a/frontend/Dockerfile.prod b/frontend/Dockerfile.prod index bd6d65a62f..d95c00883f 100644 --- a/frontend/Dockerfile.prod +++ b/frontend/Dockerfile.prod @@ -7,7 +7,6 @@ WORKDIR /app # Copy over dependency files COPY package.json ./ COPY package-lock.json ./ -COPY yarn.lock ./ # Install RUN npm install