diff --git a/plane/README.md b/plane/README.md index 86611bc..ce423fb 100644 --- a/plane/README.md +++ b/plane/README.md @@ -1,4 +1,42 @@ -# Plane +# Plane - Project Management Script -- copied from https://github.com/makeplane/plane -- removed `ports` +This directory contains the Plane project management tool deployment for Easypanel. + +## Update Process + +To update Plane to the latest version, follow these steps in order: + +### Step 1: Run the Setup Script for Upgrade + +First, run the `setup.sh` script and choose the upgrade option: + +``` +./setup.sh +``` + +When prompted, select option **5** for "Upgrade". This will: + +* Check for the latest available release +* Download the latest stable version + +### Step 2: Run the Update Script + +After the setup script completes successfully, run the `update.js` script: + +``` +node update.js +``` + +This script will: + +* Removes the existing code directory and changes the name for the newly fetched directory to code.  +* Rename `plane.env` to `.env.example` +* Rename `docker-compose.yaml` to `docker-compose.yml` +* Remove container names and ports from docker-compose.yml +* Update environment variables to use Easypanel's `PRIMARY_DOMAIN` variable + +## Important Notes + +* **Always run setup.sh first** - This ensures you get the latest official Plane release +* **Then run update.js** - This applies Easypanel-specific customizations +* The update process will preserve your existing data and configuration \ No newline at end of file diff --git a/plane/code/.env.example b/plane/code/.env.example index 78031a4..fd92cb4 100644 --- a/plane/code/.env.example +++ b/plane/code/.env.example @@ -1,5 +1,6 @@ -APP_DOMAIN=localhost -APP_RELEASE=stable +APP_DOMAIN=$(PRIMARY_DOMAIN) +APP_RELEASE=v0.28.0 +SSL=false WEB_REPLICAS=1 SPACE_REPLICAS=1 @@ -9,10 +10,12 @@ WORKER_REPLICAS=1 BEAT_WORKER_REPLICAS=1 LIVE_REPLICAS=1 -NGINX_PORT=80 -WEB_URL=http://${APP_DOMAIN} +LISTEN_HTTP_PORT=80 +LISTEN_HTTPS_PORT=443 + +WEB_URL=https://$(PRIMARY_DOMAIN) DEBUG=0 -CORS_ALLOWED_ORIGINS=http://${APP_DOMAIN} +CORS_ALLOWED_ORIGINS=https://$(PRIMARY_DOMAIN) API_BASE_URL=http://api:8000 #DB SETTINGS @@ -38,6 +41,19 @@ RABBITMQ_PASSWORD=plane RABBITMQ_VHOST=plane AMQP_URL= +# If SSL Cert to be generated, set CERT_EMAIl="email " +CERT_ACME_CA=https://acme-v02.api.letsencrypt.org/directory +TRUSTED_PROXIES=0.0.0.0/0 +SITE_ADDRESS=:80 +CERT_EMAIL= + + + +# For DNS Challenge based certificate generation, set the CERT_ACME_DNS, CERT_EMAIL +# CERT_ACME_DNS="acme_dns " +CERT_ACME_DNS= + + # Secret Key SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5 @@ -61,3 +77,6 @@ MINIO_ENDPOINT_SSL=0 # API key rate limit API_KEY_RATE_LIMIT=60/minute +DOCKERHUB_USER=artifacts.plane.so/makeplane +PULL_POLICY=if_not_present +CUSTOM_BUILD=false diff --git a/plane/code/README.md b/plane/code/README.md deleted file mode 100644 index ba7af0e..0000000 --- a/plane/code/README.md +++ /dev/null @@ -1,630 +0,0 @@ -# Self Hosting - -In this guide, we will walk you through the process of setting up a self-hosted environment. Self-hosting allows you to have full control over your applications and data. It's a great way to ensure privacy, control, and customization. - -We will cover two main options for setting up your self-hosted environment: using a cloud server or using your desktop. For the cloud server, we will use an AWS EC2 instance. For the desktop, we will use Docker to create a local environment. - -Let's get started! - -## Setting up Docker Environment - -
- Option 1 - Using Cloud Server -

Best way to start is to create EC2 machine on AWS. It must have minimum of 2vCPU and 4GB RAM.

-

Run the below command to install docker engine.

- -`curl -fsSL https://get.docker.com | sh -` - -
- ---- - -
- Option 2 - Using Desktop - -#### For Mac - -
    -
  1. Download Docker Desktop for Mac from the Docker Hub.
  2. -
  3. Double-click the downloaded `.dmg` file and drag the Docker app icon to the Applications folder.
  4. -
  5. Open Docker Desktop from the Applications folder. You might be asked to provide your system password to install additional software.
  6. -
- -#### For Windows: - -
    -
  1. Download Docker Desktop for Windows from the Docker Hub.
  2. -
  3. Run the installer and follow the instructions. You might be asked to enable Hyper-V and "Containers" Windows features.
  4. -
  5. Open Docker Desktop. You might be asked to log out and log back in, or restart your machine, for changes to take effect.
  6. -
- -After installation, you can verify the installation by opening a terminal (Command Prompt on Windows, Terminal app on Mac) and running the command `docker --version`. This should display the installed version of Docker. - -
- ---- - -## Installing Plane - -Installing plane is a very easy and minimal step process. - -### Prerequisite - -- Docker installed and running -- OS with bash scripting enabled (Ubuntu, Linux AMI, macos). Windows systems need to have [gitbash](https://git-scm.com/download/win) -- User context used must have access to docker services. In most cases, use sudo su to switch as root user -- Use the terminal (or gitbash) window to run all the future steps - -### Downloading Latest Release - -``` -mkdir plane-selfhost - -cd plane-selfhost -``` - -#### For *Docker Compose* based setup - -``` -curl -fsSL -o setup.sh https://github.com/makeplane/plane/releases/latest/download/setup.sh - -chmod +x setup.sh -``` - -#### For *Docker Swarm* based setup - -``` -curl -fsSL -o setup.sh https://github.com/makeplane/plane/releases/latest/download/swarm.sh - -chmod +x setup.sh -``` - ---- - -### Proceed with setup - -Above steps will set you ready to install and start plane services. - -Lets get started by running the `./setup.sh` command. - -This will prompt you with the below options. - -#### Docker Compose -```bash -Select an Action you want to perform: - 1) Install (x86_64) - 2) Start - 3) Stop - 4) Restart - 5) Upgrade - 6) View Logs - 7) Backup Data - 8) Exit - -Action [2]: 1 -``` - -For the 1st time setup, type "1" as action input. - -This will create a folder `plane-app` and will download 2 files inside that - -- `docker-compose.yaml` -- `plane.env` - -Again the `options [1-8]` will be popped up, and this time hit `8` to exit. - -#### Docker Swarm - -```bash -Select an Action you want to perform: - 1) Deploy Stack - 2) Remove Stack - 3) View Stack Status - 4) Redeploy Stack - 5) Upgrade - 6) View Logs - 7) Exit - -Action [3]: 1 -``` - -For the 1st time setup, type "1" as action input. - -This will create a create a folder `plane-app` and will download 2 files inside that - -- `docker-compose.yaml` -- `plane.env` - -Again the `options [1-7]` will be popped up, and this time hit `7` to exit. - ---- - -### Continue with setup - Environment Settings - -Before proceeding, we suggest used to review `.env` file and set the values. -Below are the most import keys you must refer to. _You can use any text editor to edit this file_. - -> `NGINX_PORT` - This is default set to `80`. Make sure the port you choose to use is not preoccupied. (e.g `NGINX_PORT=8080`) - -> `WEB_URL` - This is default set to `http://localhost`. Change this to the FQDN you plan to use along with NGINX_PORT (eg. `https://plane.example.com:8080` or `http://[IP-ADDRESS]:8080`) - -> `CORS_ALLOWED_ORIGINS` - This is default set to `http://localhost`. Change this to the FQDN you plan to use along with NGINX_PORT (eg. `https://plane.example.com:8080` or `http://[IP-ADDRESS]:8080`) - -There are many other settings you can play with, but we suggest you configure `EMAIL SETTINGS` as it will enable you to invite your teammates onto the platform. - ---- - -### Continue with setup - Start Server (Docker Compose) - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `2` to start the sevices - -```bash -Select a Action you want to perform: - 1) Install (x86_64) - 2) Start - 3) Stop - 4) Restart - 5) Upgrade - 6) View Logs - 7) Backup Data - 8) Exit - -Action [2]: 2 -``` - -Expect something like this. -![Downloading docker images](images/download.png) - -Be patient as it might take sometime based on download speed and system configuration. If all goes well, you must see something like this - -![Downloading completed](images/started.png) - -This is the confirmation that all images were downloaded and the services are up & running. - -You have successfully self hosted `Plane` instance. Access the application by going to IP or domain you have configured it (e.g `https://plane.example.com:8080` or `http://[IP-ADDRESS]:8080`) - ---- - -### Stopping the Server / Remove Stack - -In case you want to make changes to `plane.env` variables, we suggest you to stop the services before doing that. - -#### Docker Compose - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `3` to stop the sevices - -```bash -Select a Action you want to perform: - 1) Install (x86_64) - 2) Start - 3) Stop - 4) Restart - 5) Upgrade - 6) View Logs - 7) Backup Data - 8) Exit - -Action [2]: 3 -``` - -If all goes well, you must see something like this - -![Stop Services](images/stopped.png) - -#### Docker Swarm - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `2` to stop the sevices - -```bash -Select an Action you want to perform: - 1) Deploy Stack - 2) Remove Stack - 3) View Stack Status - 4) Redeploy Stack - 5) Upgrade - 6) View Logs - 7) Exit - -Action [3]: 2 -``` - -If all goes well, you will see the confirmation from docker cli - ---- - -### Restarting the Server / Redeploy Stack - -In case you want to make changes to `plane.env` variables, without stopping the server or you noticed some abnormalies in services, you can restart the services with `RESTART` / `REDEPLOY` option. - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `4` to restart the sevices - -#### Docker Compose -```bash -Select a Action you want to perform: - 1) Install (x86_64) - 2) Start - 3) Stop - 4) Restart - 5) Upgrade - 6) View Logs - 7) Backup Data - 8) Exit - -Action [2]: 4 -``` - -If all goes well, you must see something like this - -![Restart Services](images/restart.png) - -#### Docker Swarm - -```bash - 1) Deploy Stack - 2) Remove Stack - 3) View Stack Status - 4) Redeploy Stack - 5) Upgrade - 6) View Logs - 7) Exit - -Action [3]: 4 -``` - -If all goes well, you will see the confirmation from docker cli - ---- - -### Upgrading Plane Version - -It is always advised to keep Plane up to date with the latest release. - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `5` to upgrade the release. - -#### Docker Compose - -```bash -Select a Action you want to perform: - 1) Install (x86_64) - 2) Start - 3) Stop - 4) Restart - 5) Upgrade - 6) View Logs - 7) Backup Data - 8) Exit - -Action [2]: 5 -``` - -By choosing this, it will stop the services and then will download the latest `docker-compose.yaml` and `plane.env`. - -You must expect the below message - -![Alt text](images/upgrade.png) - -Once done, choose `8` to exit from prompt. - -> It is very important for you to validate the `plane.env` for the new changes. - -Once done with making changes in `plane.env` file, jump on to `Start Server` - -#### Docker Swarm - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `5` to upgrade the release. - -```bash - 1) Deploy Stack - 2) Remove Stack - 3) View Stack Status - 4) Redeploy Stack - 5) Upgrade - 6) View Logs - 7) Exit - -Action [3]: 5 -``` - -By choosing this, it will stop the services and then will download the latest `docker-compose.yaml` and `plane.env`. - -Once done, choose `7` to exit from prompt. - -> It is very important for you to validate the `plane.env` for the new changes. - -Once done with making changes in `plane.env` file, jump on to `Redeploy Stack` - ---- - -### View Logs - -There would a time when you might want to check what is happening inside the API, Worker or any other container. - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. - -This time select `6` to view logs. - -#### Docker Compose - -```bash -Select a Action you want to perform: - 1) Install (x86_64) - 2) Start - 3) Stop - 4) Restart - 5) Upgrade - 6) View Logs - 7) Backup Data - 8) Exit - -Action [2]: 6 -``` - -#### Docker Swarm - - -```bash - 1) Deploy Stack - 2) Remove Stack - 3) View Stack Status - 4) Redeploy Stack - 5) Upgrade - 6) View Logs - 7) Exit - -Action [3]: 6 -``` - -#### Service Menu Options for Logs -This will further open sub-menu with list of services -```bash -Select a Service you want to view the logs for: - 1) Web - 2) Space - 3) API - 4) Worker - 5) Beat-Worker - 6) Migrator - 7) Proxy - 8) Redis - 9) Postgres - 10) Minio - 11) RabbitMQ - 0) Back to Main Menu - -Service: 3 -``` - -Select any of the service to view the logs e.g. `3`. Expect something similar to this -```bash -api-1 | Waiting for database... -api-1 | Database available! -api-1 | Waiting for database migrations to complete... -api-1 | Waiting for database migrations to complete... -api-1 | Waiting for database migrations to complete... -api-1 | Waiting for database migrations to complete... -api-1 | Waiting for database migrations to complete... -api-1 | Waiting for database migrations to complete... -api-1 | Waiting for database migrations to complete... -api-1 | No migrations Pending. Starting processes ... -api-1 | Instance registered -api-1 | ENABLE_SIGNUP loaded with value from environment variable. -api-1 | ENABLE_EMAIL_PASSWORD loaded with value from environment variable. -api-1 | ENABLE_MAGIC_LINK_LOGIN loaded with value from environment variable. -api-1 | GOOGLE_CLIENT_ID loaded with value from environment variable. -api-1 | GITHUB_CLIENT_ID loaded with value from environment variable. -api-1 | GITHUB_CLIENT_SECRET loaded with value from environment variable. -api-1 | EMAIL_HOST loaded with value from environment variable. -api-1 | EMAIL_HOST_USER loaded with value from environment variable. -api-1 | EMAIL_HOST_PASSWORD loaded with value from environment variable. -api-1 | EMAIL_PORT loaded with value from environment variable. -api-1 | EMAIL_FROM loaded with value from environment variable. -api-1 | EMAIL_USE_TLS loaded with value from environment variable. -api-1 | EMAIL_USE_SSL loaded with value from environment variable. -api-1 | OPENAI_API_KEY loaded with value from environment variable. -api-1 | GPT_ENGINE loaded with value from environment variable. -api-1 | UNSPLASH_ACCESS_KEY loaded with value from environment variable. -api-1 | Checking bucket... -api-1 | Bucket 'uploads' does not exist. Creating bucket... -api-1 | Bucket 'uploads' created successfully. -api-1 | Public read access policy set for bucket 'uploads'. -api-1 | Cache Cleared -api-1 | [2024-05-02 03:56:01 +0000] [1] [INFO] Starting gunicorn 21.2.0 -api-1 | [2024-05-02 03:56:01 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) -api-1 | [2024-05-02 03:56:01 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker -api-1 | [2024-05-02 03:56:01 +0000] [25] [INFO] Booting worker with pid: 25 -api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] Started server process [25] -api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] Waiting for application startup. -api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] ASGI 'lifespan' protocol appears unsupported. -api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] Application startup complete. - -``` - -To exit this, use `CTRL+C` and then you will land on to the main-menu with the list of actions. - -Similarly, you can view the logs of other services. - ---- - -### Backup Data (Docker Compose) - -There would a time when you might want to backup your data from docker volumes to external storage like S3 or drives. - -Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `7` to Backup the data. - -```bash -Select a Action you want to perform: - 1) Install (x86_64) - 2) Start - 3) Stop - 4) Restart - 5) Upgrade - 6) View Logs - 7) Backup Data - 8) Exit - -Action [2]: 7 -``` - -In response, you can find the backup folder - -```bash -Backing Up plane-app_pgdata -Backing Up plane-app_redisdata -Backing Up plane-app_uploads - -Backup completed successfully. Backup files are stored in /....../plane-app/backup/20240502-1120 -``` - ---- - -### Restore Data (Docker Compose) - -When you want to restore the previously backed-up data, follow the instructions below. - -1. Make sure that Plane-CE is installed, started, and then stopped. This ensures that the Docker volumes are created. - -1. Download the restore script using the command below. We suggest downloading it in the same folder as `setup.sh`. - - ```bash - curl -fsSL -o restore.sh https://github.com/makeplane/plane/releases/latest/download/restore.sh - chmod +x restore.sh - ``` - -1. Execute the command below to restore your data. - - ```bash - ./restore.sh - ``` - - As an example, for a backup folder `/opt/plane-selfhost/plane-app/backup/20240722-0914`, expect the response below: - - ```bash - -------------------------------------------- - ____ _ ///////// - | _ \| | __ _ _ __ ___ ///////// - | |_) | |/ _` | '_ \ / _ \ ///// ///// - | __/| | (_| | | | | __/ ///// ///// - |_| |_|\__,_|_| |_|\___| //// - //// - -------------------------------------------- - Project management tool from the future - -------------------------------------------- - Found /opt/plane-selfhost/plane-app/backup/20240722-0914/pgdata.tar.gz - .....Restoring plane-app_pgdata - .....Successfully restored volume plane-app_pgdata from pgdata.tar.gz - - Found /opt/plane-selfhost/plane-app/backup/20240722-0914/redisdata.tar.gz - .....Restoring plane-app_redisdata - .....Successfully restored volume plane-app_redisdata from redisdata.tar.gz - - Found /opt/plane-selfhost/plane-app/backup/20240722-0914/uploads.tar.gz - .....Restoring plane-app_uploads - .....Successfully restored volume plane-app_uploads from uploads.tar.gz - - - Restore completed successfully. - ``` - -1. Start the Plane instance using `./setup.sh start`. - ---- - -### Restore for Commercial Air-Gapped (Docker Compose) - -When you want to restore the previously backed-up data on Plane Commercial Air-Gapped version, follow the instructions below. - -1. Download the restore script using the command below - - ```bash - curl -fsSL -o restore-airgapped.sh https://github.com/makeplane/plane/releases/latest/download/restore-airgapped.sh - chmod +x restore-airgapped.sh - ``` - -1. Copy the backup folder and the `restore-airgapped.sh` to `Commercial Airgapped Edition` server - -1. Make sure that Plane Commercial (Airgapped) is extracted and ready to get started. In case it is running, you would need to stop that. - -1. Execute the command below to restore your data. - - ```bash - ./restore-airgapped.sh - ``` - -1. After restoration, you are ready to start Plane Commercial (Airgapped) will all your previously saved data. - ---- - -
-

Upgrading from v0.13.2 to v0.14.x

- -This is one time activity for users who are upgrading from v0.13.2 to v0.14.0 - -As there has been significant changes to Self Hosting process, this step mainly covers the data migration from current (v0.13.2) docker volumes from newly created volumes - -> Before we begin with migration, make sure your v0.14.0 was started and then stopped. This is required to know the newly created docker volume names. - -Begin with downloading the migration script using below command - -``` - -curl -fsSL -o migrate.sh https://raw.githubusercontent.com/makeplane/plane/master/deploy/selfhost/migration-0.13-0.14.sh - -chmod +x migrate.sh - -``` - -Now run the `./migrate.sh` command and expect the instructions as below - -``` -****************************************************************** - -This script is solely for the migration purpose only. -This is a 1 time migration of volume data from v0.13.2 => v0.14.x - -Assumption: -1. Postgres data volume name ends with _pgdata -2. Minio data volume name ends with _uploads -3. Redis data volume name ends with _redisdata - -Any changes to this script can break the migration. - -Before you proceed, make sure you run the below command -to know the docker volumes - -docker volume ls -q | grep -i "_pgdata" -docker volume ls -q | grep -i "_uploads" -docker volume ls -q | grep -i "_redisdata" - -******************************************************* - -Given below list of REDIS volumes, identify the prefix of source and destination volumes leaving "_redisdata" ---------------------- -plane-app_redisdata -v0132_redisdata - -Provide the Source Volume Prefix : -``` - -**Open another terminal window**, and run the mentioned 3 command. This may be different for users who have changed the volume names in their previous setup (v0.13.2) - -For every command you must see 2 records something like shown in above example of `redisdata` - -To move forward, you would need PREFIX of old setup and new setup. As per above example, `v0132` is the prefix of v0.13.2 and `plane-app` is the prefix of v0.14.0 setup - -**Back to original terminal window**, _Provide the Source Volume Prefix_ and hit ENTER. - -Now you will be prompted to _Provide Destination Volume Prefix_. Provide the value and hit ENTER - -``` -Provide the Source Volume Prefix : v0132 -Provide the Destination Volume Prefix : plane-app -``` - -In case the suffixes are wrong or the mentioned volumes are not found, you will receive the error shown below. The image below displays an error for source volumes. - -![Migrate Error](images/migrate-error.png) - -In case of successful migration, it will be a silent exit without error. - -Now its time to restart v0.14.0 setup. -
\ No newline at end of file diff --git a/plane/code/build.yml b/plane/code/build.yml deleted file mode 100644 index b65d297..0000000 --- a/plane/code/build.yml +++ /dev/null @@ -1,30 +0,0 @@ -services: - web: - image: ${DOCKERHUB_USER:-local}/plane-frontend:${APP_RELEASE:-latest} - build: - context: . - dockerfile: ./web/Dockerfile.web - - space: - image: ${DOCKERHUB_USER:-local}/plane-space:${APP_RELEASE:-latest} - build: - context: ./ - dockerfile: ./space/Dockerfile.space - - admin: - image: ${DOCKERHUB_USER:-local}/plane-admin:${APP_RELEASE:-latest} - build: - context: ./ - dockerfile: ./admin/Dockerfile.admin - - api: - image: ${DOCKERHUB_USER:-local}/plane-backend:${APP_RELEASE:-latest} - build: - context: ./apiserver - dockerfile: ./Dockerfile.api - - proxy: - image: ${DOCKERHUB_USER:-local}/plane-proxy:${APP_RELEASE:-latest} - build: - context: ./nginx - dockerfile: ./Dockerfile diff --git a/plane/code/docker-compose.yml b/plane/code/docker-compose.yml index 65fb84e..284b80e 100644 --- a/plane/code/docker-compose.yml +++ b/plane/code/docker-compose.yml @@ -24,9 +24,16 @@ x-aws-s3-env: &aws-s3-env AWS_S3_BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads} x-proxy-env: &proxy-env - NGINX_PORT: ${NGINX_PORT:-80} - BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads} + SSL: ${SSL:-false} + APP_DOMAIN: ${APP_DOMAIN:-localhost} FILE_SIZE_LIMIT: ${FILE_SIZE_LIMIT:-5242880} + CERT_EMAIL: ${CERT_EMAIL} + CERT_ACME_CA: ${CERT_ACME_CA} + CERT_ACME_DNS: ${CERT_ACME_DNS} + LISTEN_HTTP_PORT: ${LISTEN_HTTP_PORT:-80} + LISTEN_HTTPS_PORT: ${LISTEN_HTTPS_PORT:-443} + BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads} + SITE_ADDRESS: ${SITE_ADDRESS:-:80} x-mq-env: # RabbitMQ Settings @@ -55,8 +62,7 @@ x-app-env: &app-env services: web: - image: artifacts.plane.so/makeplane/plane-frontend:${APP_RELEASE:-stable} - command: node web/server.js web + image: artifacts.plane.so/makeplane/plane-frontend:${APP_RELEASE:-v0.28.0} deploy: replicas: ${WEB_REPLICAS:-1} restart_policy: @@ -66,8 +72,7 @@ services: - worker space: - image: artifacts.plane.so/makeplane/plane-space:${APP_RELEASE:-stable} - command: node space/server.js space + image: artifacts.plane.so/makeplane/plane-space:${APP_RELEASE:-v0.28.0} deploy: replicas: ${SPACE_REPLICAS:-1} restart_policy: @@ -78,8 +83,7 @@ services: - web admin: - image: artifacts.plane.so/makeplane/plane-admin:${APP_RELEASE:-stable} - command: node admin/server.js admin + image: artifacts.plane.so/makeplane/plane-admin:${APP_RELEASE:-v0.28.0} deploy: replicas: ${ADMIN_REPLICAS:-1} restart_policy: @@ -89,8 +93,7 @@ services: - web live: - image: artifacts.plane.so/makeplane/plane-live:${APP_RELEASE:-stable} - command: node live/dist/server.js live + image: artifacts.plane.so/makeplane/plane-live:${APP_RELEASE:-v0.28.0} environment: <<: [ *live-env ] deploy: @@ -102,7 +105,7 @@ services: - web api: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} + image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0} command: ./bin/docker-entrypoint-api.sh deploy: replicas: ${API_REPLICAS:-1} @@ -118,7 +121,7 @@ services: - plane-mq worker: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} + image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0} command: ./bin/docker-entrypoint-worker.sh deploy: replicas: ${WORKER_REPLICAS:-1} @@ -135,7 +138,7 @@ services: - plane-mq beat-worker: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} + image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0} command: ./bin/docker-entrypoint-beat.sh deploy: replicas: ${BEAT_WORKER_REPLICAS:-1} @@ -152,7 +155,7 @@ services: - plane-mq migrator: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} + image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0} command: ./bin/docker-entrypoint-migrator.sh deploy: replicas: 1 @@ -214,17 +217,31 @@ services: # Comment this if you already have a reverse proxy running proxy: - image: artifacts.plane.so/makeplane/plane-proxy:${APP_RELEASE:-stable} - environment: - <<: *proxy-env + image: artifacts.plane.so/makeplane/plane-proxy:${APP_RELEASE:-v0.28.0} + command: + [ + "caddy", + "run", + "--config", + "/etc/caddy/Caddyfile", + "--adapter", + "caddyfile" + ] deploy: replicas: 1 restart_policy: condition: on-failure + environment: + <<: *proxy-env + volumes: + - proxy_config:/config + - proxy_data:/data depends_on: - web - api - space + - admin + - live volumes: pgdata: @@ -235,3 +252,5 @@ volumes: logs_beat-worker: logs_migrator: rabbitmq_data: + proxy_config: + proxy_data: diff --git a/plane/code/images/download.png b/plane/code/images/download.png deleted file mode 100644 index bb0d118..0000000 Binary files a/plane/code/images/download.png and /dev/null differ diff --git a/plane/code/images/migrate-error.png b/plane/code/images/migrate-error.png deleted file mode 100644 index f42ec44..0000000 Binary files a/plane/code/images/migrate-error.png and /dev/null differ diff --git a/plane/code/images/restart.png b/plane/code/images/restart.png deleted file mode 100644 index 0387599..0000000 Binary files a/plane/code/images/restart.png and /dev/null differ diff --git a/plane/code/images/started.png b/plane/code/images/started.png deleted file mode 100644 index d6a0a0b..0000000 Binary files a/plane/code/images/started.png and /dev/null differ diff --git a/plane/code/images/stopped.png b/plane/code/images/stopped.png deleted file mode 100644 index 0f58768..0000000 Binary files a/plane/code/images/stopped.png and /dev/null differ diff --git a/plane/code/images/upgrade.png b/plane/code/images/upgrade.png deleted file mode 100644 index b78fbbb..0000000 Binary files a/plane/code/images/upgrade.png and /dev/null differ diff --git a/plane/code/migration-0.13-0.14.sh b/plane/code/migration-0.13-0.14.sh deleted file mode 100755 index d03f877..0000000 --- a/plane/code/migration-0.13-0.14.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash - -echo ' -****************************************************************** - -This script is solely for the migration purpose only. -This is a 1 time migration of volume data from v0.13.2 => v0.14.x - -Assumption: -1. Postgres data volume name ends with _pgdata -2. Minio data volume name ends with _uploads -3. Redis data volume name ends with _redisdata - -Any changes to this script can break the migration. - -Before you proceed, make sure you run the below command -to know the docker volumes - -docker volume ls -q | grep -i "_pgdata" -docker volume ls -q | grep -i "_uploads" -docker volume ls -q | grep -i "_redisdata" - -******************************************************* -' - -DOWNLOAD_FOL=./download -rm -rf ${DOWNLOAD_FOL} -mkdir -p ${DOWNLOAD_FOL} - -function volumeExists { - if [ "$(docker volume ls -f name=$1 | awk '{print $NF}' | grep -E '^'$1'$')" ]; then - return 0 - else - return 1 - fi -} - -function readPrefixes(){ - echo '' - echo 'Given below list of REDIS volumes, identify the prefix of source and destination volumes leaving "_redisdata" ' - echo '---------------------' - docker volume ls -q | grep -i "_redisdata" - echo '' - - read -p "Provide the Source Volume Prefix : " SRC_VOL_PREFIX - until [ "$SRC_VOL_PREFIX" ]; do - read -p "Provide the Source Volume Prefix : " SRC_VOL_PREFIX - done - - read -p "Provide the Destination Volume Prefix : " DEST_VOL_PREFIX - until [ "$DEST_VOL_PREFIX" ]; do - read -p "Provide the Source Volume Prefix : " DEST_VOL_PREFIX - done - - echo '' - echo 'Prefix Provided ' - echo " Source : ${SRC_VOL_PREFIX}" - echo " Destination : ${DEST_VOL_PREFIX}" - echo '---------------------------------------' -} - -function migrate(){ - - SRC_VOLUME=${SRC_VOL_PREFIX}_${VOL_NAME_SUFFIX} - DEST_VOLUME=${DEST_VOL_PREFIX}_${VOL_NAME_SUFFIX} - - if volumeExists $SRC_VOLUME; then - if volumeExists $DEST_VOLUME; then - GOOD_TO_GO=1 - else - echo "Destination Volume '$DEST_VOLUME' does not exist" - echo '' - fi - else - echo "Source Volume '$SRC_VOLUME' does not exist" - echo '' - fi - - if [ $GOOD_TO_GO = 1 ]; then - - echo "MIGRATING ${VOL_NAME_SUFFIX} FROM ${SRC_VOLUME} => ${DEST_VOLUME}" - - TEMP_CONTAINER=$(docker run -d -v $SRC_VOLUME:$CONTAINER_VOL_FOLDER busybox true) - docker cp -q $TEMP_CONTAINER:$CONTAINER_VOL_FOLDER ${DOWNLOAD_FOL}/${VOL_NAME_SUFFIX} - docker rm $TEMP_CONTAINER &> /dev/null - - TEMP_CONTAINER=$(docker run -d -v $DEST_VOLUME:$CONTAINER_VOL_FOLDER busybox true) - if [ "$VOL_NAME_SUFFIX" = "pgdata" ]; then - docker cp -q ${DOWNLOAD_FOL}/${VOL_NAME_SUFFIX} $TEMP_CONTAINER:$CONTAINER_VOL_FOLDER/_temp - docker run --rm -v $DEST_VOLUME:$CONTAINER_VOL_FOLDER \ - -e DATA_FOLDER="${CONTAINER_VOL_FOLDER}" \ - busybox /bin/sh -c 'cp -Rf $DATA_FOLDER/_temp/* $DATA_FOLDER ' - else - docker cp -q ${DOWNLOAD_FOL}/${VOL_NAME_SUFFIX} $TEMP_CONTAINER:$CONTAINER_VOL_FOLDER - fi - docker rm $TEMP_CONTAINER &> /dev/null - - echo '' - fi -} - -readPrefixes - -# MIGRATE DB -CONTAINER_VOL_FOLDER=/var/lib/postgresql/data -VOL_NAME_SUFFIX=pgdata -migrate - -# MIGRATE REDIS -CONTAINER_VOL_FOLDER=/data -VOL_NAME_SUFFIX=redisdata -migrate - -# MIGRATE MINIO -CONTAINER_VOL_FOLDER=/export -VOL_NAME_SUFFIX=uploads -migrate - diff --git a/plane/code/restore-airgapped.sh b/plane/code/restore-airgapped.sh deleted file mode 100755 index 9da02fd..0000000 --- a/plane/code/restore-airgapped.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash -+set -euo pipefail - -function print_header() { -clear - -cat <<"EOF" --------------------------------------------- - ____ _ ///////// -| _ \| | __ _ _ __ ___ ///////// -| |_) | |/ _` | '_ \ / _ \ ///// ///// -| __/| | (_| | | | | __/ ///// ///// -|_| |_|\__,_|_| |_|\___| //// - //// --------------------------------------------- -Project management tool from the future --------------------------------------------- -EOF -} - -function restoreData() { - - echo "" - echo "****************************************************" - echo "We are about to restore your data from the backup files." - echo "****************************************************" - echo "" - - # set the backup folder path - BACKUP_FOLDER=${1} - - if [ -z "$BACKUP_FOLDER" ]; then - BACKUP_FOLDER="$PWD/backup" - read -p "Enter the backup folder path [$BACKUP_FOLDER]: " BACKUP_FOLDER - if [ -z "$BACKUP_FOLDER" ]; then - BACKUP_FOLDER="$PWD/backup" - fi - fi - - # check if the backup folder exists - if [ ! -d "$BACKUP_FOLDER" ]; then - echo "Error: Backup folder not found at $BACKUP_FOLDER" - exit 1 - fi - - # check if there are any .tar.gz files in the backup folder - if ! ls "$BACKUP_FOLDER"/*.tar.gz 1> /dev/null 2>&1; then - echo "Error: Backup folder does not contain .tar.gz files" - exit 1 - fi - - echo "" - echo "Using backup folder: $BACKUP_FOLDER" - echo "" - - # ask for current install path - AIRGAPPED_INSTALL_PATH="$HOME/planeairgapped" - read -p "Enter the airgapped instance install path [$AIRGAPPED_INSTALL_PATH]: " AIRGAPPED_INSTALL_PATH - if [ -z "$AIRGAPPED_INSTALL_PATH" ]; then - AIRGAPPED_INSTALL_PATH="$HOME/planeairgapped" - fi - - # check if the airgapped instance install path exists - if [ ! -d "$AIRGAPPED_INSTALL_PATH" ]; then - echo "Error: Airgapped instance install path not found at $AIRGAPPED_INSTALL_PATH" - exit 1 - fi - - echo "" - echo "Using airgapped instance install path: $AIRGAPPED_INSTALL_PATH" - echo "" - - # check if the docker-compose.yaml exists - if [ ! -f "$AIRGAPPED_INSTALL_PATH/docker-compose.yml" ]; then - echo "Error: docker-compose.yml not found at $AIRGAPPED_INSTALL_PATH/docker-compose.yml" - exit 1 - fi - - local dockerServiceStatus - if command -v jq &> /dev/null; then - dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped --format=json | jq -r .[0].Status) - else - dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped | grep -o "running" | head -n 1) - fi - - if [[ $dockerServiceStatus == "running" ]]; then - echo "Plane Airgapped is running. Please STOP the Plane Airgapped before restoring data." - exit 1 - fi - - CURRENT_USER_ID=$(id -u) - CURRENT_GROUP_ID=$(id -g) - - # if the data folder not exists, create it - if [ ! -d "$AIRGAPPED_INSTALL_PATH/data" ]; then - mkdir -p "$AIRGAPPED_INSTALL_PATH/data" - chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$AIRGAPPED_INSTALL_PATH/data" - fi - - for BACKUP_FILE in "$BACKUP_FOLDER/*.tar.gz"; do - if [ -e "$BACKUP_FILE" ]; then - - # get the basefilename without the extension - BASE_FILE_NAME=$(basename "$BACKUP_FILE" ".tar.gz") - - # extract the restoreFile to the airgapped instance install path - echo "Restoring $BASE_FILE_NAME" - rm -rf "$AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME" || true - - tar -xvzf "$BACKUP_FILE" -C "$AIRGAPPED_INSTALL_PATH/data/" - if [ $? -ne 0 ]; then - echo "Error: Failed to extract $BACKUP_FILE" - exit 1 - fi - chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME" - if [ $? -ne 0 ]; then - echo "Error: Failed to change ownership of $AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME" - exit 1 - fi - else - echo "No .tar.gz files found in the current directory." - echo "" - echo "Please provide the path to the backup file." - echo "" - echo "Usage: $0 /path/to/backup" - exit 1 - fi - done - - echo "" - echo "Restore completed successfully." - echo "" -} - -# if docker-compose is installed -if command -v docker-compose &> /dev/null -then - COMPOSE_CMD="docker-compose" -else - COMPOSE_CMD="docker compose" -fi - -print_header -restoreData "$@" diff --git a/plane/code/restore.sh b/plane/code/restore.sh deleted file mode 100755 index 23b8de6..0000000 --- a/plane/code/restore.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/bash - -function print_header() { -clear - -cat <<"EOF" --------------------------------------------- - ____ _ ///////// -| _ \| | __ _ _ __ ___ ///////// -| |_) | |/ _` | '_ \ / _ \ ///// ///// -| __/| | (_| | | | | __/ ///// ///// -|_| |_|\__,_|_| |_|\___| //// - //// --------------------------------------------- -Project management tool from the future --------------------------------------------- -EOF -} - -function restoreSingleVolume() { - selectedVolume=$1 - backupFolder=$2 - restoreFile=$3 - - docker volume rm "$selectedVolume" > /dev/null 2>&1 - - if [ $? -ne 0 ]; then - echo "Error: Failed to remove volume $selectedVolume" - echo "" - return 1 - fi - - docker volume create "$selectedVolume" > /dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "Error: Failed to create volume $selectedVolume" - echo "" - return 1 - fi - - docker run --rm \ - -e TAR_NAME="$restoreFile" \ - -v "$selectedVolume":"/vol" \ - -v "$backupFolder":/backup \ - busybox sh -c 'mkdir -p /restore && tar -xzf "/backup/${TAR_NAME}.tar.gz" -C /restore && mv /restore/${TAR_NAME}/* /vol' - - if [ $? -ne 0 ]; then - echo "Error: Failed to restore volume ${selectedVolume} from ${restoreFile}.tar.gz" - echo "" - return 1 - fi - echo ".....Successfully restored volume $selectedVolume from ${restoreFile}.tar.gz" - echo "" -} - -function restoreData() { - print_header - local BACKUP_FOLDER=${1:-$PWD} - - local dockerServiceStatus - dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-app --format=json | jq -r .[0].Status) - local dockerServicePrefix - dockerServicePrefix="running" - - if [[ $dockerServiceStatus == $dockerServicePrefix* ]]; then - echo "Plane App is running. Please STOP the Plane App before restoring data." - exit 1 - fi - - local volume_suffix - volume_suffix="_pgdata|_redisdata|_uploads|_rabbitmq_data" - local volumes - volumes=$(docker volume ls -f "name=plane-app" --format "{{.Name}}" | grep -E "$volume_suffix") - # Check if there are any matching volumes - if [ -z "$volumes" ]; then - echo ".....No volumes found starting with 'plane-app'" - exit 1 - fi - - - for BACKUP_FILE in $BACKUP_FOLDER/*.tar.gz; do - if [ -e "$BACKUP_FILE" ]; then - - local restoreFileName - restoreFileName=$(basename "$BACKUP_FILE") - restoreFileName="${restoreFileName%.tar.gz}" - - local restoreVolName - restoreVolName="plane-app_${restoreFileName}" - echo "Found $BACKUP_FILE" - - local docVol - docVol=$(docker volume ls -f "name=$restoreVolName" --format "{{.Name}}" | grep -E "$volume_suffix") - - if [ -z "$docVol" ]; then - echo "Skipping: No volume found with name $restoreVolName" - else - echo ".....Restoring $docVol" - restoreSingleVolume "$docVol" "$BACKUP_FOLDER" "$restoreFileName" - fi - else - echo "No .tar.gz files found in the current directory." - echo "" - echo "Please provide the path to the backup file." - echo "" - echo "Usage: ./restore.sh /path/to/backup" - exit 1 - fi - done - - echo "" - echo "Restore completed successfully." - echo "" -} - -# if docker-compose is installed -if command -v docker-compose &> /dev/null -then - COMPOSE_CMD="docker-compose" -else - COMPOSE_CMD="docker compose" -fi - -restoreData "$@" \ No newline at end of file diff --git a/plane/code/swarm.sh b/plane/code/swarm.sh deleted file mode 100755 index c58f05e..0000000 --- a/plane/code/swarm.sh +++ /dev/null @@ -1,612 +0,0 @@ -#!/bin/bash - -BRANCH=${BRANCH:-master} -SERVICE_FOLDER=plane-app -SCRIPT_DIR=$PWD -PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER -export APP_RELEASE="stable" -export DOCKERHUB_USER=artifacts.plane.so/makeplane - -export GH_REPO=makeplane/plane -export RELEASE_DOWNLOAD_URL="https://github.com/$GH_REPO/releases/download" -export FALLBACK_DOWNLOAD_URL="https://raw.githubusercontent.com/$GH_REPO/$BRANCH/deploy/selfhost" - -OS_NAME=$(uname) - -# Create necessary directories -mkdir -p $PLANE_INSTALL_DIR/archive - -DOCKER_FILE_PATH=$PLANE_INSTALL_DIR/docker-compose.yml -DOCKER_ENV_PATH=$PLANE_INSTALL_DIR/plane.env - -function print_header() { -clear - -cat <<"EOF" --------------------------------------------- - ____ _ ///////// -| _ \| | __ _ _ __ ___ ///////// -| |_) | |/ _` | '_ \ / _ \ ///// ///// -| __/| | (_| | | | | __/ ///// ///// -|_| |_|\__,_|_| |_|\___| //// - //// --------------------------------------------- -Project management tool from the future --------------------------------------------- -EOF -} - -function checkLatestRelease(){ - echo "Checking for the latest release..." >&2 - local latest_release=$(curl -s https://api.github.com/repos/$GH_REPO/releases/latest | grep -o '"tag_name": "[^"]*"' | sed 's/"tag_name": "//;s/"//g') - if [ -z "$latest_release" ]; then - echo "Failed to check for the latest release. Exiting..." >&2 - exit 1 - fi - - echo $latest_release -} - -# Function to read stack name from env file -function readStackName() { - if [ -f "$DOCKER_ENV_PATH" ]; then - local saved_stack_name=$(grep "^STACK_NAME=" "$DOCKER_ENV_PATH" | cut -d'=' -f2) - if [ -n "$saved_stack_name" ]; then - stack_name=$saved_stack_name - return 1 - fi - fi - return 0 -} - -# Function to get stack name (either from env or user input) -function getStackName() { - read -p "Enter stack name [plane]: " input_stack_name - if [ -z "$input_stack_name" ]; then - input_stack_name="plane" - fi - stack_name=$input_stack_name - updateEnvFile "STACK_NAME" "$stack_name" "$DOCKER_ENV_PATH" - echo "Using stack name: $stack_name" -} - -function syncEnvFile(){ - echo "Syncing environment variables..." >&2 - if [ -f "$PLANE_INSTALL_DIR/plane.env.bak" ]; then - # READ keys of plane.env and update the values from plane.env.bak - while IFS= read -r line - do - # ignore if the line is empty or starts with # - if [ -z "$line" ] || [[ $line == \#* ]]; then - continue - fi - key=$(echo "$line" | cut -d'=' -f1) - value=$(getEnvValue "$key" "$PLANE_INSTALL_DIR/plane.env.bak") - if [ -n "$value" ]; then - updateEnvFile "$key" "$value" "$DOCKER_ENV_PATH" - fi - done < "$DOCKER_ENV_PATH" - - value=$(getEnvValue "STACK_NAME" "$PLANE_INSTALL_DIR/plane.env.bak") - if [ -n "$value" ]; then - updateEnvFile "STACK_NAME" "$value" "$DOCKER_ENV_PATH" - fi - fi - echo "Environment variables synced successfully" >&2 - rm -f $PLANE_INSTALL_DIR/plane.env.bak -} - -function getEnvValue() { - local key=$1 - local file=$2 - - if [ -z "$key" ] || [ -z "$file" ]; then - echo "Invalid arguments supplied" - exit 1 - fi - - if [ -f "$file" ]; then - grep -q "^$key=" "$file" - if [ $? -eq 0 ]; then - local value - value=$(grep "^$key=" "$file" | cut -d'=' -f2) - echo "$value" - else - echo "" - fi - fi -} - -function updateEnvFile() { - local key=$1 - local value=$2 - local file=$3 - - if [ -z "$key" ] || [ -z "$value" ] || [ -z "$file" ]; then - echo "Invalid arguments supplied" - exit 1 - fi - - if [ -f "$file" ]; then - # check if key exists in the file - grep -q "^$key=" "$file" - if [ $? -ne 0 ]; then - echo "$key=$value" >> "$file" - return - else - if [ "$OS_NAME" == "Darwin" ]; then - value=$(echo "$value" | sed 's/|/\\|/g') - sed -i '' "s|^$key=.*|$key=$value|g" "$file" - else - sed -i "s/^$key=.*/$key=$value/g" "$file" - fi - fi - else - echo "File not found: $file" - exit 1 - fi -} - -function download() { - cd $SCRIPT_DIR || exit 1 - TS=$(date +%s) - if [ -f "$PLANE_INSTALL_DIR/docker-compose.yml" ] - then - mv $PLANE_INSTALL_DIR/docker-compose.yml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yml - fi - - echo $RELEASE_DOWNLOAD_URL - echo $FALLBACK_DOWNLOAD_URL - echo $APP_RELEASE - - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml?$(date +%s)") - BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') - STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') - - if [ "$STATUS" -eq 200 ]; then - echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yml - else - # Fallback to download from the raw github url - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/docker-compose.yml?$(date +%s)") - BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') - STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') - - if [ "$STATUS" -eq 200 ]; then - echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yml - else - echo "Failed to download docker-compose.yml. HTTP Status: $STATUS" - echo "URL: $RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml" - mv $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yml $PLANE_INSTALL_DIR/docker-compose.yml - exit 1 - fi - fi - - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env?$(date +%s)") - BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') - STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') - - if [ "$STATUS" -eq 200 ]; then - echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env - else - # Fallback to download from the raw github url - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/variables.env?$(date +%s)") - BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') - STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') - - if [ "$STATUS" -eq 200 ]; then - echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env - else - echo "Failed to download variables.env. HTTP Status: $STATUS" - echo "URL: $RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env" - mv $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yml $PLANE_INSTALL_DIR/docker-compose.yml - exit 1 - fi - fi - - if [ -f "$DOCKER_ENV_PATH" ]; - then - cp "$DOCKER_ENV_PATH" "$PLANE_INSTALL_DIR/archive/$TS.env" - cp "$DOCKER_ENV_PATH" "$PLANE_INSTALL_DIR/plane.env.bak" - fi - - mv $PLANE_INSTALL_DIR/variables-upgrade.env $DOCKER_ENV_PATH - - syncEnvFile - - updateEnvFile "APP_RELEASE" "$APP_RELEASE" "$DOCKER_ENV_PATH" - -} -function deployStack() { - # Check if docker compose file and env file exist - if [ ! -f "$DOCKER_FILE_PATH" ] || [ ! -f "$DOCKER_ENV_PATH" ]; then - echo "Configuration files not found" - echo "Downloading it now......" - APP_RELEASE=$(checkLatestRelease) - download - fi - if [ -z "$stack_name" ]; then - getStackName - fi - echo "Starting ${stack_name} stack..." - - # Pull envs - if [ -f "$DOCKER_ENV_PATH" ]; then - set -o allexport; source $DOCKER_ENV_PATH; set +o allexport; - else - echo "Environment file not found: $DOCKER_ENV_PATH" - exit 1 - fi - - # Deploy the stack - docker stack deploy -c $DOCKER_FILE_PATH $stack_name - - echo "Waiting for services to be deployed..." - sleep 10 - - # Check migrator service - local migrator_service=$(docker service ls --filter name=${stack_name}_migrator -q) - if [ -n "$migrator_service" ]; then - echo ">> Waiting for Data Migration to finish" - while docker service ls --filter name=${stack_name}_migrator | grep -q "running"; do - echo -n "." - sleep 1 - done - echo "" - - # Get the most recent container for the migrator service - local migrator_container=$(docker ps -a --filter name=${stack_name}_migrator --latest -q) - - if [ -n "$migrator_container" ]; then - # Get the exit code of the container - local exit_code=$(docker inspect --format='{{.State.ExitCode}}' $migrator_container) - - if [ "$exit_code" != "0" ]; then - echo "Server failed to start ❌" - echo "Migration failed with exit code: $exit_code" - echo "Please check the logs for the 'migrator' service and resolve the issue(s)." - echo "Stop the services by running the command: ./swarm.sh stop" - exit 1 - else - echo " Data Migration completed successfully ✅" - fi - else - echo "Warning: Could not find migrator container to check exit status" - fi - fi - - # Check API service - local api_service=$(docker service ls --filter name=${stack_name}_api -q) - while docker service ls --filter name=${stack_name}_api | grep -q "running"; do - local running_container=$(docker ps --filter "name=${stack_name}_api" --filter "status=running" -q) - if [ -n "$running_container" ]; then - if docker container logs $running_container 2>/dev/null | grep -q "Application Startup Complete"; then - break - fi - fi - sleep 2 - done - - if [ -z "$api_service" ]; then - echo "Plane Server failed to start ❌" - echo "Please check the logs for the 'api' service and resolve the issue(s)." - echo "Stop the services by running the command: ./swarm.sh stop" - exit 1 - fi - echo " Plane Server started successfully ✅" - echo "" - echo " You can access the application at $WEB_URL" - echo "" -} - -function removeStack() { - if [ -z "$stack_name" ]; then - echo "Stack name not found" - exit 1 - fi - echo "Removing ${stack_name} stack..." - docker stack rm "$stack_name" - echo "Waiting for services to be removed..." - while docker stack ls | grep -q "$stack_name"; do - sleep 1 - done - sleep 20 - echo "Services stopped successfully ✅" -} - -function viewStatus() { - echo "Checking status of ${stack_name} stack..." - if [ -z "$stack_name" ]; then - echo "Stack name not found" - exit 1 - fi - docker stack ps "$stack_name" -} - -function redeployStack() { - removeStack - echo "ReDeploying ${stack_name} stack..." - deployStack -} - -function upgrade() { - - echo "Checking status of ${stack_name} stack..." - if [ -z "$stack_name" ]; then - echo "Stack name not found" - exit 1 - fi - - local latest_release=$(checkLatestRelease) - - echo "" - echo "Current release: $APP_RELEASE" - - if [ "$latest_release" == "$APP_RELEASE" ]; then - echo "" - echo "You are already using the latest release" - exit 0 - fi - - echo "Latest release: $latest_release" - echo "" - - # Check for confirmation to upgrade - echo "Do you want to upgrade to the latest release ($latest_release)?" - read -p "Continue? [y/N]: " confirm - - if [[ ! "$confirm" =~ ^[Yy]$ ]]; then - echo "Exiting..." - exit 0 - fi - - export APP_RELEASE=$latest_release - - # check if stack exists - echo "Upgrading ${stack_name} stack..." - - # check env file and take backup - if [ -f "$DOCKER_ENV_PATH" ]; then - cp "$DOCKER_ENV_PATH" "${DOCKER_ENV_PATH}.bak" - fi - - download - redeployStack -} - -function viewSpecificLogs() { - local service=$1 - - # Input validation - if [ -z "$service" ]; then - echo "Error: Please specify a service name" - return 1 - fi - - # Main loop for service logs - while true; do - # Get all running containers for the service - local running_containers=$(docker ps --filter "name=${stack_name}_${service}" --filter "status=running" -q) - - # If no running containers found, try service logs - if [ -z "$running_containers" ]; then - echo "No running containers found for ${stack_name}_${service}, checking service logs..." - if docker service inspect ${stack_name}_${service} >/dev/null 2>&1; then - echo "Press Ctrl+C or 'q' to exit logs" - docker service logs ${stack_name}_${service} -f - break - else - echo "Error: No running containers or services found for ${stack_name}_${service}" - return 1 - fi - return - fi - - # If multiple containers are running, let user choose - if [ $(echo "$running_containers" | grep -v '^$' | wc -l) -gt 1 ]; then - clear - echo "Multiple containers found for ${stack_name}_${service}:" - local i=1 - # Use regular arrays instead of associative arrays - container_ids=() - container_names=() - - while read -r container_id; do - if [ -n "$container_id" ]; then - local container_name=$(docker inspect --format '{{.Name}}' "$container_id" | sed 's/\///') - container_ids[$i]=$container_id - container_names[$i]=$container_name - echo "[$i] ${container_names[$i]} (${container_ids[$i]})" - i=$((i+1)) - fi - done <<< "$running_containers" - - echo -e "\nPlease select a container number:" - read -r selection - - if [[ "$selection" =~ ^[0-9]+$ ]] && [ -n "${container_ids[$selection]}" ]; then - local selected_container=${container_ids[$selection]} - clear - echo "Showing logs for container: ${container_names[$selection]}" - echo "Press Ctrl+C or 'q' to return to container selection" - - # Start watching logs in the background - docker container logs -f "$selected_container" & - local log_pid=$! - - while true; do - read -r -n 1 input - if [[ $input == "q" ]]; then - kill $log_pid 2>/dev/null - wait $log_pid 2>/dev/null - break - fi - done - clear - else - echo "Error: Invalid selection" - sleep 2 - fi - else - # Single container case - local container_name=$(docker inspect --format '{{.Name}}' "$running_containers" | sed 's/\///') - echo "Showing logs for container: $container_name" - echo "Press Ctrl+C or 'q' to exit logs" - docker container logs -f "$running_containers" & - local log_pid=$! - - while true; do - read -r -n 1 input - if [[ $input == "q" ]]; then - kill $log_pid 2>/dev/null - wait $log_pid 2>/dev/null - break - fi - done - break - fi - done -} - -function viewLogs(){ - - ARG_SERVICE_NAME=$2 - if [ -z "$ARG_SERVICE_NAME" ]; - then - echo - echo "Select a Service you want to view the logs for:" - echo " 1) Web" - echo " 2) Space" - echo " 3) API" - echo " 4) Worker" - echo " 5) Beat-Worker" - echo " 6) Migrator" - echo " 7) Proxy" - echo " 8) Redis" - echo " 9) Postgres" - echo " 10) Minio" - echo " 11) RabbitMQ" - echo " 0) Back to Main Menu" - echo - read -p "Service: " DOCKER_SERVICE_NAME - - until (( DOCKER_SERVICE_NAME >= 0 && DOCKER_SERVICE_NAME <= 11 )); do - echo "Invalid selection. Please enter a number between 0 and 11." - read -p "Service: " DOCKER_SERVICE_NAME - done - - if [ -z "$DOCKER_SERVICE_NAME" ]; - then - echo "INVALID SERVICE NAME SUPPLIED" - else - case $DOCKER_SERVICE_NAME in - 1) viewSpecificLogs "web";; - 2) viewSpecificLogs "space";; - 3) viewSpecificLogs "api";; - 4) viewSpecificLogs "worker";; - 5) viewSpecificLogs "beat-worker";; - 6) viewSpecificLogs "migrator";; - 7) viewSpecificLogs "proxy";; - 8) viewSpecificLogs "plane-redis";; - 9) viewSpecificLogs "plane-db";; - 10) viewSpecificLogs "plane-minio";; - 11) viewSpecificLogs "plane-mq";; - 0) askForAction;; - *) echo "INVALID SERVICE NAME SUPPLIED";; - esac - fi - elif [ -n "$ARG_SERVICE_NAME" ]; - then - ARG_SERVICE_NAME=$(echo "$ARG_SERVICE_NAME" | tr '[:upper:]' '[:lower:]') - case $ARG_SERVICE_NAME in - web) viewSpecificLogs "web";; - space) viewSpecificLogs "space";; - api) viewSpecificLogs "api";; - worker) viewSpecificLogs "worker";; - beat-worker) viewSpecificLogs "beat-worker";; - migrator) viewSpecificLogs "migrator";; - proxy) viewSpecificLogs "proxy";; - redis) viewSpecificLogs "plane-redis";; - postgres) viewSpecificLogs "plane-db";; - minio) viewSpecificLogs "plane-minio";; - rabbitmq) viewSpecificLogs "plane-mq";; - *) echo "INVALID SERVICE NAME SUPPLIED";; - esac - else - echo "INVALID SERVICE NAME SUPPLIED" - fi -} - - - -function askForAction() { - # Rest of askForAction remains the same but use $stack_name instead of $STACK_NAME - local DEFAULT_ACTION=$1 - - if [ -z "$DEFAULT_ACTION" ]; then - echo - echo "Select an Action you want to perform:" - echo " 1) Deploy Stack" - echo " 2) Remove Stack" - echo " 3) View Stack Status" - echo " 4) Redeploy Stack" - echo " 5) Upgrade" - echo " 6) View Logs" - echo " 7) Exit" - echo - read -p "Action [3]: " ACTION - until [[ -z "$ACTION" || "$ACTION" =~ ^[1-6]$ ]]; do - echo "$ACTION: invalid selection." - read -p "Action [3]: " ACTION - done - - if [ -z "$ACTION" ]; then - ACTION=3 - fi - echo - fi - - if [ "$ACTION" == "1" ] || [ "$DEFAULT_ACTION" == "deploy" ]; then - deployStack - elif [ "$ACTION" == "2" ] || [ "$DEFAULT_ACTION" == "remove" ]; then - removeStack - elif [ "$ACTION" == "3" ] || [ "$DEFAULT_ACTION" == "status" ]; then - viewStatus - elif [ "$ACTION" == "4" ] || [ "$DEFAULT_ACTION" == "redeploy" ]; then - redeployStack - elif [ "$ACTION" == "5" ] || [ "$DEFAULT_ACTION" == "upgrade" ]; then - upgrade - elif [ "$ACTION" == "6" ] || [ "$DEFAULT_ACTION" == "logs" ]; then - viewLogs "$@" - elif [ "$ACTION" == "7" ] || [ "$DEFAULT_ACTION" == "exit" ]; then - exit 0 - else - echo "INVALID ACTION SUPPLIED" - fi -} - -# Initialize stack name at script start - -if [ -z "$stack_name" ]; then - readStackName -fi - -# Sync environment variables -if [ -f "$DOCKER_ENV_PATH" ]; then - DOCKERHUB_USER=$(getEnvValue "DOCKERHUB_USER" "$DOCKER_ENV_PATH") - APP_RELEASE=$(getEnvValue "APP_RELEASE" "$DOCKER_ENV_PATH") - - if [ -z "$DOCKERHUB_USER" ]; then - DOCKERHUB_USER=artifacts.plane.so/makeplane - updateEnvFile "DOCKERHUB_USER" "$DOCKERHUB_USER" "$DOCKER_ENV_PATH" - fi - - if [ -z "$APP_RELEASE" ]; then - APP_RELEASE=stable - updateEnvFile "APP_RELEASE" "$APP_RELEASE" "$DOCKER_ENV_PATH" - fi -fi - - -# Main execution -print_header -askForAction "$@" diff --git a/plane/code/install.sh b/plane/setup.sh similarity index 95% rename from plane/code/install.sh rename to plane/setup.sh index 9f0065f..3460d35 100755 --- a/plane/code/install.sh +++ b/plane/setup.sh @@ -2,14 +2,14 @@ BRANCH=${BRANCH:-master} SCRIPT_DIR=$PWD -SERVICE_FOLDER=plane-app +SERVICE_FOLDER=plane-code PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER export APP_RELEASE=stable export DOCKERHUB_USER=artifacts.plane.so/makeplane export PULL_POLICY=${PULL_POLICY:-if_not_present} export GH_REPO=makeplane/plane export RELEASE_DOWNLOAD_URL="https://github.com/$GH_REPO/releases/download" -export FALLBACK_DOWNLOAD_URL="https://raw.githubusercontent.com/$GH_REPO/$BRANCH/deploy/selfhost" +export FALLBACK_DOWNLOAD_URL="https://raw.githubusercontent.com/$GH_REPO/$BRANCH/deployments/cli/community" CPU_ARCH=$(uname -m) OS_NAME=$(uname) @@ -57,7 +57,7 @@ function spinner() { function checkLatestRelease(){ echo "Checking for the latest release..." >&2 - local latest_release=$(curl -s https://api.github.com/repos/$GH_REPO/releases/latest | grep -o '"tag_name": "[^"]*"' | sed 's/"tag_name": "//;s/"//g') + local latest_release=$(curl -fsSL https://api.github.com/repos/$GH_REPO/releases/latest | grep -o '"tag_name": "[^"]*"' | sed 's/"tag_name": "//;s/"//g') if [ -z "$latest_release" ]; then echo "Failed to check for the latest release. Exiting..." >&2 exit 1 @@ -196,7 +196,7 @@ function buildYourOwnImage(){ REPO=https://github.com/$GH_REPO.git git clone "$REPO" "$PLANE_TEMP_CODE_DIR" --branch "$BRANCH" --single-branch --depth 1 - cp "$PLANE_TEMP_CODE_DIR/deploy/selfhost/build.yml" "$PLANE_TEMP_CODE_DIR/build.yml" + cp "$PLANE_TEMP_CODE_DIR/deployments/cli/community/build.yml" "$PLANE_TEMP_CODE_DIR/build.yml" cd "$PLANE_TEMP_CODE_DIR" || exit @@ -247,7 +247,7 @@ function download() { mv $PLANE_INSTALL_DIR/docker-compose.yaml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml fi - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml?$(date +%s)") + RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml?$(date +%s)") BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') @@ -255,7 +255,7 @@ function download() { echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yaml else # Fallback to download from the raw github url - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/docker-compose.yml?$(date +%s)") + RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/docker-compose.yml?$(date +%s)") BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') @@ -269,7 +269,7 @@ function download() { fi fi - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env?$(date +%s)") + RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env?$(date +%s)") BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') @@ -277,7 +277,7 @@ function download() { echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env else # Fallback to download from the raw github url - RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/variables.env?$(date +%s)") + RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/variables.env?$(date +%s)") BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') diff --git a/plane/update.js b/plane/update.js index a5ef43f..51317d8 100644 --- a/plane/update.js +++ b/plane/update.js @@ -1,19 +1,10 @@ import utils from "../utils.js"; -console.log( - "Plan file structure has changed. This script needs to be reworked." -); - -process.exit(); - -await utils.cloneOrPullRepo({ - repo: "https://github.com/makeplane/plane.git", - path: "./repo", - branch: "preview", -}); - -await utils.copyDir("./repo/deploy/selfhost", "./code"); -await utils.renameFile("./code/variables.env", "./code/.env.example"); +await utils.removeDir("./code"); +await utils.renameDir("./plane-code", "./code"); +await utils.removeDir("./code/archive"); +await utils.renameFile("./code/plane.env", "./code/.env.example"); +await utils.renameFile("./code/docker-compose.yaml", "./code/docker-compose.yml"); await utils.removeContainerNames("./code/docker-compose.yml"); await utils.removePorts("./code/docker-compose.yml"); diff --git a/twenty/README.md b/twenty/README.md deleted file mode 100644 index 1fa12fb..0000000 --- a/twenty/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Twenty - -- copied from https://github.com/twentyhq/twenty -- removed `ports` diff --git a/twenty/code/.env.example b/twenty/code/.env.example deleted file mode 100644 index d538814..0000000 --- a/twenty/code/.env.example +++ /dev/null @@ -1,18 +0,0 @@ -TAG=latest - -#PG_DATABASE_USER=postgres -#PG_DATABASE_PASSWORD=replace_me_with_a_strong_password_without_special_characters -#PG_DATABASE_HOST=db -#PG_DATABASE_PORT=5432 -REDIS_URL=redis://redis:6379 - -SERVER_URL=https://$(PRIMARY_DOMAIN) - -# Use openssl rand -base64 32 for each secret -APP_SECRET=replace_me_with_a_random_string - -STORAGE_TYPE=local - -# STORAGE_S3_REGION=eu-west3 -# STORAGE_S3_NAME=my-bucket -# STORAGE_S3_ENDPOINT= diff --git a/twenty/code/Makefile b/twenty/code/Makefile deleted file mode 100644 index bdda023..0000000 --- a/twenty/code/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# Makefile for building Twenty CRM docker images. -# Set the tag and/or target build platform using make command-line variables assignments. -# -# Optional make variables: -# PLATFORM - defaults to 'linux/amd64' -# TAG - defaults to 'latest' -# -# Example: make -# Example: make PLATFORM=linux/aarch64 TAG=my-tag - -PLATFORM ?= linux/amd64 -TAG ?= latest - -prod-build: - @cd ../.. && docker build -f ./packages/twenty-docker/twenty/Dockerfile --platform $(PLATFORM) --tag twenty:$(TAG) . && cd - - -prod-run: - @docker run -d -p 3000:3000 --name twenty twenty:$(TAG) - -prod-postgres-run: - @docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name twenty-postgres twenty-postgres:$(TAG) - -prod-website-build: - @cd ../.. && docker build -f ./packages/twenty-docker/twenty-website/Dockerfile --platform $(PLATFORM) --tag twenty-website:$(TAG) . && cd - - -prod-website-run: - @docker run -d -p 3000:3000 --name twenty-website twenty-website:$(TAG) diff --git a/twenty/code/docker-compose.yml b/twenty/code/docker-compose.yml deleted file mode 100644 index 55dfc6d..0000000 --- a/twenty/code/docker-compose.yml +++ /dev/null @@ -1,126 +0,0 @@ -name: twenty - -services: - server: - image: twentycrm/twenty:${TAG:-latest} - volumes: - - server-local-data:/app/packages/twenty-server/.local-storage - environment: - NODE_PORT: 3000 - PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default - SERVER_URL: ${SERVER_URL} - REDIS_URL: ${REDIS_URL:-redis://redis:6379} - DISABLE_DB_MIGRATIONS: ${DISABLE_DB_MIGRATIONS} - DISABLE_CRON_JOBS_REGISTRATION: ${DISABLE_CRON_JOBS_REGISTRATION} - - STORAGE_TYPE: ${STORAGE_TYPE} - STORAGE_S3_REGION: ${STORAGE_S3_REGION} - STORAGE_S3_NAME: ${STORAGE_S3_NAME} - STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT} - - APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string} - # MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED} - # CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED} - # AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID} - # AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET} - # AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL} - # AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL} - - # CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED} - # MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED} - # AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED} - # AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID} - # AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET} - # AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL} - # AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL} - - # EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com} - # EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"} - # EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com} - # EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp} - # EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com} - # EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465} - # EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-} - # EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-} - - depends_on: - db: - condition: service_healthy - healthcheck: - test: curl --fail http://localhost:3000/healthz - interval: 5s - timeout: 5s - retries: 20 - restart: always - - worker: - image: twentycrm/twenty:${TAG:-latest} - volumes: - - server-local-data:/app/packages/twenty-server/.local-storage - command: [ "yarn", "worker:prod" ] - environment: - PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default - SERVER_URL: ${SERVER_URL} - REDIS_URL: ${REDIS_URL:-redis://redis:6379} - DISABLE_DB_MIGRATIONS: "true" # it already runs on the server - DISABLE_CRON_JOBS_REGISTRATION: "true" # it already runs on the server - - STORAGE_TYPE: ${STORAGE_TYPE} - STORAGE_S3_REGION: ${STORAGE_S3_REGION} - STORAGE_S3_NAME: ${STORAGE_S3_NAME} - STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT} - - APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string} - # MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED} - # CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED} - # AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID} - # AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET} - # AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL} - # AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL} - - # CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED} - # MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED} - # AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED} - # AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID} - # AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET} - # AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL} - # AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL} - - # EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com} - # EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"} - # EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com} - # EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp} - # EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com} - # EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465} - # EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-} - # EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-} - - depends_on: - db: - condition: service_healthy - server: - condition: service_healthy - restart: always - - db: - image: postgres:16 - volumes: - - db-data:/var/lib/postgresql/data - environment: - POSTGRES_USER: ${PG_DATABASE_USER:-postgres} - POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD:-postgres} - healthcheck: - test: pg_isready -U ${PG_DATABASE_USER:-postgres} -h localhost -d postgres - interval: 5s - timeout: 5s - retries: 10 - restart: always - - redis: - image: redis - restart: always - command: [ "--maxmemory-policy", "noeviction" ] - -volumes: - db-data: - server-local-data: diff --git a/twenty/code/grafana/provisioning/datasources/clickhouse-datasource.yaml b/twenty/code/grafana/provisioning/datasources/clickhouse-datasource.yaml deleted file mode 100644 index bb4279e..0000000 --- a/twenty/code/grafana/provisioning/datasources/clickhouse-datasource.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: 1 - -datasources: - - name: ClickHouse - type: grafana-clickhouse-datasource - uid: clickhouse_datasource - jsonData: - server: twenty_clickhouse - defaultDatabase: twenty_dev - port: 9000 - protocol: native - tlsSkipVerify: true - username: default - secureJsonData: - password: devPassword \ No newline at end of file diff --git a/twenty/code/k8s/README.md b/twenty/code/k8s/README.md deleted file mode 100644 index d538d21..0000000 --- a/twenty/code/k8s/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# README -DISCLAIMER: The k8s and podman deployments are not maintained by the core team. -These files are provided and maintained by the community. Twenty core team -maintains support for docker deployment. - -## Overview - -This repository contains Kubernetes manifests and Terraform files to help you deploy and manage the TwentyCRM application. The files are located in the `packages/twenty-docker/k8s` directory. - -## Prerequisites - -Before using these files, ensure you have the following installed and configured on your system: - -- Kubernetes cluster (e.g., Minikube, EKS, GKE) -- kubectl -- Terraform -- Docker - -## Setup Instructions - -### Step 1: Clone the Repository - -Clone the repository to your local machine: - -``` bash -git clone https://github.com/twentyhq/twenty.git -cd twentycrm/packages/twenty-docker/k8s -``` - -### Step 2: Customize the Manifests and Terraform Files - -**Important:** These files require customization for your specific implementation. Update the placeholders and configurations according to your environment and requirements. - -### Step 3: Deploy with Terraform - -1. Navigate to the Terraform directory: - - ```bash - cd terraform - ``` - -2. Initialize Terraform: - - ```bash - terraform init - ``` - -3. Plan the deployment: - - ```bash - terraform plan - ``` - -4. Apply the deployment: - - ```bash - terraform apply - ``` - -## OR - -### Step 3: Deploy with Kubernetes Manifests - -1. Navigate to the Kubernetes manifests directory: - - ```bash - cd ../k8s - ``` - -2. Create Server Secret - - ``` bash - kubectl create secret generic -n twentycrm tokens --from-literal accessToken=changeme --from-literal loginToken="changeme" --from-literal refreshToken="changeme" --from-literal fileToken="changeme" - ``` - -3. Apply the manifests: - - ```bash - kubectl apply -f . - ``` - -## Customization - -### Kubernetes Manifests - -- **Namespace:** Update the `namespace` in the manifests as needed. -- **Resource Limits:** Adjust the resource limits and requests according to your application's requirements. -- **Environment Variables:** Configure server tokens in the `Secret` command above. - -### Terraform Files - -- **Variables:** Update the variables in the `variables.tf` file to match your environment. -- **Locals:** Update the locals in the `main.tf` file to match your environment. -- **Providers:** Ensure the provider configurations (e.g., AWS, GCP) are correct for your setup. -- **Resources:** Modify the resource definitions as needed to fit your infrastructure. - -## Troubleshooting - -### Common Issues - -- **Connectivity:** Ensure your Kubernetes cluster is accessible and configured correctly. -- **Permissions:** Verify that you have the necessary permissions to deploy resources in your cloud provider. -- **Resource Limits:** Adjust resource limits if you encounter issues related to insufficient resources. - -### Logs and Debugging - -- Use `kubectl logs` to check the logs of your Kubernetes pods. -- Use `terraform show` and `terraform state` to inspect your Terraform state and configurations. - -## Conclusion - -This setup provides a basic structure for deploying the TwentyCRM application using Kubernetes and Terraform. Ensure you thoroughly customize the manifests and Terraform files to suit your specific needs. For any issues or questions, please refer to the official documentation of Kubernetes and Terraform or seek support from your cloud provider. - ---- - -Feel free to contribute and improve this repository by submitting pull requests or opening issues. Happy deploying! diff --git a/twenty/code/k8s/manifests/deployment-db.yaml b/twenty/code/k8s/manifests/deployment-db.yaml deleted file mode 100644 index c797972..0000000 --- a/twenty/code/k8s/manifests/deployment-db.yaml +++ /dev/null @@ -1,58 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: twentycrm-db - name: twentycrm-db - namespace: twentycrm -spec: - progressDeadlineSeconds: 600 - replicas: 1 - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - type: RollingUpdate - selector: - matchLabels: - app: twentycrm-db - template: - metadata: - labels: - app: twentycrm-db - spec: - volumes: - - name: twentycrm-db-data - persistentVolumeClaim: - claimName: twentycrm-db-pvc - containers: - - name: twentycrm - image: twentycrm/twenty-postgres-spilo:latest - imagePullPolicy: Always - env: - - name: PGUSER_SUPERUSER - value: "postgres" - - name: PGPASSWORD_SUPERUSER - value: "postgres" - - name: SPILO_PROVIDER - value: "local" - - name: ALLOW_NOSSL - value: "true" - ports: - - containerPort: 5432 - name: tcp - protocol: TCP - resources: - requests: - memory: "256Mi" - cpu: "250m" - limits: - memory: "1024Mi" - cpu: "1000m" - stdin: true - tty: true - volumeMounts: - - mountPath: /home/postgres/pgdata - name: twentycrm-db-data - dnsPolicy: ClusterFirst - restartPolicy: Always diff --git a/twenty/code/k8s/manifests/deployment-redis.yaml b/twenty/code/k8s/manifests/deployment-redis.yaml deleted file mode 100644 index bd7aaa3..0000000 --- a/twenty/code/k8s/manifests/deployment-redis.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: twentycrm-redis - name: twentycrm-redis - namespace: twentycrm -spec: - progressDeadlineSeconds: 600 - replicas: 1 - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - type: RollingUpdate - selector: - matchLabels: - app: twentycrm-redis - template: - metadata: - labels: - app: twentycrm-redis - spec: - containers: - - name: redis - image: redis/redis-stack-server:latest - imagePullPolicy: Always - args: ["--maxmemory-policy", "noeviction"] - env: - - name: PORT - value: "6379" - ports: - - containerPort: 6379 - name: redis - protocol: TCP - resources: - requests: - memory: "1024Mi" - cpu: "250m" - limits: - memory: "2048Mi" - cpu: "500m" - - dnsPolicy: ClusterFirst - restartPolicy: Always diff --git a/twenty/code/k8s/manifests/deployment-server.yaml b/twenty/code/k8s/manifests/deployment-server.yaml deleted file mode 100644 index 9d21993..0000000 --- a/twenty/code/k8s/manifests/deployment-server.yaml +++ /dev/null @@ -1,76 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: twentycrm-server - name: twentycrm-server - namespace: twentycrm -spec: - progressDeadlineSeconds: 600 - replicas: 1 - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - type: RollingUpdate - selector: - matchLabels: - app: twentycrm-server - template: - metadata: - labels: - app: twentycrm-server - spec: - volumes: - - name: twentycrm-server-data - persistentVolumeClaim: - claimName: twentycrm-server-pvc - - name: twentycrm-docker-data - persistentVolumeClaim: - claimName: twentycrm-docker-data-pvc - containers: - - name: twentycrm - image: twentycrm/twenty:latest - imagePullPolicy: Always - env: - - name: NODE_PORT - value: 3000 - - name: SERVER_URL - value: "https://crm.example.com:443" - - name: "PG_DATABASE_URL" - value: "postgres://postgres:postgres@twentycrm-db.twentycrm.svc.cluster.local/default" - - name: "REDIS_URL" - value: "redis://twentycrm-redis.twentycrm.svc.cluster.local:6379" - - name: SIGN_IN_PREFILLED - value: "false" - - name: STORAGE_TYPE - value: "local" - - name: "ACCESS_TOKEN_EXPIRES_IN" - value: "7d" - - name: "LOGIN_TOKEN_EXPIRES_IN" - value: "1h" - - name: APP_SECRET - valueFrom: - secretKeyRef: - name: tokens - key: accessToken - ports: - - containerPort: 3000 - name: http-tcp - protocol: TCP - resources: - requests: - memory: "256Mi" - cpu: "250m" - limits: - memory: "1024Mi" - cpu: "1000m" - stdin: true - tty: true - volumeMounts: - - mountPath: /app/docker-data - name: twentycrm-docker-data - - mountPath: /app/packages/twenty-server/.local-storage - name: twentycrm-server-data - dnsPolicy: ClusterFirst - restartPolicy: Always diff --git a/twenty/code/k8s/manifests/deployment-worker.yaml b/twenty/code/k8s/manifests/deployment-worker.yaml deleted file mode 100644 index fbee277..0000000 --- a/twenty/code/k8s/manifests/deployment-worker.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: twentycrm-worker - name: twentycrm-worker - namespace: twentycrm -spec: - progressDeadlineSeconds: 600 - replicas: 1 - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - type: RollingUpdate - selector: - matchLabels: - app: twentycrm-worker - template: - metadata: - labels: - app: twentycrm-worker - spec: - containers: - - name: twentycrm - image: twentycrm/twenty:latest - imagePullPolicy: Always - env: - - name: SERVER_URL - value: "https://crm.example.com:443" - - name: PG_DATABASE_URL - value: "postgres://postgres:postgres@twentycrm-db.twentycrm.svc.cluster.local/default" - - name: DISABLE_DB_MIGRATIONS - value: "false" # it already runs on the server - - name: STORAGE_TYPE - value: "local" - - name: "REDIS_URL" - value: "redis://twentycrm-redis.twentycrm.svc.cluster.local:6379" - - name: APP_SECRET - valueFrom: - secretKeyRef: - name: tokens - key: accessToken - command: - - yarn - - worker:prod - resources: - requests: - memory: "1024Mi" - cpu: "250m" - limits: - memory: "2048Mi" - cpu: "1000m" - stdin: true - tty: true - dnsPolicy: ClusterFirst - restartPolicy: Always diff --git a/twenty/code/k8s/manifests/ingress.yaml b/twenty/code/k8s/manifests/ingress.yaml deleted file mode 100644 index 0bbae11..0000000 --- a/twenty/code/k8s/manifests/ingress.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: twentycrm - namespace: twentycrm - annotations: - nginx.ingress.kubernetes.io/configuration-snippet: | - more_set_headers "X-Forwarded-For $http_x_forwarded_for"; - nginx.ingress.kubernetes.io/force-ssl-redirect: "false" - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/backend-protocol: "HTTP" -spec: - ingressClassName: nginx - rules: - - host: crm.example.com - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: twentycrm-server - port: - name: http-tcp diff --git a/twenty/code/k8s/manifests/pv-db.yaml b/twenty/code/k8s/manifests/pv-db.yaml deleted file mode 100644 index 9caa4ca..0000000 --- a/twenty/code/k8s/manifests/pv-db.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: PersistentVolume -metadata: - name: twentycrm-db-pv -spec: - storageClassName: default - capacity: - storage: 10Gi - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Retain diff --git a/twenty/code/k8s/manifests/pv-docker-data.yaml b/twenty/code/k8s/manifests/pv-docker-data.yaml deleted file mode 100644 index 95fc52a..0000000 --- a/twenty/code/k8s/manifests/pv-docker-data.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: PersistentVolume -metadata: - name: twentycrm-docker-data-pv -spec: - storageClassName: default - capacity: - storage: 100Mi - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Retain diff --git a/twenty/code/k8s/manifests/pv-server.yaml b/twenty/code/k8s/manifests/pv-server.yaml deleted file mode 100644 index 721de7d..0000000 --- a/twenty/code/k8s/manifests/pv-server.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: PersistentVolume -metadata: - name: twentycrm-server-pv - namespace: twentycrm -spec: - storageClassName: default - capacity: - storage: 10Gi - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Retain diff --git a/twenty/code/k8s/manifests/pvc-db.yaml b/twenty/code/k8s/manifests/pvc-db.yaml deleted file mode 100644 index 146596e..0000000 --- a/twenty/code/k8s/manifests/pvc-db.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: twentycrm-db-pvc - namespace: twentycrm -spec: - storageClassName: default - volumeName: twentycrm-db-pv - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 10Gi diff --git a/twenty/code/k8s/manifests/pvc-docker-data.yaml b/twenty/code/k8s/manifests/pvc-docker-data.yaml deleted file mode 100644 index 12dd071..0000000 --- a/twenty/code/k8s/manifests/pvc-docker-data.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: twentycrm-docker-data-pvc - namespace: twentycrm -spec: - storageClassName: default - volumeName: twentycrm-docker-data-pv - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 100Mi diff --git a/twenty/code/k8s/manifests/pvc-server.yaml b/twenty/code/k8s/manifests/pvc-server.yaml deleted file mode 100644 index f265057..0000000 --- a/twenty/code/k8s/manifests/pvc-server.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: twentycrm-server-pvc - namespace: twentycrm -spec: - storageClassName: default - volumeName: twentycrm-server-pv - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 10Gi diff --git a/twenty/code/k8s/manifests/service-db.yaml b/twenty/code/k8s/manifests/service-db.yaml deleted file mode 100644 index 89dbd14..0000000 --- a/twenty/code/k8s/manifests/service-db.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: twentycrm-db - namespace: twentycrm -spec: - internalTrafficPolicy: Cluster - ports: - - port: 5432 - protocol: TCP - targetPort: 5432 - selector: - app: twentycrm-db - sessionAffinity: ClientIP - sessionAffinityConfig: - clientIP: - timeoutSeconds: 10800 - type: ClusterIP diff --git a/twenty/code/k8s/manifests/service-redis.yaml b/twenty/code/k8s/manifests/service-redis.yaml deleted file mode 100644 index 49f5088..0000000 --- a/twenty/code/k8s/manifests/service-redis.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: twentycrm-redis - namespace: twentycrm -spec: - internalTrafficPolicy: Cluster - ports: - - port: 6379 - protocol: TCP - targetPort: 6379 - selector: - app: twentycrm-redis - sessionAffinity: ClientIP - sessionAffinityConfig: - clientIP: - timeoutSeconds: 10800 - type: ClusterIP diff --git a/twenty/code/k8s/manifests/service-server.yaml b/twenty/code/k8s/manifests/service-server.yaml deleted file mode 100644 index b45b28f..0000000 --- a/twenty/code/k8s/manifests/service-server.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: twentycrm-server - namespace: twentycrm -spec: - internalTrafficPolicy: Cluster - ports: - - name: http-tcp - port: 3000 - protocol: TCP - targetPort: 3000 - selector: - app: twentycrm-server - sessionAffinity: ClientIP - sessionAffinityConfig: - clientIP: - timeoutSeconds: 10800 - type: ClusterIP diff --git a/twenty/code/k8s/terraform/.terraform-docs.yml b/twenty/code/k8s/terraform/.terraform-docs.yml deleted file mode 100644 index 792c543..0000000 --- a/twenty/code/k8s/terraform/.terraform-docs.yml +++ /dev/null @@ -1,48 +0,0 @@ -formatter: "markdown table" # this is required - -version: "" - -header-from: main.tf - -recursive: - enabled: false - path: modules - -output: - file: "README.md" - mode: inject - template: |- - - # TwentyCRM Terraform Docs - - This file was generated by [terraform-docs](https://terraform-docs.io/), for more information on how to install, configure, and use visit their website. - - To update this `README.md` after changes to the Terraform code in this folder, run: `terraform-docs -c `./.terraform-docs.yml .` - - To make configuration changes to how this doc is generated, see `./.terraform-docs.yml` - - {{ .Content }} - - -output-values: - enabled: false - from: "outputs.tf" - -sort: - enabled: true - by: required - -settings: - anchor: true - color: true - default: true - description: true - escape: true - hide-empty: true - html: true - indent: 2 - lockfile: true - read-comments: true - required: true - sensitive: true - type: true diff --git a/twenty/code/k8s/terraform/README.md b/twenty/code/k8s/terraform/README.md deleted file mode 100644 index 32facfd..0000000 --- a/twenty/code/k8s/terraform/README.md +++ /dev/null @@ -1,73 +0,0 @@ - -# TwentyCRM Terraform Docs - -This file was generated by [terraform-docs](https://terraform-docs.io/), for more information on how to install, configure, and use visit their website. - -To update this `README.md` after changes to the Terraform code in this folder, run: `terraform-docs -c `./.terraform-docs.yml .` - -To make configuration changes to how this doc is generated, see `./.terraform-docs.yml` - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.9.2 | -| [kubernetes](#requirement\_kubernetes) | >= 2.32.0 | -| [random](#requirement\_random) | >= 3.6.3 | - -## Providers - -| Name | Version | -|------|---------| -| [kubernetes](#provider\_kubernetes) | >= 2.32.0 | -| [random](#provider\_random) | >= 3.6.3 | - -## Resources - -| Name | Type | -|------|------| -| [kubernetes_deployment.twentycrm_db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource | -| [kubernetes_deployment.twentycrm_redis](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource | -| [kubernetes_deployment.twentycrm_server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource | -| [kubernetes_deployment.twentycrm_worker](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource | -| [kubernetes_ingress.twentycrm](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/ingress) | resource | -| [kubernetes_namespace.twentycrm](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | -| [kubernetes_persistent_volume.db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume) | resource | -| [kubernetes_persistent_volume.docker_data](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume) | resource | -| [kubernetes_persistent_volume.server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume) | resource | -| [kubernetes_persistent_volume_claim.db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume_claim) | resource | -| [kubernetes_persistent_volume_claim.docker_data](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume_claim) | resource | -| [kubernetes_persistent_volume_claim.server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume_claim) | resource | -| [kubernetes_secret.twentycrm_tokens](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource | -| [kubernetes_service.twentycrm_db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource | -| [kubernetes_service.twentycrm_redis](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource | -| [kubernetes_service.twentycrm_server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource | -| [random_bytes.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/bytes) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [twentycrm\_app\_hostname](#input\_twentycrm\_app\_hostname) | The protocol, DNS fully qualified hostname, and port used to access TwentyCRM in your environment. Ex: https://crm.example.com:443 | `string` | n/a | yes | -| [twentycrm\_pgdb\_admin\_password](#input\_twentycrm\_pgdb\_admin\_password) | TwentyCRM password for postgres database. | `string` | n/a | yes | -| [twentycrm\_app\_name](#input\_twentycrm\_app\_name) | A friendly name prefix to use for every component deployed. | `string` | `"twentycrm"` | no | -| [twentycrm\_db\_image](#input\_twentycrm\_db\_image) | TwentyCRM image for database deployment. This defaults to latest. | `string` | `"twentycrm/twenty-postgres-spilo:latest"` | no | -| [twentycrm\_db\_pv\_capacity](#input\_twentycrm\_db\_pv\_capacity) | Storage capacity provisioned for database persistent volume. | `string` | `"10Gi"` | no | -| [twentycrm\_db\_pv\_path](#input\_twentycrm\_db\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no | -| [twentycrm\_db\_pvc\_requests](#input\_twentycrm\_db\_pvc\_requests) | Storage capacity reservation for database persistent volume claim. | `string` | `"10Gi"` | no | -| [twentycrm\_db\_replicas](#input\_twentycrm\_db\_replicas) | Number of replicas for the TwentyCRM database deployment. This defaults to 1. | `number` | `1` | no | -| [twentycrm\_docker\_data\_mount\_path](#input\_twentycrm\_docker\_data\_mount\_path) | TwentyCRM mount path for servers application data. Defaults to '/app/docker-data'. | `string` | `"/app/docker-data"` | no | -| [twentycrm\_docker\_data\_pv\_capacity](#input\_twentycrm\_docker\_data\_pv\_capacity) | Storage capacity provisioned for server persistent volume. | `string` | `"10Gi"` | no | -| [twentycrm\_docker\_data\_pv\_path](#input\_twentycrm\_docker\_data\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no | -| [twentycrm\_docker\_data\_pvc\_requests](#input\_twentycrm\_docker\_data\_pvc\_requests) | Storage capacity reservation for server persistent volume claim. | `string` | `"10Gi"` | no | -| [twentycrm\_namespace](#input\_twentycrm\_namespace) | Namespace for all TwentyCRM resources | `string` | `"twentycrm"` | no | -| [twentycrm\_redis\_image](#input\_twentycrm\_redis\_image) | TwentyCRM image for Redis deployment. This defaults to latest. | `string` | `"redis/redis-stack-server:latest"` | no | -| [twentycrm\_redis\_replicas](#input\_twentycrm\_redis\_replicas) | Number of replicas for the TwentyCRM Redis deployment. This defaults to 1. | `number` | `1` | no | -| [twentycrm\_server\_data\_mount\_path](#input\_twentycrm\_server\_data\_mount\_path) | TwentyCRM mount path for servers application data. Defaults to '/app/packages/twenty-server/.local-storage'. | `string` | `"/app/packages/twenty-server/.local-storage"` | no | -| [twentycrm\_server\_image](#input\_twentycrm\_server\_image) | TwentyCRM server image for the server deployment. This defaults to latest. This value is also used for the workers image. | `string` | `"twentycrm/twenty:latest"` | no | -| [twentycrm\_server\_pv\_capacity](#input\_twentycrm\_server\_pv\_capacity) | Storage capacity provisioned for server persistent volume. | `string` | `"10Gi"` | no | -| [twentycrm\_server\_pv\_path](#input\_twentycrm\_server\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no | -| [twentycrm\_server\_pvc\_requests](#input\_twentycrm\_server\_pvc\_requests) | Storage capacity reservation for server persistent volume claim. | `string` | `"10Gi"` | no | -| [twentycrm\_server\_replicas](#input\_twentycrm\_server\_replicas) | Number of replicas for the TwentyCRM server deployment. This defaults to 1. | `number` | `1` | no | -| [twentycrm\_worker\_replicas](#input\_twentycrm\_worker\_replicas) | Number of replicas for the TwentyCRM worker deployment. This defaults to 1. | `number` | `1` | no | - diff --git a/twenty/code/k8s/terraform/deployment-db.tf b/twenty/code/k8s/terraform/deployment-db.tf deleted file mode 100644 index 62c61a2..0000000 --- a/twenty/code/k8s/terraform/deployment-db.tf +++ /dev/null @@ -1,87 +0,0 @@ -resource "kubernetes_deployment" "twentycrm_db" { - metadata { - name = "${var.twentycrm_app_name}-db" - namespace = kubernetes_namespace.twentycrm.metadata.0.name - labels = { - app = "${var.twentycrm_app_name}-db" - } - } - - spec { - replicas = var.twentycrm_db_replicas - selector { - match_labels = { - app = "${var.twentycrm_app_name}-db" - } - } - - strategy { - type = "RollingUpdate" - rolling_update { - max_surge = "1" - max_unavailable = "1" - } - } - - template { - metadata { - labels = { - app = "${var.twentycrm_app_name}-db" - } - } - - spec { - container { - image = var.twentycrm_db_image - name = var.twentycrm_app_name - stdin = true - tty = true - security_context { - allow_privilege_escalation = true - } - - env { - name = "POSTGRES_PASSWORD" - value = var.twentycrm_pgdb_admin_password - } - env { - name = "BITNAMI_DEBUG" - value = true - } - - port { - container_port = 5432 - protocol = "TCP" - } - - resources { - requests = { - cpu = "250m" - memory = "256Mi" - } - limits = { - cpu = "1000m" - memory = "1024Mi" - } - } - - volume_mount { - name = "db-data" - mount_path = "/bitnami/postgresql" - } - } - - volume { - name = "db-data" - - persistent_volume_claim { - claim_name = kubernetes_persistent_volume_claim.db.metadata.0.name - } - } - - dns_policy = "ClusterFirst" - restart_policy = "Always" - } - } - } -} diff --git a/twenty/code/k8s/terraform/deployment-redis.tf b/twenty/code/k8s/terraform/deployment-redis.tf deleted file mode 100644 index d867dac..0000000 --- a/twenty/code/k8s/terraform/deployment-redis.tf +++ /dev/null @@ -1,60 +0,0 @@ -resource "kubernetes_deployment" "twentycrm_redis" { - metadata { - name = "${var.twentycrm_app_name}-redis" - namespace = kubernetes_namespace.twentycrm.metadata.0.name - - labels = { - app = "${var.twentycrm_app_name}-redis" - } - } - - spec { - replicas = var.twentycrm_redis_replicas - selector { - match_labels = { - app = "${var.twentycrm_app_name}-redis" - } - } - - strategy { - type = "RollingUpdate" - rolling_update { - max_surge = "1" - max_unavailable = "1" - } - } - - template { - metadata { - labels = { - app = "${var.twentycrm_app_name}-redis" - } - } - - spec { - container { - image = var.twentycrm_redis_image - name = "redis" - - port { - container_port = 6379 - protocol = "TCP" - } - - resources { - requests = { - cpu = "250m" - memory = "1024Mi" - } - limits = { - cpu = "500m" - memory = "2048Mi" - } - } - } - dns_policy = "ClusterFirst" - restart_policy = "Always" - } - } - } -} diff --git a/twenty/code/k8s/terraform/deployment-server.tf b/twenty/code/k8s/terraform/deployment-server.tf deleted file mode 100644 index a8bb43b..0000000 --- a/twenty/code/k8s/terraform/deployment-server.tf +++ /dev/null @@ -1,138 +0,0 @@ -resource "kubernetes_deployment" "twentycrm_server" { - metadata { - name = "${var.twentycrm_app_name}-server" - namespace = kubernetes_namespace.twentycrm.metadata.0.name - labels = { - app = "${var.twentycrm_app_name}-server" - } - } - - spec { - replicas = var.twentycrm_server_replicas - selector { - match_labels = { - app = "${var.twentycrm_app_name}-server" - } - } - - strategy { - type = "RollingUpdate" - rolling_update { - max_surge = "1" - max_unavailable = "1" - } - } - - template { - metadata { - labels = { - app = "${var.twentycrm_app_name}-server" - } - } - - spec { - container { - image = var.twentycrm_server_image - name = var.twentycrm_app_name - stdin = true - tty = true - - env { - name = "NODE_PORT" - value = "3000" - } - - env { - name = "SERVER_URL" - value = var.twentycrm_app_hostname - } - - env { - name = "PG_DATABASE_URL" - value = "postgres://twenty:${var.twentycrm_pgdb_admin_password}@${kubernetes_service.twentycrm_db.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local/default" - } - env { - name = "REDIS_URL" - value = "redis://${kubernetes_service.twentycrm_redis.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local:6379" - } - env { - name = "DISABLE_DB_MIGRATIONS" - value = "false" - } - - env { - name = "STORAGE_TYPE" - value = "local" - } - env { - name = "ACCESS_TOKEN_EXPIRES_IN" - value = "7d" - } - env { - name = "LOGIN_TOKEN_EXPIRES_IN" - value = "1h" - } - env { - name = "APP_SECRET" - value_from { - secret_key_ref { - name = "tokens" - key = "accessToken" - } - } - } - - port { - container_port = 3000 - protocol = "TCP" - } - - resources { - requests = { - cpu = "250m" - memory = "256Mi" - } - limits = { - cpu = "1000m" - memory = "1024Mi" - } - } - - volume_mount { - name = "server-data" - mount_path = var.twentycrm_server_data_mount_path - } - - volume_mount { - name = "docker-data" - mount_path = var.twentycrm_docker_data_mount_path - } - } - - volume { - name = "server-data" - - persistent_volume_claim { - claim_name = kubernetes_persistent_volume_claim.server.metadata.0.name - } - } - - volume { - name = "docker-data" - - persistent_volume_claim { - claim_name = kubernetes_persistent_volume_claim.docker_data.metadata.0.name - } - } - - dns_policy = "ClusterFirst" - restart_policy = "Always" - } - } - } - depends_on = [ - kubernetes_deployment.twentycrm_db, - kubernetes_deployment.twentycrm_redis, - kubernetes_secret.twentycrm_tokens - ] -} diff --git a/twenty/code/k8s/terraform/deployment-worker.tf b/twenty/code/k8s/terraform/deployment-worker.tf deleted file mode 100644 index 9e4da3e..0000000 --- a/twenty/code/k8s/terraform/deployment-worker.tf +++ /dev/null @@ -1,99 +0,0 @@ -resource "kubernetes_deployment" "twentycrm_worker" { - metadata { - name = "${var.twentycrm_app_name}-worker" - namespace = kubernetes_namespace.twentycrm.metadata.0.name - labels = { - app = "${var.twentycrm_app_name}-worker" - } - } - - spec { - replicas = var.twentycrm_worker_replicas - selector { - match_labels = { - app = "${var.twentycrm_app_name}-worker" - } - } - - strategy { - type = "RollingUpdate" - rolling_update { - max_surge = "1" - max_unavailable = "1" - } - } - - template { - metadata { - labels = { - app = "${var.twentycrm_app_name}-worker" - } - } - - spec { - container { - image = var.twentycrm_server_image - name = var.twentycrm_app_name - stdin = true - tty = true - command = ["yarn", "worker:prod"] - - env { - name = "SERVER_URL" - value = var.twentycrm_app_hostname - } - - env { - name = "PG_DATABASE_URL" - value = "postgres://twenty:${var.twentycrm_pgdb_admin_password}@${kubernetes_service.twentycrm_db.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local/default" - } - - env { - name = "REDIS_URL" - value = "redis://${kubernetes_service.twentycrm_redis.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local:6379" - } - - env { - name = "DISABLE_DB_MIGRATIONS" - value = "true" #it already runs on the server - } - - env { - name = "STORAGE_TYPE" - value = "local" - } - - env { - name = "APP_SECRET" - value_from { - secret_key_ref { - name = "tokens" - key = "accessToken" - } - } - } - - resources { - requests = { - cpu = "250m" - memory = "1024Mi" - } - limits = { - cpu = "1000m" - memory = "2048Mi" - } - } - } - - dns_policy = "ClusterFirst" - restart_policy = "Always" - } - } - } - depends_on = [ - kubernetes_deployment.twentycrm_db, - kubernetes_deployment.twentycrm_redis, - kubernetes_deployment.twentycrm_server, - kubernetes_secret.twentycrm_tokens, - ] -} diff --git a/twenty/code/k8s/terraform/ingress.tf b/twenty/code/k8s/terraform/ingress.tf deleted file mode 100644 index f8a2877..0000000 --- a/twenty/code/k8s/terraform/ingress.tf +++ /dev/null @@ -1,30 +0,0 @@ -resource "kubernetes_ingress" "twentycrm" { - wait_for_load_balancer = true - metadata { - name = "${var.twentycrm_app_name}-ingress" - namespace = kubernetes_namespace.twentycrm.metadata.0.name - annotations = { - "kubernetes.io/ingress.class" = "nginx" - "nginx.ingress.kubernetes.io/configuration-snippet" = </dev/null; then - echo -e "\t❌ Docker is not installed or not in PATH. Please install Docker first.\n\t\tSee https://docs.docker.com/get-docker/" - exit 1 -fi -# Check if docker compose plugin is installed -if ! docker compose version &>/dev/null; then - echo -e "\t❌ Docker Compose is not installed or not in PATH (n.b. docker-compose is deprecated)\n\t\tUpdate docker or install docker-compose-plugin\n\t\tOn Linux: sudo apt-get install docker-compose-plugin\n\t\tSee https://docs.docker.com/compose/install/" - exit 1 -fi -# Check if docker is started -if ! docker info &>/dev/null; then - echo -e "\t❌ Docker is not running.\n\t\tPlease start Docker Desktop, Docker or check documentation at https://docs.docker.com/config/daemon/start/" - exit 1 -fi -if ! command -v curl &>/dev/null; then - echo -e "\t❌ Curl is not installed or not in PATH.\n\t\tOn macOS: brew install curl\n\t\tOn Linux: sudo apt install curl" - exit 1 -fi - -# Check if docker compose version is >= 2 -if [ "$(docker compose version --short | cut -d' ' -f3 | cut -d'.' -f1)" -lt 2 ]; then - echo -e "\t❌ Docker Compose is outdated. Please update Docker Compose to version 2 or higher.\n\t\tSee https://docs.docker.com/compose/install/linux/" - exit 1 -fi -# Check if docker-compose is installed, if so issue a warning if version is < 2 -if command -v docker-compose &>/dev/null; then - if [ "$(docker-compose version --short | cut -d' ' -f3 | cut -d'.' -f1)" -lt 2 ]; then - echo -e "\n\t⚠️ 'docker-compose' is installed but outdated. Make sure to use 'docker compose' or to upgrade 'docker-compose' to version 2.\n\t\tSee https://docs.docker.com/compose/install/standalone/\n" - fi -fi - -# Catch errors -set -e -function on_exit { - # $? is the exit status of the last command executed - local exit_status=$? - if [ $exit_status -ne 0 ]; then - echo "❌ Something went wrong, exiting: $exit_status" - fi -} -trap on_exit EXIT - -# Use environment variables VERSION and BRANCH, with defaults if not set -version=${VERSION:-$(curl -s "https://hub.docker.com/v2/repositories/twentycrm/twenty/tags" | grep -o '"name":"[^"]*"' | grep -v 'latest' | cut -d'"' -f4 | sort -V | tail -n1)} -branch=${BRANCH:-$(curl -s https://api.github.com/repos/twentyhq/twenty/tags | grep '"name":' | head -n 1 | cut -d '"' -f 4)} - -echo "🚀 Using docker version $version and Github branch $branch" - -dir_name="twenty" -function ask_directory { - read -p "📁 Enter the directory name to setup the project (default: $dir_name): " answer - if [ -n "$answer" ]; then - dir_name=$answer - fi -} - -ask_directory - -while [ -d "$dir_name" ]; do - read -p "🚫 Directory '$dir_name' already exists. Do you want to overwrite it? (y/N) " answer - if [ "$answer" = "y" ]; then - break - else - ask_directory - fi -done - -# Create a directory named twenty -echo "📁 Creating directory '$dir_name'" -mkdir -p "$dir_name" && cd "$dir_name" || { echo "❌ Failed to create/access directory '$dir_name'"; exit 1; } - -# Copy twenty/packages/twenty-docker/docker-compose.yml in it -echo -e "\t• Copying docker-compose.yml" -curl -sLo docker-compose.yml https://raw.githubusercontent.com/twentyhq/twenty/$branch/packages/twenty-docker/docker-compose.yml - -# Copy twenty/packages/twenty-docker/.env.example to .env -echo -e "\t• Setting up .env file" -curl -sLo .env https://raw.githubusercontent.com/twentyhq/twenty/$branch/packages/twenty-docker/.env.example - -# Replace TAG=latest by TAG= -if [[ $(uname) == "Darwin" ]]; then - # Running on macOS - sed -i '' "s/TAG=latest/TAG=$version/g" .env -else - # Assuming Linux - sed -i'' "s/TAG=latest/TAG=$version/g" .env -fi - -# Generate random strings for secrets -echo "# === Randomly generated secret ===" >> .env -echo "APP_SECRET=$(openssl rand -base64 32)" >> .env - -echo "" >> .env -echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 32)" >> .env - -echo -e "\t• .env configuration completed" - -port=3000 -# Check if command nc is available -if command -v nc &> /dev/null; then - # Check if port 3000 is already in use, propose to change it - while nc -zv localhost $port &>/dev/null; do - read -p "🚫 Port $port is already in use. Do you want to use another port? (Y/n) " answer - if [ "$answer" = "n" ]; then - continue - fi - read -p "Enter a new port number: " new_port - if [[ $(uname) == "Darwin" ]]; then - sed -i '' "s/$port:$port/$new_port:$port/g" docker-compose.yml - sed -E -i '' "s|^SERVER_URL=http://localhost:[0-9]+|SERVER_URL=http://localhost:$new_port|g" .env - else - sed -i'' "s/$port:$port/$new_port:$port/g" docker-compose.yml - sed -E -i'' "s|^SERVER_URL=http://localhost:[0-9]+|SERVER_URL=http://localhost:$new_port|g" .env - fi - port=$new_port - done -fi - -# Ask user if they want to start the project -read -p "🚀 Do you want to start the project now? (Y/n) " answer -if [ "$answer" = "n" ]; then - echo "✅ Project setup completed. Run 'docker compose up -d' to start." - exit 0 -else - echo "🐳 Starting Docker containers..." - docker compose up -d - # Check if port is listening - echo "Waiting for server to be healthy, it might take a few minutes while we initialize the database..." - # Tail logs of the server until it's ready - docker compose logs -f server & - pid=$! - while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do - sleep 1 - done - kill $pid - echo "" - echo "✅ Server is up and running" -fi - -function ask_open_browser { - read -p "🌐 Do you want to open the project in your browser? (Y/n) " answer - if [ "$answer" = "n" ]; then - echo "✅ Setup completed. Access your project at http://localhost:$port" - exit 0 - fi -} - -# Ask user if they want to open the project -# Running on macOS -if [[ $(uname) == "Darwin" ]]; then - ask_open_browser - - open "http://localhost:$port" -# Assuming Linux -else - # xdg-open is not installed, we could be running in a non gui environment - if command -v xdg-open >/dev/null 2>&1; then - ask_open_browser - - xdg-open "http://localhost:$port" - else - echo "✅ Setup completed. Your project is available at http://localhost:$port" - fi -fi diff --git a/twenty/code/twenty-postgres-spilo/Dockerfile b/twenty/code/twenty-postgres-spilo/Dockerfile deleted file mode 100644 index 9a84c12..0000000 --- a/twenty/code/twenty-postgres-spilo/Dockerfile +++ /dev/null @@ -1,68 +0,0 @@ -ARG POSTGRES_VERSION=15 -ARG SPILO_VERSION=3.2-p1 -ARG WRAPPERS_VERSION=0.2.0 - -# Build the mysql_fdw extension -FROM debian:bookworm AS build-mysql_fdw -ARG POSTGRES_VERSION - -ENV DEBIAN_FRONTEND=noninteractive -RUN apt update && \ - apt install -y \ - build-essential \ - git \ - postgresql-server-dev-${POSTGRES_VERSION} \ - default-libmysqlclient-dev && \ - rm -rf /var/lib/apt/lists/* - -# Install mysql_fdw -RUN git clone https://github.com/EnterpriseDB/mysql_fdw.git -WORKDIR /mysql_fdw -RUN make USE_PGXS=1 - - -# Build libssl for wrappers -FROM ubuntu:22.04 AS build-libssl - -ENV DEBIAN_FRONTEND=noninteractive -RUN apt update && \ - apt install -y \ - build-essential \ - git && \ - rm -rf /var/lib/apt/lists/* - -WORKDIR /build -RUN git clone --branch OpenSSL_1_1_1-stable https://github.com/openssl/openssl.git -WORKDIR /build/openssl -RUN ./config && make && make install - - -# Extend the Spilo image with the mysql_fdw extensions -FROM ghcr.io/zalando/spilo-${POSTGRES_VERSION}:${SPILO_VERSION} -ARG POSTGRES_VERSION -ARG WRAPPERS_VERSION -ARG TARGETARCH - -# Install precompiled supabase wrappers extensions -RUN set -eux; \ - ARCH="$(dpkg --print-architecture)"; \ - case "${ARCH}" in \ - aarch64|arm64) TARGETARCH='arm64';; \ - amd64|x86_64) TARGETARCH='amd64';; \ - *) echo "Unsupported arch: ${ARCH}"; exit 1;; \ - esac; - -RUN apt update && apt install default-libmysqlclient-dev -y && rm -rf /var/lib/apt/lists/* - -RUN curl -L "https://github.com/supabase/wrappers/releases/download/v${WRAPPERS_VERSION}/wrappers-v${WRAPPERS_VERSION}-pg${POSTGRES_VERSION}-${TARGETARCH}-linux-gnu.deb" -o wrappers.deb && \ - dpkg --install wrappers.deb && \ - rm wrappers.deb - -COPY --from=build-libssl /usr/local/lib/libssl* /usr/local/lib/libcrypto* /usr/lib/ -COPY --from=build-libssl /usr/local/lib/engines-1.1 /usr/lib/engines-1.1 - -# Copy mysql_fdw -COPY --from=build-mysql_fdw /mysql_fdw/mysql_fdw.so \ - /usr/lib/postgresql/${POSTGRES_VERSION}/lib/mysql_fdw.so -COPY --from=build-mysql_fdw /mysql_fdw/mysql_fdw*.sql /mysql_fdw/mysql_fdw.control /mysql_fdw/mysql_fdw_pushdown.config \ - /usr/share/postgresql/${POSTGRES_VERSION}/extension/ diff --git a/twenty/code/twenty-website/Dockerfile b/twenty/code/twenty-website/Dockerfile deleted file mode 100644 index 2ff7cb8..0000000 --- a/twenty/code/twenty-website/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -FROM node:24-alpine AS twenty-website-build - - -WORKDIR /app - -COPY ./package.json . -COPY ./yarn.lock . -COPY ./.yarnrc.yml . -COPY ./.yarn/releases /app/.yarn/releases -COPY ./.yarn/patches /app/.yarn/patches -COPY ./tools/eslint-rules /app/tools/eslint-rules -COPY ./packages/twenty-ui/package.json /app/packages/twenty-ui/ -COPY ./packages/twenty-shared/package.json /app/packages/twenty-shared/ -COPY ./packages/twenty-website/package.json /app/packages/twenty-website/package.json - -RUN yarn - -ENV KEYSTATIC_GITHUB_CLIENT_ID="" -ENV KEYSTATIC_GITHUB_CLIENT_SECRET="" -ENV KEYSTATIC_SECRET="" -ENV NEXT_PUBLIC_KEYSTATIC_GITHUB_APP_SLUG="" - -COPY ./packages/twenty-ui /app/packages/twenty-ui -COPY ./packages/twenty-website /app/packages/twenty-website -RUN npx nx build twenty-website - -FROM node:24-alpine AS twenty-website - -WORKDIR /app/packages/twenty-website - -COPY --from=twenty-website-build /app /app - -WORKDIR /app/packages/twenty-website - -LABEL org.opencontainers.image.source=https://github.com/twentyhq/twenty -LABEL org.opencontainers.image.description="This image provides a consistent and reproducible environment for the website." - -RUN chown -R 1000 /app - -# Use non root user with uid 1000 -USER 1000 - -CMD ["/bin/sh", "-c", "npx nx start"] \ No newline at end of file diff --git a/twenty/code/twenty/Dockerfile b/twenty/code/twenty/Dockerfile deleted file mode 100644 index 7818be7..0000000 --- a/twenty/code/twenty/Dockerfile +++ /dev/null @@ -1,82 +0,0 @@ -# Base image for common dependencies -FROM node:24-alpine AS common-deps - -WORKDIR /app - -# Copy only the necessary files for dependency resolution -COPY ./package.json ./yarn.lock ./.yarnrc.yml ./tsconfig.base.json ./nx.json /app/ -COPY ./.yarn/releases /app/.yarn/releases -COPY ./.yarn/patches /app/.yarn/patches - -COPY ./.prettierrc /app/ -COPY ./packages/twenty-emails/package.json /app/packages/twenty-emails/ -COPY ./packages/twenty-server/package.json /app/packages/twenty-server/ -COPY ./packages/twenty-server/patches /app/packages/twenty-server/patches -COPY ./packages/twenty-ui/package.json /app/packages/twenty-ui/ -COPY ./packages/twenty-shared/package.json /app/packages/twenty-shared/ -COPY ./packages/twenty-front/package.json /app/packages/twenty-front/ - -# Install all dependencies -RUN yarn && yarn cache clean && npx nx reset - - -# Build the back -FROM common-deps AS twenty-server-build - -# Copy sourcecode after installing dependences to accelerate subsequents builds -COPY ./packages/twenty-emails /app/packages/twenty-emails -COPY ./packages/twenty-shared /app/packages/twenty-shared -COPY ./packages/twenty-server /app/packages/twenty-server - -RUN npx nx run twenty-server:build - -RUN yarn workspaces focus --production twenty-emails twenty-shared twenty-server - -# Build the front -FROM common-deps AS twenty-front-build - -ARG REACT_APP_SERVER_BASE_URL - -COPY ./packages/twenty-front /app/packages/twenty-front -COPY ./packages/twenty-ui /app/packages/twenty-ui -COPY ./packages/twenty-shared /app/packages/twenty-shared -RUN npx nx build twenty-front - - -# Final stage: Run the application -FROM node:24-alpine AS twenty - -# Used to run healthcheck in docker -RUN apk add --no-cache curl jq - -RUN npm install -g tsx - -RUN apk add --no-cache postgresql-client - -COPY ./packages/twenty-docker/twenty/entrypoint.sh /app/entrypoint.sh -RUN chmod +x /app/entrypoint.sh -WORKDIR /app/packages/twenty-server - -ARG REACT_APP_SERVER_BASE_URL -ENV REACT_APP_SERVER_BASE_URL=$REACT_APP_SERVER_BASE_URL - -ARG APP_VERSION -ENV APP_VERSION=$APP_VERSION - -# Copy built applications from previous stages -COPY --chown=1000 --from=twenty-server-build /app /app -COPY --chown=1000 --from=twenty-server-build /app/packages/twenty-server /app/packages/twenty-server -COPY --chown=1000 --from=twenty-front-build /app/packages/twenty-front/build /app/packages/twenty-server/dist/front - -# Set metadata and labels -LABEL org.opencontainers.image.source=https://github.com/twentyhq/twenty -LABEL org.opencontainers.image.description="This image provides a consistent and reproducible environment for the backend and frontend, ensuring it deploys faster and runs the same way regardless of the deployment environment." - -RUN mkdir -p /app/.local-storage /app/packages/twenty-server/.local-storage && \ - chown -R 1000:1000 /app - -# Use non root user with uid 1000 -USER 1000 - -CMD ["node", "dist/src/main"] -ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/twenty/code/twenty/entrypoint.sh b/twenty/code/twenty/entrypoint.sh deleted file mode 100755 index 0175a0a..0000000 --- a/twenty/code/twenty/entrypoint.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -set -e - -setup_and_migrate_db() { - if [ "${DISABLE_DB_MIGRATIONS}" = "true" ]; then - echo "Database setup and migrations are disabled, skipping..." - return - fi - - echo "Running database setup and migrations..." - PGUSER=$(echo $PG_DATABASE_URL | awk -F '//' '{print $2}' | awk -F ':' '{print $1}') - PGPASS=$(echo $PG_DATABASE_URL | awk -F ':' '{print $3}' | awk -F '@' '{print $1}') - PGHOST=$(echo $PG_DATABASE_URL | awk -F '@' '{print $2}' | awk -F ':' '{print $1}') - PGPORT=$(echo $PG_DATABASE_URL | awk -F ':' '{print $4}' | awk -F '/' '{print $1}') - PGDATABASE=$(echo $PG_DATABASE_URL | awk -F '/' '{print $NF}' | cut -d'?' -f1) - - # Creating the database if it doesn't exist - db_count=$(PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -tAc "SELECT COUNT(*) FROM pg_database WHERE datname = '${PGDATABASE}'") - if [ "$db_count" = "0" ]; then - echo "Database ${PGDATABASE} does not exist, creating..." - PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d postgres -c "CREATE DATABASE \"${PGDATABASE}\"" - fi - - # Run setup and migration scripts - has_schema=$(PGPASSWORD=${PGPASS} psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d ${PGDATABASE} -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.schemata WHERE schema_name = 'core')") - if [ "$has_schema" = "f" ]; then - echo "Database appears to be empty, running migrations." - NODE_OPTIONS="--max-old-space-size=1500" tsx ./scripts/setup-db.ts - yarn database:migrate:prod - fi - - yarn command:prod upgrade - echo "Successfully migrated DB!" -} - -register_background_jobs() { - if [ "${DISABLE_CRON_JOBS_REGISTRATION}" = "true" ]; then - echo "Cron job registration is disabled, skipping..." - return - fi - - echo "Registering background sync jobs..." - if yarn command:prod cron:register:all; then - echo "Successfully registered all background sync jobs!" - else - echo "Warning: Failed to register background jobs, but continuing startup..." - fi -} - -setup_and_migrate_db -register_background_jobs - -# Continue with the original Docker command -exec "$@" diff --git a/twenty/update.js b/twenty/update.js deleted file mode 100644 index b6131b7..0000000 --- a/twenty/update.js +++ /dev/null @@ -1,25 +0,0 @@ -import utils from "../utils.js"; - -await utils.cloneOrPullRepo({ repo: "git@github.com:twentyhq/twenty.git" }); -await utils.copyDir("./repo/packages/twenty-docker", "./code"); - -await utils.removeContainerNames("./code/docker-compose.yml"); -await utils.removePorts("./code/docker-compose.yml"); - -await utils.searchReplace( - "./code/.env.example", - "#REDIS_URL=redis://redis:6379", - "REDIS_URL=redis://redis:6379" -); - -await utils.searchReplace( - "./code/.env.example", - "SERVER_URL=http://localhost:3000", - "SERVER_URL=https://$(PRIMARY_DOMAIN)" -); - -await utils.searchReplace( - "./code/.env.example", - "# APP_SECRET=replace_me_with_a_random_string", - "APP_SECRET=replace_me_with_a_random_string" -); diff --git a/utils.js b/utils.js index d22ef20..2644f31 100644 --- a/utils.js +++ b/utils.js @@ -81,6 +81,18 @@ async function searchReplace(path, search, replace) { await fs.promises.writeFile(path, newFile); } +async function removeDir(path) { + console.log(`Removing directory ${path}`); + + await execa("rm", ["-rf", path]); +} + +async function renameDir(src, dest) { + console.log(`Renaming directory ${src} to ${dest}`); + + await execa("mv", [src, dest]); +} + export default { cloneOrPullRepo, removeContainerNames, @@ -89,4 +101,6 @@ export default { downloadFile, renameFile, searchReplace, + removeDir, + renameDir, };