plane.so
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
# Supabase
|
||||||
|
|
||||||
|
- copied from https://github.com/makeplane/plane
|
||||||
|
- removed `ports`
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
APP_DOMAIN=localhost
|
||||||
|
APP_RELEASE=stable
|
||||||
|
|
||||||
|
WEB_REPLICAS=1
|
||||||
|
SPACE_REPLICAS=1
|
||||||
|
ADMIN_REPLICAS=1
|
||||||
|
API_REPLICAS=1
|
||||||
|
|
||||||
|
NGINX_PORT=80
|
||||||
|
WEB_URL=http://${APP_DOMAIN}
|
||||||
|
DEBUG=0
|
||||||
|
SENTRY_DSN=
|
||||||
|
SENTRY_ENVIRONMENT=production
|
||||||
|
CORS_ALLOWED_ORIGINS=http://${APP_DOMAIN}
|
||||||
|
|
||||||
|
#DB SETTINGS
|
||||||
|
PGHOST=plane-db
|
||||||
|
PGDATABASE=plane
|
||||||
|
POSTGRES_USER=plane
|
||||||
|
POSTGRES_PASSWORD=plane
|
||||||
|
POSTGRES_DB=plane
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
PGDATA=/var/lib/postgresql/data
|
||||||
|
DATABASE_URL=
|
||||||
|
|
||||||
|
# REDIS SETTINGS
|
||||||
|
REDIS_HOST=plane-redis
|
||||||
|
REDIS_PORT=6379
|
||||||
|
REDIS_URL=
|
||||||
|
|
||||||
|
# Secret Key
|
||||||
|
SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5
|
||||||
|
|
||||||
|
# DATA STORE SETTINGS
|
||||||
|
USE_MINIO=1
|
||||||
|
AWS_REGION=
|
||||||
|
AWS_ACCESS_KEY_ID=access-key
|
||||||
|
AWS_SECRET_ACCESS_KEY=secret-key
|
||||||
|
AWS_S3_ENDPOINT_URL=http://plane-minio:9000
|
||||||
|
AWS_S3_BUCKET_NAME=uploads
|
||||||
|
MINIO_ROOT_USER=access-key
|
||||||
|
MINIO_ROOT_PASSWORD=secret-key
|
||||||
|
BUCKET_NAME=uploads
|
||||||
|
FILE_SIZE_LIMIT=5242880
|
||||||
|
|
||||||
|
# Gunicorn Workers
|
||||||
|
GUNICORN_WORKERS=1
|
||||||
|
|
||||||
|
# UNCOMMENT `DOCKER_PLATFORM` IF YOU ARE ON `ARM64` AND DOCKER IMAGE IS NOT AVAILABLE FOR RESPECTIVE `APP_RELEASE`
|
||||||
|
# DOCKER_PLATFORM=linux/amd64
|
||||||
|
|
||||||
@@ -0,0 +1,483 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Option 1 - Using Cloud Server</summary>
|
||||||
|
<p>Best way to start is to create EC2 machine on AWS. It must have minimum of 2vCPU and 4GB RAM.</p>
|
||||||
|
<p>Run the below command to install docker engine.</p>
|
||||||
|
|
||||||
|
`curl -fsSL https://get.docker.com | sh -`
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Option 2 - Using Desktop</summary>
|
||||||
|
|
||||||
|
#### For Mac
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li> Download Docker Desktop for Mac from the <a href="https://hub.docker.com/editions/community/docker-ce-desktop-mac/" target="_blank">Docker Hub</a>. </li>
|
||||||
|
<li> Double-click the downloaded `.dmg` file and drag the Docker app icon to the Applications folder. </li>
|
||||||
|
<li>Open Docker Desktop from the Applications folder. You might be asked to provide your system password to install additional software.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
#### For Windows:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>Download Docker Desktop for Windows from the <a href="https://hub.docker.com/editions/community/docker-ce-desktop-windows/" target="_blank">Docker Hub</a>.</li>
|
||||||
|
<li>Run the installer and follow the instructions. You might be asked to enable Hyper-V and "Containers" Windows features.</li>
|
||||||
|
<li>Open Docker Desktop. You might be asked to log out and log back in, or restart your machine, for changes to take effect.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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 Stable Release
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir plane-selfhost
|
||||||
|
|
||||||
|
cd plane-selfhost
|
||||||
|
|
||||||
|
curl -fsSL -o setup.sh https://raw.githubusercontent.com/makeplane/plane/master/deploy/selfhost/install.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.
|
||||||
|
|
||||||
|
```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]: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
For the 1st time setup, type "1" as action input.
|
||||||
|
|
||||||
|
This will create a create a folder `plane-app` or `plane-app-preview` (in case of preview deployment) 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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. _<span style="color: #fcba03">You can use any text editor to edit this file</span>_.
|
||||||
|
|
||||||
|
> `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
|
||||||
|
|
||||||
|
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.
|
||||||
|

|
||||||
|
|
||||||
|
Be patient as it might take sometime based on download speed and system configuration. If all goes well, you must see something like this
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
In case you want to make changes to `.env` variables, we suggest you to stop the services before doing that.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Restarting the Server
|
||||||
|
|
||||||
|
In case you want to make changes to `.env` variables, without stopping the server or you noticed some abnormalies in services, you can restart the services with RESTART 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
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
0) Back to Main Menu
|
||||||
|
|
||||||
|
Service:
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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://raw.githubusercontent.com/makeplane/plane/master/deploy/selfhost/restore.sh
|
||||||
|
chmod +x restore.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Execute the command below to restore your data.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./restore.sh <path to backup folder containing *.tar.gz files>
|
||||||
|
```
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>Upgrading from v0.13.2 to v0.14.x</h2></summary>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
In case of successful migration, it will be a silent exit without error.
|
||||||
|
|
||||||
|
Now its time to restart v0.14.0 setup.
|
||||||
|
</details>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
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
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
x-app-env: &app-env
|
||||||
|
environment:
|
||||||
|
- NGINX_PORT=${NGINX_PORT:-80}
|
||||||
|
- WEB_URL=${WEB_URL:-http://localhost}
|
||||||
|
- DEBUG=${DEBUG:-0}
|
||||||
|
- SENTRY_DSN=${SENTRY_DSN}
|
||||||
|
- SENTRY_ENVIRONMENT=${SENTRY_ENVIRONMENT:-"production"}
|
||||||
|
- CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS}
|
||||||
|
# Gunicorn Workers
|
||||||
|
- GUNICORN_WORKERS=${GUNICORN_WORKERS:-1}
|
||||||
|
#DB SETTINGS
|
||||||
|
- PGHOST=${PGHOST:-plane-db}
|
||||||
|
- PGDATABASE=${PGDATABASE:-plane}
|
||||||
|
- POSTGRES_USER=${POSTGRES_USER:-plane}
|
||||||
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-plane}
|
||||||
|
- POSTGRES_DB=${POSTGRES_DB:-plane}
|
||||||
|
- POSTGRES_PORT=${POSTGRES_PORT:-5432}
|
||||||
|
- PGDATA=${PGDATA:-/var/lib/postgresql/data}
|
||||||
|
- DATABASE_URL=${DATABASE_URL:-postgresql://plane:plane@plane-db/plane}
|
||||||
|
# REDIS SETTINGS
|
||||||
|
- REDIS_HOST=${REDIS_HOST:-plane-redis}
|
||||||
|
- REDIS_PORT=${REDIS_PORT:-6379}
|
||||||
|
- REDIS_URL=${REDIS_URL:-redis://plane-redis:6379/}
|
||||||
|
# Application secret
|
||||||
|
- SECRET_KEY=${SECRET_KEY:-60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5}
|
||||||
|
# DATA STORE SETTINGS
|
||||||
|
- USE_MINIO=${USE_MINIO:-1}
|
||||||
|
- AWS_REGION=${AWS_REGION:-""}
|
||||||
|
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-"access-key"}
|
||||||
|
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-"secret-key"}
|
||||||
|
- AWS_S3_ENDPOINT_URL=${AWS_S3_ENDPOINT_URL:-http://plane-minio:9000}
|
||||||
|
- AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME:-uploads}
|
||||||
|
- MINIO_ROOT_USER=${MINIO_ROOT_USER:-"access-key"}
|
||||||
|
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-"secret-key"}
|
||||||
|
- BUCKET_NAME=${BUCKET_NAME:-uploads}
|
||||||
|
- FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT:-5242880}
|
||||||
|
# Admin and Space URLs
|
||||||
|
- ADMIN_BASE_URL=${ADMIN_BASE_URL}
|
||||||
|
- SPACE_BASE_URL=${SPACE_BASE_URL}
|
||||||
|
- APP_BASE_URL=${APP_BASE_URL}
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-frontend:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: node web/server.js web
|
||||||
|
deploy:
|
||||||
|
replicas: ${WEB_REPLICAS:-1}
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- worker
|
||||||
|
|
||||||
|
space:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-space:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: node space/server.js space
|
||||||
|
deploy:
|
||||||
|
replicas: ${SPACE_REPLICAS:-1}
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- worker
|
||||||
|
- web
|
||||||
|
|
||||||
|
admin:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-admin:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: node admin/server.js admin
|
||||||
|
deploy:
|
||||||
|
replicas: ${ADMIN_REPLICAS:-1}
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- web
|
||||||
|
|
||||||
|
api:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ./bin/docker-entrypoint-api.sh
|
||||||
|
deploy:
|
||||||
|
replicas: ${API_REPLICAS:-1}
|
||||||
|
volumes:
|
||||||
|
- logs_api:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
|
||||||
|
worker:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ./bin/docker-entrypoint-worker.sh
|
||||||
|
volumes:
|
||||||
|
- logs_worker:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
|
||||||
|
beat-worker:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ./bin/docker-entrypoint-beat.sh
|
||||||
|
volumes:
|
||||||
|
- logs_beat-worker:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
|
||||||
|
migrator:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: "no"
|
||||||
|
command: ./bin/docker-entrypoint-migrator.sh
|
||||||
|
volumes:
|
||||||
|
- logs_migrator:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
|
||||||
|
plane-db:
|
||||||
|
<<: *app-env
|
||||||
|
image: postgres:15.5-alpine
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: postgres -c 'max_connections=1000'
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
plane-redis:
|
||||||
|
<<: *app-env
|
||||||
|
image: valkey/valkey:7.2.5-alpine
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- redisdata:/data
|
||||||
|
|
||||||
|
plane-minio:
|
||||||
|
<<: *app-env
|
||||||
|
image: minio/minio:latest
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
command: server /export --console-address ":9090"
|
||||||
|
volumes:
|
||||||
|
- uploads:/export
|
||||||
|
|
||||||
|
# Comment this if you already have a reverse proxy running
|
||||||
|
proxy:
|
||||||
|
<<: *app-env
|
||||||
|
image: ${DOCKERHUB_USER:-makeplane}/plane-proxy:${APP_RELEASE:-stable}
|
||||||
|
platform: ${DOCKER_PLATFORM:-}
|
||||||
|
pull_policy: if_not_present
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- web
|
||||||
|
- api
|
||||||
|
- space
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
redisdata:
|
||||||
|
uploads:
|
||||||
|
logs_api:
|
||||||
|
logs_worker:
|
||||||
|
logs_beat-worker:
|
||||||
|
logs_migrator:
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Executable
+559
@@ -0,0 +1,559 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
BRANCH=${BRANCH:-master}
|
||||||
|
SCRIPT_DIR=$PWD
|
||||||
|
SERVICE_FOLDER=plane-app
|
||||||
|
PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER
|
||||||
|
export APP_RELEASE="stable"
|
||||||
|
export DOCKERHUB_USER=makeplane
|
||||||
|
export PULL_POLICY=${PULL_POLICY:-if_not_present}
|
||||||
|
|
||||||
|
CPU_ARCH=$(uname -m)
|
||||||
|
|
||||||
|
mkdir -p $PLANE_INSTALL_DIR/archive
|
||||||
|
DOCKER_FILE_PATH=$PLANE_INSTALL_DIR/docker-compose.yaml
|
||||||
|
DOCKER_ENV_PATH=$PLANE_INSTALL_DIR/plane.env
|
||||||
|
|
||||||
|
function print_header() {
|
||||||
|
clear
|
||||||
|
|
||||||
|
cat <<"EOF"
|
||||||
|
--------------------------------------------
|
||||||
|
____ _ /////////
|
||||||
|
| _ \| | __ _ _ __ ___ /////////
|
||||||
|
| |_) | |/ _` | '_ \ / _ \ ///// /////
|
||||||
|
| __/| | (_| | | | | __/ ///// /////
|
||||||
|
|_| |_|\__,_|_| |_|\___| ////
|
||||||
|
////
|
||||||
|
--------------------------------------------
|
||||||
|
Project management tool from the future
|
||||||
|
--------------------------------------------
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
function spinner() {
|
||||||
|
local pid=$1
|
||||||
|
local delay=.5
|
||||||
|
local spinstr='|/-\'
|
||||||
|
|
||||||
|
if ! ps -p "$pid" > /dev/null; then
|
||||||
|
echo "Invalid PID: $pid"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
while ps -p "$pid" > /dev/null; do
|
||||||
|
local temp=${spinstr#?}
|
||||||
|
printf " [%c] " "$spinstr" >&2
|
||||||
|
local spinstr=$temp${spinstr%"$temp"}
|
||||||
|
sleep $delay
|
||||||
|
printf "\b\b\b\b\b\b" >&2
|
||||||
|
done
|
||||||
|
printf " \b\b\b\b" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
function initialize(){
|
||||||
|
printf "Please wait while we check the availability of Docker images for the selected release ($APP_RELEASE) with ${CPU_ARCH^^} support." >&2
|
||||||
|
|
||||||
|
if [ "$CUSTOM_BUILD" == "true" ]; then
|
||||||
|
echo "" >&2
|
||||||
|
echo "" >&2
|
||||||
|
echo "${CPU_ARCH^^} images are not available for selected release ($APP_RELEASE)." >&2
|
||||||
|
echo "build"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local IMAGE_NAME=makeplane/plane-proxy
|
||||||
|
local IMAGE_TAG=${APP_RELEASE}
|
||||||
|
docker manifest inspect "${IMAGE_NAME}:${IMAGE_TAG}" | grep -q "\"architecture\": \"${CPU_ARCH}\"" &
|
||||||
|
local pid=$!
|
||||||
|
spinner "$pid"
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
|
||||||
|
wait "$pid"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Plane supports ${CPU_ARCH}" >&2
|
||||||
|
echo "available"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "" >&2
|
||||||
|
echo "" >&2
|
||||||
|
echo "${CPU_ARCH^^} images are not available for selected release ($APP_RELEASE)." >&2
|
||||||
|
echo "" >&2
|
||||||
|
echo "build"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
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 key exists, update the value
|
||||||
|
sed -i "s/^$key=.*/$key=$value/g" "$file"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "File not found: $file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCustomVariables(){
|
||||||
|
echo "Updating custom variables..." >&2
|
||||||
|
updateEnvFile "DOCKERHUB_USER" "$DOCKERHUB_USER" "$DOCKER_ENV_PATH"
|
||||||
|
updateEnvFile "APP_RELEASE" "$APP_RELEASE" "$DOCKER_ENV_PATH"
|
||||||
|
updateEnvFile "PULL_POLICY" "$PULL_POLICY" "$DOCKER_ENV_PATH"
|
||||||
|
updateEnvFile "CUSTOM_BUILD" "$CUSTOM_BUILD" "$DOCKER_ENV_PATH"
|
||||||
|
echo "Custom variables updated successfully" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncEnvFile(){
|
||||||
|
echo "Syncing environment variables..." >&2
|
||||||
|
if [ -f "$PLANE_INSTALL_DIR/plane.env.bak" ]; then
|
||||||
|
updateCustomVariables
|
||||||
|
|
||||||
|
# READ keys of plane.env and update the values from plane.env.bak
|
||||||
|
while IFS= read -r line
|
||||||
|
do
|
||||||
|
# ignore is 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"
|
||||||
|
fi
|
||||||
|
echo "Environment variables synced successfully" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildYourOwnImage(){
|
||||||
|
echo "Building images locally..."
|
||||||
|
|
||||||
|
export DOCKERHUB_USER="myplane"
|
||||||
|
export APP_RELEASE="local"
|
||||||
|
export PULL_POLICY="never"
|
||||||
|
CUSTOM_BUILD="true"
|
||||||
|
|
||||||
|
# checkout the code to ~/tmp/plane folder and build the images
|
||||||
|
local PLANE_TEMP_CODE_DIR=~/tmp/plane
|
||||||
|
rm -rf $PLANE_TEMP_CODE_DIR
|
||||||
|
mkdir -p $PLANE_TEMP_CODE_DIR
|
||||||
|
REPO=https://github.com/makeplane/plane.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"
|
||||||
|
|
||||||
|
cd "$PLANE_TEMP_CODE_DIR" || exit
|
||||||
|
|
||||||
|
/bin/bash -c "$COMPOSE_CMD -f build.yml build --no-cache" >&2
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Build failed. Exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Build completed successfully"
|
||||||
|
echo ""
|
||||||
|
echo "You can now start the services by running the command: ./setup.sh start"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function install() {
|
||||||
|
echo "Begin Installing Plane"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local build_image=$(initialize)
|
||||||
|
|
||||||
|
if [ "$build_image" == "build" ]; then
|
||||||
|
# ask for confirmation to continue building the images
|
||||||
|
echo "Do you want to continue with building the Docker images locally?"
|
||||||
|
read -p "Continue? [y/N]: " confirm
|
||||||
|
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Exiting..."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$build_image" == "build" ]; then
|
||||||
|
download "true"
|
||||||
|
else
|
||||||
|
download "false"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function download() {
|
||||||
|
local LOCAL_BUILD=$1
|
||||||
|
cd $SCRIPT_DIR
|
||||||
|
TS=$(date +%s)
|
||||||
|
if [ -f "$PLANE_INSTALL_DIR/docker-compose.yaml" ]
|
||||||
|
then
|
||||||
|
mv $PLANE_INSTALL_DIR/docker-compose.yaml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -H 'Cache-Control: no-cache, no-store' -s -o $PLANE_INSTALL_DIR/docker-compose.yaml https://raw.githubusercontent.com/makeplane/plane/$BRANCH/deploy/selfhost/docker-compose.yml?$(date +%s)
|
||||||
|
curl -H 'Cache-Control: no-cache, no-store' -s -o $PLANE_INSTALL_DIR/variables-upgrade.env https://raw.githubusercontent.com/makeplane/plane/$BRANCH/deploy/selfhost/variables.env?$(date +%s)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if [ "$LOCAL_BUILD" == "true" ]; then
|
||||||
|
export DOCKERHUB_USER="myplane"
|
||||||
|
export APP_RELEASE="local"
|
||||||
|
export PULL_POLICY="never"
|
||||||
|
CUSTOM_BUILD="true"
|
||||||
|
|
||||||
|
buildYourOwnImage
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Build failed. Exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
updateCustomVariables
|
||||||
|
else
|
||||||
|
CUSTOM_BUILD="false"
|
||||||
|
updateCustomVariables
|
||||||
|
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH pull --policy always"
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Failed to pull the images. Exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Most recent version of Plane is now available for you to use"
|
||||||
|
echo ""
|
||||||
|
echo "In case of 'Upgrade', please check the 'plane.env 'file for any new variables and update them accordingly"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
function startServices() {
|
||||||
|
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH up -d --pull if_not_present --quiet-pull"
|
||||||
|
|
||||||
|
local migrator_container_id=$(docker container ls -aq -f "name=$SERVICE_FOLDER-migrator")
|
||||||
|
if [ -n "$migrator_container_id" ]; then
|
||||||
|
local idx=0
|
||||||
|
while docker inspect --format='{{.State.Status}}' $migrator_container_id | grep -q "running"; do
|
||||||
|
local message=">> Waiting for Data Migration to finish"
|
||||||
|
local dots=$(printf '%*s' $idx | tr ' ' '.')
|
||||||
|
echo -ne "\r$message$dots"
|
||||||
|
((idx++))
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
printf "\r\033[K"
|
||||||
|
echo ""
|
||||||
|
echo " Data Migration completed successfully ✅"
|
||||||
|
|
||||||
|
# if migrator exit status is not 0, show error message and exit
|
||||||
|
if [ -n "$migrator_container_id" ]; then
|
||||||
|
local migrator_exit_code=$(docker inspect --format='{{.State.ExitCode}}' $migrator_container_id)
|
||||||
|
if [ $migrator_exit_code -ne 0 ]; then
|
||||||
|
echo "Plane Server failed to start ❌"
|
||||||
|
# stopServices
|
||||||
|
echo
|
||||||
|
echo "Please check the logs for the 'migrator' service and resolve the issue(s)."
|
||||||
|
echo "Stop the services by running the command: ./setup.sh stop"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local api_container_id=$(docker container ls -q -f "name=$SERVICE_FOLDER-api")
|
||||||
|
local idx2=0
|
||||||
|
while ! docker logs $api_container_id 2>&1 | grep -m 1 -i "Application startup complete" | grep -q ".";
|
||||||
|
do
|
||||||
|
local message=">> Waiting for API Service to Start"
|
||||||
|
local dots=$(printf '%*s' $idx2 | tr ' ' '.')
|
||||||
|
echo -ne "\r$message$dots"
|
||||||
|
((idx2++))
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
printf "\r\033[K"
|
||||||
|
echo " API Service started successfully ✅"
|
||||||
|
source "${DOCKER_ENV_PATH}"
|
||||||
|
echo " Plane Server started successfully ✅"
|
||||||
|
echo ""
|
||||||
|
echo " You can access the application at $WEB_URL"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
}
|
||||||
|
function stopServices() {
|
||||||
|
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH down"
|
||||||
|
}
|
||||||
|
function restartServices() {
|
||||||
|
stopServices
|
||||||
|
startServices
|
||||||
|
}
|
||||||
|
function upgrade() {
|
||||||
|
echo "***** STOPPING SERVICES ****"
|
||||||
|
stopServices
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "***** DOWNLOADING STABLE VERSION ****"
|
||||||
|
install
|
||||||
|
|
||||||
|
echo "***** PLEASE VALIDATE AND START SERVICES ****"
|
||||||
|
}
|
||||||
|
function viewSpecificLogs(){
|
||||||
|
local SERVICE_NAME=$1
|
||||||
|
|
||||||
|
if /bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH ps | grep -q '$SERVICE_NAME'"; then
|
||||||
|
echo "Service '$SERVICE_NAME' is running."
|
||||||
|
else
|
||||||
|
echo "Service '$SERVICE_NAME' is not running."
|
||||||
|
fi
|
||||||
|
|
||||||
|
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH logs -f $SERVICE_NAME"
|
||||||
|
}
|
||||||
|
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 " 0) Back to Main Menu"
|
||||||
|
echo
|
||||||
|
read -p "Service: " DOCKER_SERVICE_NAME
|
||||||
|
|
||||||
|
until (( DOCKER_SERVICE_NAME >= 0 && DOCKER_SERVICE_NAME <= 10 )); do
|
||||||
|
echo "Invalid selection. Please enter a number between 1 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";;
|
||||||
|
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";;
|
||||||
|
*) echo "INVALID SERVICE NAME SUPPLIED";;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
echo "INVALID SERVICE NAME SUPPLIED"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function backupSingleVolume() {
|
||||||
|
backupFolder=$1
|
||||||
|
selectedVolume=$2
|
||||||
|
# Backup data from Docker volume to the backup folder
|
||||||
|
# docker run --rm -v "$selectedVolume":/source -v "$backupFolder":/backup busybox sh -c 'cp -r /source/* /backup/'
|
||||||
|
local tobereplaced="plane-app_"
|
||||||
|
local replacewith=""
|
||||||
|
|
||||||
|
local svcName="${selectedVolume//$tobereplaced/$replacewith}"
|
||||||
|
|
||||||
|
docker run --rm \
|
||||||
|
-e TAR_NAME="$svcName" \
|
||||||
|
-v "$selectedVolume":/"$svcName" \
|
||||||
|
-v "$backupFolder":/backup \
|
||||||
|
busybox sh -c 'tar -czf "/backup/${TAR_NAME}.tar.gz" /${TAR_NAME}'
|
||||||
|
}
|
||||||
|
function backupData() {
|
||||||
|
local datetime=$(date +"%Y%m%d-%H%M")
|
||||||
|
local BACKUP_FOLDER=$PLANE_INSTALL_DIR/backup/$datetime
|
||||||
|
mkdir -p "$BACKUP_FOLDER"
|
||||||
|
|
||||||
|
volumes=$(docker volume ls -f "name=plane-app" --format "{{.Name}}" | grep -E "_pgdata|_redisdata|_uploads")
|
||||||
|
# Check if there are any matching volumes
|
||||||
|
if [ -z "$volumes" ]; then
|
||||||
|
echo "No volumes found starting with 'plane-app'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for vol in $volumes; do
|
||||||
|
echo "Backing Up $vol"
|
||||||
|
backupSingleVolume "$BACKUP_FOLDER" "$vol"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Backup completed successfully. Backup files are stored in $BACKUP_FOLDER"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
}
|
||||||
|
function askForAction() {
|
||||||
|
local DEFAULT_ACTION=$1
|
||||||
|
|
||||||
|
if [ -z "$DEFAULT_ACTION" ];
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo "Select a Action you want to perform:"
|
||||||
|
echo " 1) Install"
|
||||||
|
echo " 2) Start"
|
||||||
|
echo " 3) Stop"
|
||||||
|
echo " 4) Restart"
|
||||||
|
echo " 5) Upgrade"
|
||||||
|
echo " 6) View Logs"
|
||||||
|
echo " 7) Backup Data"
|
||||||
|
echo " 8) Exit"
|
||||||
|
echo
|
||||||
|
read -p "Action [2]: " ACTION
|
||||||
|
until [[ -z "$ACTION" || "$ACTION" =~ ^[1-8]$ ]]; do
|
||||||
|
echo "$ACTION: invalid selection."
|
||||||
|
read -p "Action [2]: " ACTION
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$ACTION" ];
|
||||||
|
then
|
||||||
|
ACTION=2
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ACTION" == "1" ] || [ "$DEFAULT_ACTION" == "install" ];
|
||||||
|
then
|
||||||
|
install
|
||||||
|
# askForAction
|
||||||
|
elif [ "$ACTION" == "2" ] || [ "$DEFAULT_ACTION" == "start" ];
|
||||||
|
then
|
||||||
|
startServices
|
||||||
|
# askForAction
|
||||||
|
elif [ "$ACTION" == "3" ] || [ "$DEFAULT_ACTION" == "stop" ];
|
||||||
|
then
|
||||||
|
stopServices
|
||||||
|
# askForAction
|
||||||
|
elif [ "$ACTION" == "4" ] || [ "$DEFAULT_ACTION" == "restart" ];
|
||||||
|
then
|
||||||
|
restartServices
|
||||||
|
# askForAction
|
||||||
|
elif [ "$ACTION" == "5" ] || [ "$DEFAULT_ACTION" == "upgrade" ];
|
||||||
|
then
|
||||||
|
upgrade
|
||||||
|
# askForAction
|
||||||
|
elif [ "$ACTION" == "6" ] || [ "$DEFAULT_ACTION" == "logs" ];
|
||||||
|
then
|
||||||
|
viewLogs "$@"
|
||||||
|
askForAction
|
||||||
|
elif [ "$ACTION" == "7" ] || [ "$DEFAULT_ACTION" == "backup" ];
|
||||||
|
then
|
||||||
|
backupData
|
||||||
|
elif [ "$ACTION" == "8" ]
|
||||||
|
then
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "INVALID ACTION SUPPLIED"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# if docker-compose is installed
|
||||||
|
if command -v docker-compose &> /dev/null
|
||||||
|
then
|
||||||
|
COMPOSE_CMD="docker-compose"
|
||||||
|
else
|
||||||
|
COMPOSE_CMD="docker compose"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CPU_ARCH" == "x86_64" ] || [ "$CPU_ARCH" == "amd64" ]; then
|
||||||
|
CPU_ARCH="amd64"
|
||||||
|
elif [ "$CPU_ARCH" == "aarch64" ] || [ "$CPU_ARCH" == "arm64" ]; then
|
||||||
|
CPU_ARCH="arm64"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$DOCKER_ENV_PATH" ]; then
|
||||||
|
DOCKERHUB_USER=$(getEnvValue "DOCKERHUB_USER" "$DOCKER_ENV_PATH")
|
||||||
|
APP_RELEASE=$(getEnvValue "APP_RELEASE" "$DOCKER_ENV_PATH")
|
||||||
|
PULL_POLICY=$(getEnvValue "PULL_POLICY" "$DOCKER_ENV_PATH")
|
||||||
|
CUSTOM_BUILD=$(getEnvValue "CUSTOM_BUILD" "$DOCKER_ENV_PATH")
|
||||||
|
|
||||||
|
if [ -z "$DOCKERHUB_USER" ]; then
|
||||||
|
DOCKERHUB_USER=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
|
||||||
|
|
||||||
|
if [ -z "$PULL_POLICY" ]; then
|
||||||
|
PULL_POLICY=if_not_present
|
||||||
|
updateEnvFile "PULL_POLICY" "$PULL_POLICY" "$DOCKER_ENV_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$CUSTOM_BUILD" ]; then
|
||||||
|
CUSTOM_BUILD=false
|
||||||
|
updateEnvFile "CUSTOM_BUILD" "$CUSTOM_BUILD" "$DOCKER_ENV_PATH"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_header
|
||||||
|
askForAction "$@"
|
||||||
Executable
+118
@@ -0,0 +1,118 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
Executable
+121
@@ -0,0 +1,121 @@
|
|||||||
|
#!/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 volumes
|
||||||
|
volumes=$(docker volume ls -f "name=plane-app" --format "{{.Name}}" | grep -E "_pgdata|_redisdata|_uploads")
|
||||||
|
# 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 "_pgdata|_redisdata|_uploads")
|
||||||
|
|
||||||
|
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 "$@"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ ! -d "./repo" ]; then
|
||||||
|
git clone --depth 1 --branch preview --single-branch https://github.com/makeplane/plane.git repo
|
||||||
|
else
|
||||||
|
cd repo
|
||||||
|
git pull
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -r ./repo/deploy/selfhost/. ./code
|
||||||
|
mv ./code/variables.env ./code/.env.example
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# check if ./repo exists
|
|
||||||
if [ ! -d "./repo" ]; then
|
if [ ! -d "./repo" ]; then
|
||||||
git clone --depth 1 --branch master --single-branch https://github.com/supabase/supabase repo
|
git clone --depth 1 --branch master --single-branch https://github.com/supabase/supabase repo
|
||||||
else
|
else
|
||||||
@@ -9,5 +8,4 @@ else
|
|||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# copy files from ./repo/docker to ./code
|
|
||||||
cp -r ./repo/docker/. ./code
|
cp -r ./repo/docker/. ./code
|
||||||
|
|||||||
Reference in New Issue
Block a user