diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 9fa847b6e76..00000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -- Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or - advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email - address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -squawk@plane.so. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c401c3c2cf5..00000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,245 +0,0 @@ -# Contributing to Plane - -Thank you for showing an interest in contributing to Plane! All kinds of contributions are valuable to us. In this guide, we will cover how you can quickly onboard and make your first contribution. - -## Submitting an issue - -Before submitting a new issue, please search the [issues](https://github.com/makeplane/plane/issues) tab. Maybe an issue or discussion already exists and might inform you of workarounds. Otherwise, you can give new information. - -While we want to fix all the [issues](https://github.com/makeplane/plane/issues), before fixing a bug we need to be able to reproduce and confirm it. Please provide us with a minimal reproduction scenario using a repository or [Gist](https://gist.github.com/). Having a live, reproducible scenario gives us the information without asking questions back & forth with additional questions like: - -- 3rd-party libraries being used and their versions -- a use-case that fails - -Without said minimal reproduction, we won't be able to investigate all [issues](https://github.com/makeplane/plane/issues), and the issue might not be resolved. - -You can open a new issue with this [issue form](https://github.com/makeplane/plane/issues/new). - -### Naming conventions for issues - -When opening a new issue, please use a clear and concise title that follows this format: - -- For bugs: `πŸ› Bug: [short description]` -- For features: `πŸš€ Feature: [short description]` -- For improvements: `πŸ› οΈ Improvement: [short description]` -- For documentation: `πŸ“˜ Docs: [short description]` - -**Examples:** - -- `πŸ› Bug: API token expiry time not saving correctly` -- `πŸ“˜ Docs: Clarify RAM requirement for local setup` -- `πŸš€ Feature: Allow custom time selection for token expiration` - -This helps us triage and manage issues more efficiently. - -## Projects setup and Architecture - -### Requirements - -- Docker Engine installed and running -- Node.js version 20+ [LTS version](https://nodejs.org/en/about/previous-releases) -- Python version 3.8+ -- Postgres version v14 -- Redis version v6.2.7 -- **Memory**: Minimum **12 GB RAM** recommended - > ⚠️ Running the project on a system with only 8 GB RAM may lead to setup failures or memory crashes (especially during Docker container build/start or dependency install). Use cloud environments like GitHub Codespaces or upgrade local RAM if possible. - -### Setup the project - -The project is a monorepo, with backend api and frontend in a single repo. - -The backend is a django project which is kept inside apps/api - -1. Clone the repo - -```bash -git clone https://github.com/makeplane/plane.git [folder-name] -cd [folder-name] -chmod +x setup.sh -``` - -2. Run setup.sh - -```bash -./setup.sh -``` - -3. Start the containers - -```bash -docker compose -f docker-compose-local.yml up -``` - -4. Start web apps: - -```bash -yarn dev -``` - -5. Open your browser to http://localhost:3001/god-mode/ and register yourself as instance admin -6. Open up your browser to http://localhost:3000 then log in using the same credentials from the previous step - -That’s it! You’re all set to begin coding. Remember to refresh your browser if changes don’t auto-reload. Happy contributing! πŸŽ‰ - -## Missing a Feature? - -If a feature is missing, you can directly _request_ a new one [here](https://github.com/makeplane/plane/issues/new?assignees=&labels=feature&template=feature_request.yml&title=%F0%9F%9A%80+Feature%3A+). You also can do the same by choosing "πŸš€ Feature" when raising a [New Issue](https://github.com/makeplane/plane/issues/new/choose) on our GitHub Repository. -If you would like to _implement_ it, an issue with your proposal must be submitted first, to be sure that we can use it. Please consider the guidelines given below. - -## Coding guidelines - -To ensure consistency throughout the source code, please keep these rules in mind as you are working: - -- All features or bug fixes must be tested by one or more specs (unit-tests). -- We use [Eslint default rule guide](https://eslint.org/docs/rules/), with minor changes. An automated formatter is available using prettier. - -## Ways to contribute - -- Try Plane Cloud and the self hosting platform and give feedback -- Add new integrations -- Add or update translations -- Help with open [issues](https://github.com/makeplane/plane/issues) or [create your own](https://github.com/makeplane/plane/issues/new/choose) -- Share your thoughts and suggestions with us -- Help create tutorials and blog posts -- Request a feature by submitting a proposal -- Report a bug -- **Improve documentation** - fix incomplete or missing [docs](https://docs.plane.so/), bad wording, examples or explanations. - -## Contributing to language support - -This guide is designed to help contributors understand how to add or update translations in the application. - -### Understanding translation structure - -#### File organization - -Translations are organized by language in the locales directory. Each language has its own folder containing JSON files for translations. Here's how it looks: - -``` -packages/i18n/src/locales/ - β”œβ”€β”€ en/ - β”‚ β”œβ”€β”€ core.json # Critical translations - β”‚ └── translations.json - β”œβ”€β”€ fr/ - β”‚ └── translations.json - └── [language]/ - └── translations.json -``` - -#### Nested structure - -To keep translations organized, we use a nested structure for keys. This makes it easier to manage and locate specific translations. For example: - -```json -{ - "issue": { - "label": "Work item", - "title": { - "label": "Work item title" - } - } -} -``` - -### Translation formatting guide - -We use [IntlMessageFormat](https://formatjs.github.io/docs/intl-messageformat/) to handle dynamic content, such as variables and pluralization. Here's how to format your translations: - -#### Examples - -- **Simple variables** - - ```json - { - "greeting": "Hello, {name}!" - } - ``` - -- **Pluralization** - ```json - { - "items": "{count, plural, one {Work item} other {Work items}}" - } - ``` - -### Contributing guidelines - -#### Updating existing translations - -1. Locate the key in `locales//translations.json`. - -2. Update the value while ensuring the key structure remains intact. -3. Preserve any existing ICU formats (e.g., variables, pluralization). - -#### Adding new translation keys - -1. When introducing a new key, ensure it is added to **all** language files, even if translations are not immediately available. Use English as a placeholder if needed. - -2. Keep the nesting structure consistent across all languages. - -3. If the new key requires dynamic content (e.g., variables or pluralization), ensure the ICU format is applied uniformly across all languages. - -### Adding new languages - -Adding a new language involves several steps to ensure it integrates seamlessly with the project. Follow these instructions carefully: - -1. **Update type definitions** - Add the new language to the TLanguage type in the language definitions file: - -```ts - // packages/i18n/src/types/language.ts - export type TLanguage = "en" | "fr" | "your-lang"; -``` - -1. **Add language configuration** - Include the new language in the list of supported languages: -```ts - // packages/i18n/src/constants/language.ts - export const SUPPORTED_LANGUAGES: ILanguageOption[] = [ - { label: "English", value: "en" }, - { label: "Your Language", value: "your-lang" } - ]; -``` - -2. **Create translation files** - 1. Create a new folder for your language under locales (e.g., `locales/your-lang/`). - - 2. Add a `translations.json` file inside the folder. - - 3. Copy the structure from an existing translation file and translate all keys. - -3. **Update import logic** - Modify the language import logic to include your new language: -```ts - private importLanguageFile(language: TLanguage): Promise { - switch (language) { - case "your-lang": - return import("../locales/your-lang/translations.json"); - // ... - } - } -``` - -### Quality checklist - -Before submitting your contribution, please ensure the following: - -- All translation keys exist in every language file. -- Nested structures match across all language files. -- ICU message formats are correctly implemented. -- All languages load without errors in the application. -- Dynamic values and pluralization work as expected. -- There are no missing or untranslated keys. - -#### Pro tips - -- When in doubt, refer to the English translations for context. -- Verify pluralization works with different numbers. -- Ensure dynamic values (e.g., `{name}`) are correctly interpolated. -- Double-check that nested key access paths are accurate. - -Happy translating! 🌍✨ - -## Need help? Questions and suggestions - -Questions, suggestions, and thoughts are most welcome. We can also be reached in our [Discord Server](https://discord.com/invite/A92xrEGCge). diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 0e11bbb5570..00000000000 --- a/SECURITY.md +++ /dev/null @@ -1,39 +0,0 @@ -# Security policy -This document outlines the security protocols and vulnerability reporting guidelines for the Plane project. Ensuring the security of our systems is a top priority, and while we work diligently to maintain robust protection, vulnerabilities may still occur. We highly value the community’s role in identifying and reporting security concerns to uphold the integrity of our systems and safeguard our users. - -## Reporting a vulnerability -If you have identified a security vulnerability, submit your findings to [security@plane.so](mailto:security@plane.so). -Ensure your report includes all relevant information needed for us to reproduce and assess the issue. Include the IP address or URL of the affected system. - -To ensure a responsible and effective disclosure process, please adhere to the following: - -- Maintain confidentiality and refrain from publicly disclosing the vulnerability until we have had the opportunity to investigate and address the issue. -- Refrain from running automated vulnerability scans on our infrastructure or dashboard without prior consent. Contact us to set up a sandbox environment if necessary. -- Do not exploit any discovered vulnerabilities for malicious purposes, such as accessing or altering user data. -- Do not engage in physical security attacks, social engineering, distributed denial of service (DDoS) attacks, spam campaigns, or attacks on third-party applications as part of your vulnerability testing. - -## Out of scope -While we appreciate all efforts to assist in improving our security, please note that the following types of vulnerabilities are considered out of scope: - -- Vulnerabilities requiring man-in-the-middle (MITM) attacks or physical access to a user’s device. -- Content spoofing or text injection issues without a clear attack vector or the ability to modify HTML/CSS. -- Issues related to email spoofing. -- Missing DNSSEC, CAA, or CSP headers. -- Absence of secure or HTTP-only flags on non-sensitive cookies. - -## Our commitment - -At Plane, we are committed to maintaining transparent and collaborative communication throughout the vulnerability resolution process. Here's what you can expect from us: - -- **Response Time**
-We will acknowledge receipt of your vulnerability report within three business days and provide an estimated timeline for resolution. -- **Legal Protection**
-We will not initiate legal action against you for reporting vulnerabilities, provided you adhere to the reporting guidelines. -- **Confidentiality**
-Your report will be treated with confidentiality. We will not disclose your personal information to third parties without your consent. -- **Recognition**
-With your permission, we are happy to publicly acknowledge your contribution to improving our security once the issue is resolved. -- **Timely Resolution**
-We are committed to working closely with you throughout the resolution process, providing timely updates as necessary. Our goal is to address all reported vulnerabilities swiftly, and we will actively engage with you to coordinate a responsible disclosure once the issue is fully resolved. - -We appreciate your help in ensuring the security of our platform. Your contributions are crucial to protecting our users and maintaining a secure environment. Thank you for working with us to keep Plane safe. \ No newline at end of file diff --git a/deployments/aio/community/Dockerfile b/deployments/aio/community/Dockerfile deleted file mode 100644 index b217d09f8bb..00000000000 --- a/deployments/aio/community/Dockerfile +++ /dev/null @@ -1,68 +0,0 @@ -ARG PLANE_VERSION=v0.27.1 -FROM --platform=$BUILDPLATFORM tonistiigi/binfmt AS binfmt - -# ************************************************** -# STAGE 0: Image Loading -# ************************************************** -FROM node:22-alpine AS node - -FROM artifacts.plane.so/makeplane/plane-frontend:${PLANE_VERSION} AS web-img -FROM artifacts.plane.so/makeplane/plane-backend:${PLANE_VERSION} AS backend-img -FROM artifacts.plane.so/makeplane/plane-space:${PLANE_VERSION} AS space-img -FROM artifacts.plane.so/makeplane/plane-admin:${PLANE_VERSION} AS admin-img -FROM artifacts.plane.so/makeplane/plane-live:${PLANE_VERSION} AS live-img -FROM artifacts.plane.so/makeplane/plane-proxy:${PLANE_VERSION} AS proxy-img - -# ************************************************** -# STAGE 1: Runner -# ************************************************** -FROM python:3.12.10-alpine AS runner - -WORKDIR /app - -RUN apk add --no-cache \ - "libpq" \ - "libxslt" \ - "xmlsec" - - -COPY --from=node /usr/lib /usr/lib -COPY --from=node /usr/local/lib /usr/local/lib -COPY --from=node /usr/local/include /usr/local/include -COPY --from=node /usr/local/bin /usr/local/bin - -COPY --from=web-img /app /app/web -COPY --from=space-img /app /app/space -COPY --from=admin-img /app /app/admin -COPY --from=live-img /app /app/live - -RUN rm -rf /app/web/apps/web/.next/cache && \ - rm -rf /app/space/apps/space/.next/cache && \ - rm -rf /app/admin/apps/admin/.next/cache - -COPY --from=proxy-img /usr/bin/caddy /usr/bin/caddy -COPY dist/Caddyfile /app/proxy/Caddyfile - -COPY --from=backend-img /code /app/backend -COPY --from=backend-img /usr/local/lib/python3.12/site-packages/ /usr/local/lib/python3.12/site-packages/ -COPY --from=backend-img /usr/local/bin/ /usr/local/bin/ - -RUN apk add --no-cache nss-tools bash curl uuidgen ncdu vim - -RUN pip install supervisor -RUN mkdir -p /etc/supervisor/conf.d - -COPY start.sh /app/start.sh -COPY dist/plane.env /app/plane.env -COPY supervisor.conf /etc/supervisor/conf.d/supervisor.conf - -RUN mkdir -p /app/logs/access && \ - mkdir -p /app/logs/error && \ - mkdir -p /app/data && \ - chmod +x /app/start.sh - -VOLUME ['/app/data', '/app/logs'] - -EXPOSE 80 443 - -CMD ["/app/start.sh"] diff --git a/deployments/aio/community/README.md b/deployments/aio/community/README.md deleted file mode 100644 index 96aab6737d4..00000000000 --- a/deployments/aio/community/README.md +++ /dev/null @@ -1,174 +0,0 @@ -# Plane Community All-In-One (AIO) Docker Image - -The Plane Community All-In-One Docker image packages all Plane services into a single container for easy deployment and testing. This image includes web interface, API server, background workers, live server, and more. - -## What's Included - -The AIO image contains the following services: - -- **Web App** (Port 3001): Main Plane web interface -- **Space** (Port 3002): Public project spaces -- **Admin** (Port 3003): Administrative interface -- **API Server** (Port 3004): Backend API -- **Live Server** (Port 3005): Real-time collaboration -- **Proxy** (Port 80, 443): Caddy reverse proxy -- **Worker & Beat**: Background task processing - -## Prerequisites - -### Required External Services - -The AIO image requires these external services to be running: - -- **PostgreSQL Database**: For data storage -- **Redis**: For caching and session management -- **RabbitMQ**: For message queuing -- **S3-Compatible Storage**: For file uploads (AWS S3 or MinIO) - -### Required Environment Variables - -You must provide these environment variables: - -#### Core Configuration - -- `DOMAIN_NAME`: Your domain name or IP address -- `DATABASE_URL`: PostgreSQL connection string -- `REDIS_URL`: Redis connection string -- `AMQP_URL`: RabbitMQ connection string - -#### Storage Configuration - -- `AWS_REGION`: AWS region (e.g., us-east-1) -- `AWS_ACCESS_KEY_ID`: S3 access key -- `AWS_SECRET_ACCESS_KEY`: S3 secret key -- `AWS_S3_BUCKET_NAME`: S3 bucket name -- `AWS_S3_ENDPOINT_URL`: S3 endpoint (optional, defaults to AWS) - -## Quick Start - -### Basic Usage - -```bash -docker run --name plane-aio --rm -it \ - -p 80:80 \ - -e DOMAIN_NAME=your-domain.com \ - -e DATABASE_URL=postgresql://user:pass@host:port/database \ - -e REDIS_URL=redis://host:port \ - -e AMQP_URL=amqp://user:pass@host:port/vhost \ - -e AWS_REGION=us-east-1 \ - -e AWS_ACCESS_KEY_ID=your-access-key \ - -e AWS_SECRET_ACCESS_KEY=your-secret-key \ - -e AWS_S3_BUCKET_NAME=your-bucket \ - artifacts.plane.so/makeplane/plane-aio-community:latest -``` - -### Example with IP Address - -```bash -MYIP=192.168.68.169 -docker run --name myaio --rm -it \ - -p 80:80 \ - -e DOMAIN_NAME=${MYIP} \ - -e DATABASE_URL=postgresql://plane:plane@${MYIP}:15432/plane \ - -e REDIS_URL=redis://${MYIP}:16379 \ - -e AMQP_URL=amqp://plane:plane@${MYIP}:15673/plane \ - -e AWS_REGION=us-east-1 \ - -e AWS_ACCESS_KEY_ID=5MV45J9NF5TEFZWYCRAX \ - -e AWS_SECRET_ACCESS_KEY=7xMqAiAHsf2UUjMH+EwICXlyJL9TO30m8leEaDsL \ - -e AWS_S3_BUCKET_NAME=plane-app \ - -e AWS_S3_ENDPOINT_URL=http://${MYIP}:19000 \ - -e FILE_SIZE_LIMIT=10485760 \ - artifacts.plane.so/makeplane/plane-aio-community:latest -``` - -## Configuration Options - -### Optional Environment Variables - -#### Network & Protocol - -- `SITE_ADDRESS`: Server bind address (default: `:80`) - - -#### Security & Secrets - -- `SECRET_KEY`: Django secret key (default provided) -- `LIVE_SERVER_SECRET_KEY`: Live server secret (default provided) - -#### File Handling - -- `FILE_SIZE_LIMIT`: Maximum file upload size in bytes (default: `5242880` = 5MB) - -#### API Configuration - -- `API_KEY_RATE_LIMIT`: API key rate limit (default: `60/minute`) - -## Port Mapping - -The following ports are exposed: - -- `80`: Main web interface (HTTP) -- `443`: HTTPS (if SSL configured) - -## Volume Mounts - -### Recommended Persistent Volumes - -```bash --v /path/to/logs:/app/logs \ --v /path/to/data:/app/data -``` - -## Building the Image - -To build the AIO image yourself: - -```bash -cd deployments/aio/community -IMAGE_NAME=myplane-aio ./build.sh --release=v0.27.1 [--platform=linux/amd64] -``` - -Available build options: - -- `--release`: Plane version to build (required) -- `--image-name`: Custom image name (default: `plane-aio-community`) - -## Troubleshooting - -### Logs - -All service logs are available in `/app/logs/`: - -- Access logs: `/app/logs/access/` -- Error logs: `/app/logs/error/` - -### Health Checks - -The container runs multiple services managed by Supervisor. Check service status: - -```bash -docker exec -it supervisorctl status -``` - -### Common Issues - -1. **Database Connection Failed**: Ensure PostgreSQL is accessible and credentials are correct -2. **Redis Connection Failed**: Verify Redis server is running and URL is correct -3. **File Upload Issues**: Check S3 credentials and bucket permissions - -### Environment Validation - -The container will validate required environment variables on startup and display helpful error messages if any are missing. - -## Production Considerations - -- Use proper SSL certificates for HTTPS -- Configure proper backup strategies for data -- Monitor resource usage and scale accordingly -- Use external load balancer for high availability -- Regularly update to latest versions -- Secure your environment variables and secrets - -## Support - -For issues and support, please refer to the official Plane documentation. diff --git a/deployments/aio/community/build.sh b/deployments/aio/community/build.sh deleted file mode 100755 index e69ac9a50b3..00000000000 --- a/deployments/aio/community/build.sh +++ /dev/null @@ -1,155 +0,0 @@ -#!/bin/bash - -set -e - -DIST_DIR=${DIST_DIR:-./dist} -CPU_ARCH=$(uname -m) -IMAGE_NAME=${IMAGE_NAME:-makeplane/plane-aio-community} - - -# loop though all flags and set the variables -for arg in "$@"; do - case $arg in - --release) - APP_RELEASE_VERSION="$2" - shift - shift - ;; - --release=*) - APP_RELEASE_VERSION="${arg#*=}" - shift - ;; - --image-name) - IMAGE_NAME="$2" - shift - shift - ;; - --image-name=*) - IMAGE_NAME="${arg#*=}" - shift - ;; - esac -done - - -if [ -z "$APP_RELEASE_VERSION" ]; then - echo "" - echo "Usage: " - echo " ./build.sh [flags]" - echo "" - echo "Flags:" - echo " --release= required (e.g. v0.27.1)" - echo "" - echo "Example: ./build.sh --release=v0.27.1 --platform=linux/amd64" - exit 1 -fi - -# Install yq if not present -if ! command -v yq &> /dev/null; then - echo "Installing yq..." - sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${CPU_ARCH} - sudo chmod +x /usr/local/bin/yq -fi - -cd $(dirname "$0") - -string_replace(){ - local file="$1" - local search="$2" - local replace="$3" - - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' "s|$search|$replace|g" "$file" - else - sed -i "s|$search|$replace|g" "$file" - fi -} -remove_line(){ - local file="$1" - local line="$2" - - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' '/'$line'/d' "$file" - else - sed -i '/'$line'/d' "$file" - fi -} - -update_env_file(){ - local file="$1" - local key="$2" - local value="$3" - - # if key is in file, replace it - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' 's|^'$key'=.*|'$key'='$value'|' "$file" - else - sed -i 's|^'$key'=.*|'$key'='$value'|' "$file" - fi - - # if key not in file, add it - if ! grep -q "^$key=" "$file"; then - echo "$key=$value" >> "$file" - fi -} - -build_dist_files(){ - cp ./variables.env $DIST_DIR/plane.env - cp ../../../apps/proxy/Caddyfile.ce $DIST_DIR/Caddyfile - - echo "" >> $DIST_DIR/plane.env - echo "" >> $DIST_DIR/plane.env - - # update the plane.env file with the APP_RELEASE_VERSION - update_env_file $DIST_DIR/plane.env "APP_RELEASE_VERSION" "$APP_RELEASE_VERSION" - update_env_file $DIST_DIR/plane.env "APP_RELEASE" "$APP_RELEASE_VERSION" - update_env_file $DIST_DIR/plane.env "APP_VERSION" "$APP_RELEASE_VERSION" - - update_env_file $DIST_DIR/plane.env "API_BASE_URL" "http://localhost:3004" - update_env_file $DIST_DIR/plane.env "SITE_ADDRESS" ":80" - - # remove this line containing `plane-minio:9000` - remove_line $DIST_DIR/Caddyfile "plane-minio:9000" "" - - # in caddyfile, update `reverse_proxy /spaces/* space:3000` to `reverse_proxy /spaces/* space:3002` - string_replace $DIST_DIR/Caddyfile "web:3000" "localhost:3001" - string_replace $DIST_DIR/Caddyfile "space:3000" "localhost:3002" - string_replace $DIST_DIR/Caddyfile "admin:3000" "localhost:3003" - string_replace $DIST_DIR/Caddyfile "api:8000" "localhost:3004" - string_replace $DIST_DIR/Caddyfile "live:3000" "localhost:3005" - - - # print docker build command - echo "------------------------------------------------" - echo "Run the following command to build the image:" - echo "------------------------------------------------" - echo "" - echo "docker build -t $IMAGE_NAME \\" - echo " -f $(pwd)/Dockerfile \\" - echo " --build-arg PLANE_VERSION=$APP_RELEASE_VERSION \\" - echo " $(pwd)" - echo "" - echo "------------------------------------------------" -} - - -main(){ - # check if the dist directory exists - echo "" - if [ -d "$DIST_DIR" ]; then - echo "Cleaning existing dist directory..." - rm -rf $DIST_DIR - fi - echo "Creating dist directory..." - mkdir -p $DIST_DIR - echo "" - - build_dist_files - if [ $? -ne 0 ]; then - echo "Error: Failed to build docker image" - exit 1 - fi -} - -main "$@" - diff --git a/deployments/aio/community/start.sh b/deployments/aio/community/start.sh deleted file mode 100644 index 6b8c81561d5..00000000000 --- a/deployments/aio/community/start.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/bash -e - -print_header(){ - clear - echo "------------------------------------------------" - echo "Plane Community (All-In-One)" - echo "------------------------------------------------" - echo "" - echo "You are required to pass below environment variables to the script" - echo " DOMAIN_NAME, DATABASE_URL, REDIS_URL, AMQP_URL" - echo " AWS_REGION, AWS_ACCESS_KEY_ID" - echo " AWS_SECRET_ACCESS_KEY, AWS_S3_BUCKET_NAME" - echo "" - echo "Other optional environment variables: " - echo " SITE_ADDRESS (default: ':80')" - echo " FILE_SIZE_LIMIT (default: 5242880)" - echo " APP_PROTOCOL (http or https)" - echo " SECRET_KEY (default: 60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5)" - echo " LIVE_SERVER_SECRET_KEY (default: htbqvBJAgpm9bzvf3r4urJer0ENReatceh)" - echo "" - echo "" -} - -check_required_env(){ - echo "Checking required environment variables..." - local keys=("DOMAIN_NAME" "DATABASE_URL" "REDIS_URL" "AMQP_URL" - "AWS_REGION" "AWS_ACCESS_KEY_ID" "AWS_SECRET_ACCESS_KEY" "AWS_S3_BUCKET_NAME") - - local missing_keys=() - # Check if the environment variable is set and not empty - for key in "${keys[@]}"; do - if [ -z "${!key}" ]; then - echo " ❌ '$key' is not set or is empty" - missing_keys+=("$key") - fi - done - - if [ ${#missing_keys[@]} -gt 0 ]; then - echo "" - exit 1 - fi - # add checkmark - echo "βœ… Required environment variables are available" - echo "" -} - -update_env_value(){ - local key="$1" - local value="$2" - - # check if the file exists - if [ ! -f "plane.env" ]; then - echo "plane.env file not found" - exit 1 - fi - - # check if the key exists and add it if it doesn't - if ! grep -q "^$key=.*" plane.env; then - echo "${key}=${value}" >> plane.env - return 0 - fi - - # if key and value are not empty, update the value - if [ -n "$key" ] && [ -n "$value" ]; then - sed -i "s|^$key=.*|$key=$value|" plane.env - return 0 - fi - -} - -check_pre_requisites(){ - check_required_env - - # check if the file exists - if [ ! -f "plane.env" ]; then - echo "plane.env file not found" - exit 1 - fi - # add a new line to the end of the file - echo "" >> plane.env - echo "" >> plane.env - echo "βœ… Pre-requisites checked" - echo "" - -} - -validate_domain_name() { - local domain="$1" - - # Check if it's an IP address first - if [[ "$domain" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "IP" - return 0 - fi - - # FQDN validation regex - local fqdn_regex='^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.?$' - - if [[ "$domain" =~ $fqdn_regex ]]; then - # Additional checks - if [[ ${#domain} -le 253 ]] && [[ ! "$domain" =~ \.\. ]] && [[ ! "$domain" =~ ^- ]] && [[ ! "$domain" =~ -\. ]]; then - echo "FQDN" - return 0 - fi - fi - - echo "INVALID" - return 1 -} - -update_env_file(){ - echo "Updating environment file..." - # check if DOMAIN_NAME is valid IP address - local domain_type=$(validate_domain_name "$DOMAIN_NAME") - if [ "$domain_type" == "INVALID" ]; then - echo "DOMAIN_NAME is not a valid FQDN or IP address" - exit 1 - fi - - local app_protocol=${APP_PROTOCOL:-http} - - update_env_value "APP_PROTOCOL" "$app_protocol" - update_env_value "DOMAIN_NAME" "$DOMAIN_NAME" - update_env_value "APP_DOMAIN" "$DOMAIN_NAME" - if [ -n "$SITE_ADDRESS" ]; then - update_env_value "SITE_ADDRESS" "$SITE_ADDRESS" - else - update_env_value "SITE_ADDRESS" ":80" - fi - update_env_value "WEB_URL" "$app_protocol://$DOMAIN_NAME" - update_env_value "CORS_ALLOWED_ORIGINS" "http://$DOMAIN_NAME,https://$DOMAIN_NAME" - - # update database url - update_env_value "DATABASE_URL" "$DATABASE_URL" - update_env_value "REDIS_URL" "$REDIS_URL" - update_env_value "AMQP_URL" "$AMQP_URL" - - # update aws credentials - update_env_value "AWS_REGION" "$AWS_REGION" - update_env_value "AWS_ACCESS_KEY_ID" "$AWS_ACCESS_KEY_ID" - update_env_value "AWS_SECRET_ACCESS_KEY" "$AWS_SECRET_ACCESS_KEY" - update_env_value "AWS_S3_BUCKET_NAME" "$AWS_S3_BUCKET_NAME" - update_env_value "AWS_S3_ENDPOINT_URL" "${AWS_S3_ENDPOINT_URL:-https://s3.${AWS_REGION}.amazonaws.com}" - update_env_value "BUCKET_NAME" "$AWS_S3_BUCKET_NAME" - update_env_value "USE_MINIO" "0" - - # Optional environment variables - update_env_value "SECRET_KEY" "${SECRET_KEY:-60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5}" - update_env_value "FILE_SIZE_LIMIT" "${FILE_SIZE_LIMIT:-5242880}" - update_env_value "LIVE_SERVER_SECRET_KEY" "${LIVE_SERVER_SECRET_KEY:-htbqvBJAgpm9bzvf3r4urJer0ENReatceh}" - - update_env_value "API_KEY_RATE_LIMIT" "${API_KEY_RATE_LIMIT:-60/minute}" - - echo "βœ… Environment file updated" - echo "" -} - -main(){ - print_header - check_pre_requisites - update_env_file - - # load plane.env as exported variables - export $(grep -v '^#' plane.env | xargs) - - /usr/local/bin/supervisord -c /etc/supervisor/conf.d/supervisor.conf -} - -main "$@" \ No newline at end of file diff --git a/deployments/aio/community/supervisor.conf b/deployments/aio/community/supervisor.conf deleted file mode 100644 index 20a51f0c504..00000000000 --- a/deployments/aio/community/supervisor.conf +++ /dev/null @@ -1,124 +0,0 @@ -[supervisord] -user=root -nodaemon=true -stderr_logfile=/app/logs/error/supervisor.err.log -stdout_logfile=/app/logs/access/supervisor.log - -[program:migrator] -directory=/app/backend -command=sh -c "./bin/docker-entrypoint-migrator.sh" -autostart=true -autorestart=unexpected -stdout_logfile=/app/logs/access/migrator.log -stderr_logfile=/app/logs/error/migrator.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -priority=10 - - -[program:web] -command=sh -c "node /app/web/apps/web/server.js" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/web.log -stderr_logfile=/app/logs/error/web.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -environment=PORT=3001,HOSTNAME=0.0.0.0 -priority=15 - -[program:space] -command=sh -c "node /app/space/apps/space/server.js" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/space.log -stderr_logfile=/app/logs/error/space.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -environment=PORT=3002,HOSTNAME=0.0.0.0 -priority=15 - -[program:admin] -command=sh -c "node /app/admin/apps/admin/server.js" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/admin.log -stderr_logfile=/app/logs/error/admin.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -environment=PORT=3003,HOSTNAME=0.0.0.0 -priority=15 - -[program:api] -directory=/app/backend -command=sh -c "./bin/docker-entrypoint-api.sh" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/api.log -stdout_logfile_maxbytes=0 -stderr_logfile=/app/logs/error/api.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -environment=PORT=3004,HOSTNAME=0.0.0.0 -priority=15 - - -[program:worker] -directory=/app/backend -command=sh -c "./bin/docker-entrypoint-worker.sh" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/worker.log -stdout_logfile_maxbytes=0 -stderr_logfile=/app/logs/error/worker.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -priority=20 - -[program:beat] -directory=/app/backend -command=sh -c "./bin/docker-entrypoint-beat.sh" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/beat.log -stdout_logfile_maxbytes=0 -stderr_logfile=/app/logs/error/beat.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -priority=20 - - -[program:live] -directory=/app/live -command=sh -c "node live/server.js" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/live.log -stdout_logfile_maxbytes=0 -stderr_logfile=/app/logs/error/live.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -environment=PORT=3005,HOSTNAME=0.0.0.0 -priority=20 - - -[program:proxy] -directory=/app/proxy -command=sh -c "caddy run --config /app/proxy/Caddyfile" -autostart=true -autorestart=true -stdout_logfile=/app/logs/access/proxy.log -stdout_logfile_maxbytes=0 -stderr_logfile=/app/logs/error/proxy.err.log -# stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=50MB -stderr_logfile_backups=5 -priority=20 \ No newline at end of file diff --git a/deployments/aio/community/variables.env b/deployments/aio/community/variables.env deleted file mode 100644 index 99d93e3fda2..00000000000 --- a/deployments/aio/community/variables.env +++ /dev/null @@ -1,53 +0,0 @@ -APP_DOMAIN=localhost -APP_RELEASE=stable - -# If SSL Cert to be generated, set CERT_EMAIl="email " -CERT_EMAIL= -CERT_ACME_CA=https://acme-v02.api.letsencrypt.org/directory - -SITE_ADDRESS=:80 - -# For DNS Challenge based certificate generation, set the CERT_ACME_DNS, CERT_EMAIL -# CERT_ACME_DNS="acme_dns " -CERT_ACME_DNS= - -WEB_URL=http://localhost -DEBUG=0 -CORS_ALLOWED_ORIGINS=http://localhost -API_BASE_URL=http://localhost:3004 - -#DB SETTINGS -DATABASE_URL= - -# REDIS SETTINGS -REDIS_URL= - -# RabbitMQ Settings -AMQP_URL= - -# Secret Key -SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5 - -# DATA STORE SETTINGS -USE_MINIO=0 -AWS_REGION= -AWS_ACCESS_KEY_ID= -AWS_SECRET_ACCESS_KEY= -AWS_S3_ENDPOINT_URL=https://s3.amazonaws.com -AWS_S3_BUCKET_NAME= -BUCKET_NAME= -FILE_SIZE_LIMIT=5242880 - -# Gunicorn Workers -GUNICORN_WORKERS=1 - - - -# Force HTTPS for handling SSL Termination -MINIO_ENDPOINT_SSL=0 - -# API key rate limit -API_KEY_RATE_LIMIT=60/minute - -# Live Server Secret Key -LIVE_SERVER_SECRET_KEY=htbqvBJAgpm9bzvf3r4urJer0ENReatceh diff --git a/deployments/cli/community/README.md b/deployments/cli/community/README.md deleted file mode 100644 index 8cec0f72b35..00000000000 --- a/deployments/cli/community/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_. - -> `LISTEN_HTTP_PORT` - This is default set to `80`. Make sure the port you choose to use is not preoccupied. (e.g `LISTEN_HTTP_PORT=8080`) - -> `WEB_URL` - This is default set to `http://localhost`. Change this to the FQDN you plan to use along with LISTEN_HTTP_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 LISTEN_HTTP_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/deployments/cli/community/build.yml b/deployments/cli/community/build.yml deleted file mode 100644 index f7fc6a54586..00000000000 --- a/deployments/cli/community/build.yml +++ /dev/null @@ -1,36 +0,0 @@ -services: - web: - image: ${DOCKERHUB_USER:-local}/plane-frontend:${APP_RELEASE:-latest} - build: - context: ../../ - dockerfile: apps/web/Dockerfile.web - - space: - image: ${DOCKERHUB_USER:-local}/plane-space:${APP_RELEASE:-latest} - build: - context: ../../ - dockerfile: apps/space/Dockerfile.space - - admin: - image: ${DOCKERHUB_USER:-local}/plane-admin:${APP_RELEASE:-latest} - build: - context: ../../ - dockerfile: apps/admin/Dockerfile.admin - - live: - image: ${DOCKERHUB_USER:-local}/plane-live:${APP_RELEASE:-latest} - build: - context: ../../ - dockerfile: apps/live/Dockerfile.live - - api: - image: ${DOCKERHUB_USER:-local}/plane-backend:${APP_RELEASE:-latest} - build: - context: ../../apps/api - dockerfile: Dockerfile.api - - proxy: - image: ${DOCKERHUB_USER:-local}/plane-proxy:${APP_RELEASE:-latest} - build: - context: ../../apps/proxy - dockerfile: Dockerfile.ce diff --git a/deployments/cli/community/docker-compose.yml b/deployments/cli/community/docker-compose.yml deleted file mode 100644 index 7afc8d2a14f..00000000000 --- a/deployments/cli/community/docker-compose.yml +++ /dev/null @@ -1,254 +0,0 @@ -x-db-env: &db-env - 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} - -x-redis-env: &redis-env - REDIS_HOST: ${REDIS_HOST:-plane-redis} - REDIS_PORT: ${REDIS_PORT:-6379} - REDIS_URL: ${REDIS_URL:-redis://plane-redis:6379/} - -x-minio-env: &minio-env - MINIO_ROOT_USER: ${AWS_ACCESS_KEY_ID:-access-key} - MINIO_ROOT_PASSWORD: ${AWS_SECRET_ACCESS_KEY:-secret-key} - -x-aws-s3-env: &aws-s3-env - 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} - -x-proxy-env: &proxy-env - 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: &mq-env # RabbitMQ Settings - RABBITMQ_HOST: ${RABBITMQ_HOST:-plane-mq} - RABBITMQ_PORT: ${RABBITMQ_PORT:-5672} - RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-plane} - RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:-plane} - RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST:-plane} - RABBITMQ_VHOST: ${RABBITMQ_VHOST:-plane} - -x-live-env: &live-env - API_BASE_URL: ${API_BASE_URL:-http://api:8000} - -x-app-env: &app-env - WEB_URL: ${WEB_URL:-http://localhost} - DEBUG: ${DEBUG:-0} - CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS} - GUNICORN_WORKERS: 1 - USE_MINIO: ${USE_MINIO:-1} - DATABASE_URL: ${DATABASE_URL:-postgresql://plane:plane@plane-db/plane} - SECRET_KEY: ${SECRET_KEY:-60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5} - AMQP_URL: ${AMQP_URL:-amqp://plane:plane@plane-mq:5672/plane} - API_KEY_RATE_LIMIT: ${API_KEY_RATE_LIMIT:-60/minute} - MINIO_ENDPOINT_SSL: ${MINIO_ENDPOINT_SSL:-0} - -services: - web: - image: artifacts.plane.so/makeplane/plane-frontend:${APP_RELEASE:-stable} - deploy: - replicas: ${WEB_REPLICAS:-1} - restart_policy: - condition: on-failure - depends_on: - - api - - worker - - space: - image: artifacts.plane.so/makeplane/plane-space:${APP_RELEASE:-stable} - deploy: - replicas: ${SPACE_REPLICAS:-1} - restart_policy: - condition: on-failure - depends_on: - - api - - worker - - web - - admin: - image: artifacts.plane.so/makeplane/plane-admin:${APP_RELEASE:-stable} - deploy: - replicas: ${ADMIN_REPLICAS:-1} - restart_policy: - condition: on-failure - depends_on: - - api - - web - - live: - image: artifacts.plane.so/makeplane/plane-live:${APP_RELEASE:-stable} - environment: - <<: [*live-env] - deploy: - replicas: ${LIVE_REPLICAS:-1} - restart_policy: - condition: on-failure - depends_on: - - api - - web - - api: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} - command: ./bin/docker-entrypoint-api.sh - deploy: - replicas: ${API_REPLICAS:-1} - restart_policy: - condition: on-failure - volumes: - - logs_api:/code/plane/logs - environment: - <<: [*app-env, *db-env, *redis-env, *minio-env, *aws-s3-env, *proxy-env] - depends_on: - - plane-db - - plane-redis - - plane-mq - - worker: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} - command: ./bin/docker-entrypoint-worker.sh - deploy: - replicas: ${WORKER_REPLICAS:-1} - restart_policy: - condition: on-failure - volumes: - - logs_worker:/code/plane/logs - environment: - <<: [*app-env, *db-env, *redis-env, *minio-env, *aws-s3-env, *proxy-env] - depends_on: - - api - - plane-db - - plane-redis - - plane-mq - - beat-worker: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} - command: ./bin/docker-entrypoint-beat.sh - deploy: - replicas: ${BEAT_WORKER_REPLICAS:-1} - restart_policy: - condition: on-failure - volumes: - - logs_beat-worker:/code/plane/logs - environment: - <<: [*app-env, *db-env, *redis-env, *minio-env, *aws-s3-env, *proxy-env] - depends_on: - - api - - plane-db - - plane-redis - - plane-mq - - migrator: - image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable} - command: ./bin/docker-entrypoint-migrator.sh - deploy: - replicas: 1 - restart_policy: - condition: on-failure - volumes: - - logs_migrator:/code/plane/logs - environment: - <<: [*app-env, *db-env, *redis-env, *minio-env, *aws-s3-env, *proxy-env] - depends_on: - - plane-db - - plane-redis - - # Comment this if you already have a database running - plane-db: - image: postgres:15.7-alpine - command: postgres -c 'max_connections=1000' - deploy: - replicas: 1 - restart_policy: - condition: on-failure - environment: - <<: *db-env - volumes: - - pgdata:/var/lib/postgresql/data - - plane-redis: - image: valkey/valkey:7.2.5-alpine - deploy: - replicas: 1 - restart_policy: - condition: on-failure - volumes: - - redisdata:/data - - plane-mq: - image: rabbitmq:3.13.6-management-alpine - deploy: - replicas: 1 - restart_policy: - condition: on-failure - environment: - <<: *mq-env - volumes: - - rabbitmq_data:/var/lib/rabbitmq - - # Comment this if you using any external s3 compatible storage - plane-minio: - image: minio/minio:latest - command: server /export --console-address ":9090" - deploy: - replicas: 1 - restart_policy: - condition: on-failure - environment: - <<: *minio-env - volumes: - - uploads:/export - - # Comment this if you already have a reverse proxy running - proxy: - image: artifacts.plane.so/makeplane/plane-proxy:${APP_RELEASE:-stable} - deploy: - replicas: 1 - restart_policy: - condition: on-failure - environment: - <<: *proxy-env - ports: - - target: 80 - published: ${LISTEN_HTTP_PORT:-80} - protocol: tcp - mode: host - - target: 443 - published: ${LISTEN_HTTPS_PORT:-443} - protocol: tcp - mode: host - volumes: - - proxy_config:/config - - proxy_data:/data - depends_on: - - web - - api - - space - - admin - - live - -volumes: - pgdata: - redisdata: - uploads: - logs_api: - logs_worker: - logs_beat-worker: - logs_migrator: - rabbitmq_data: - proxy_config: - proxy_data: diff --git a/deployments/cli/community/images/download.png b/deployments/cli/community/images/download.png deleted file mode 100644 index bb0d1183e68..00000000000 Binary files a/deployments/cli/community/images/download.png and /dev/null differ diff --git a/deployments/cli/community/images/migrate-error.png b/deployments/cli/community/images/migrate-error.png deleted file mode 100644 index f42ec441a7d..00000000000 Binary files a/deployments/cli/community/images/migrate-error.png and /dev/null differ diff --git a/deployments/cli/community/images/restart.png b/deployments/cli/community/images/restart.png deleted file mode 100644 index 0387599a018..00000000000 Binary files a/deployments/cli/community/images/restart.png and /dev/null differ diff --git a/deployments/cli/community/images/started.png b/deployments/cli/community/images/started.png deleted file mode 100644 index d6a0a0baaee..00000000000 Binary files a/deployments/cli/community/images/started.png and /dev/null differ diff --git a/deployments/cli/community/images/stopped.png b/deployments/cli/community/images/stopped.png deleted file mode 100644 index 0f5876882ac..00000000000 Binary files a/deployments/cli/community/images/stopped.png and /dev/null differ diff --git a/deployments/cli/community/images/upgrade.png b/deployments/cli/community/images/upgrade.png deleted file mode 100644 index b78fbbb6093..00000000000 Binary files a/deployments/cli/community/images/upgrade.png and /dev/null differ diff --git a/deployments/cli/community/install.sh b/deployments/cli/community/install.sh deleted file mode 100755 index 8b8a92ec122..00000000000 --- a/deployments/cli/community/install.sh +++ /dev/null @@ -1,681 +0,0 @@ -#!/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=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/deployments/cli/community" - -CPU_ARCH=$(uname -m) -OS_NAME=$(uname) -UPPER_CPU_ARCH=$(tr '[:lower:]' '[:upper:]' <<< "$CPU_ARCH") - -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 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 initialize(){ - printf "Please wait while we check the availability of Docker images for the selected release ($APP_RELEASE) with ${UPPER_CPU_ARCH} support." >&2 - - if [ "$CUSTOM_BUILD" == "true" ]; then - echo "" >&2 - echo "" >&2 - echo "${UPPER_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 "${UPPER_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 [ "$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 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/$GH_REPO.git - git clone "$REPO" "$PLANE_TEMP_CODE_DIR" --branch "$BRANCH" --single-branch --depth 1 - - cp "$PLANE_TEMP_CODE_DIR/deployments/cli/community/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 "" - - if [ "$APP_RELEASE" == "stable" ]; then - export APP_RELEASE=$(checkLatestRelease) - fi - - 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 - - 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.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)") - 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.yaml - 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.yaml $PLANE_INSTALL_DIR/docker-compose.yaml - 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.yaml $PLANE_INSTALL_DIR/docker-compose.yaml - 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 - - 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 exec $api_container_id python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/')" > /dev/null 2>&1; - 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() { - 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 - - echo "Upgrading Plane to the latest release..." - echo "" - - 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 " 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 backup_container_dir() { - local BACKUP_FOLDER=$1 - local CONTAINER_NAME=$2 - local CONTAINER_DATA_DIR=$3 - local SERVICE_FOLDER=$4 - - echo "Backing up $CONTAINER_NAME data..." - local CONTAINER_ID=$(/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH ps -q $CONTAINER_NAME") - if [ -z "$CONTAINER_ID" ]; then - echo "Error: $CONTAINER_NAME container not found. Make sure the services are running." - return 1 - fi - - # Create a temporary directory for the backup - mkdir -p "$BACKUP_FOLDER/$SERVICE_FOLDER" - - # Copy the data directory from the running container - echo "Copying $CONTAINER_NAME data directory..." - docker cp -q "$CONTAINER_ID:$CONTAINER_DATA_DIR/." "$BACKUP_FOLDER/$SERVICE_FOLDER/" - local cp_status=$? - - if [ $cp_status -ne 0 ]; then - echo "Error: Failed to copy $SERVICE_FOLDER data" - rm -rf $BACKUP_FOLDER/$SERVICE_FOLDER - return 1 - fi - - # Create tar.gz of the data - cd "$BACKUP_FOLDER" - tar -czf "${SERVICE_FOLDER}.tar.gz" "$SERVICE_FOLDER/" - local tar_status=$? - if [ $tar_status -eq 0 ]; then - rm -rf "$SERVICE_FOLDER/" - fi - cd - > /dev/null - - if [ $tar_status -ne 0 ]; then - echo "Error: Failed to create tar archive" - return 1 - fi - - echo "Successfully backed up $SERVICE_FOLDER data" -} - -function backupData() { - local datetime=$(date +"%Y%m%d-%H%M") - local BACKUP_FOLDER=$PLANE_INSTALL_DIR/backup/$datetime - mkdir -p "$BACKUP_FOLDER" - - # Check if docker-compose.yml exists - if [ ! -f "$DOCKER_FILE_PATH" ]; then - echo "Error: docker-compose.yml not found at $DOCKER_FILE_PATH" - exit 1 - fi - - backup_container_dir "$BACKUP_FOLDER" "plane-db" "/var/lib/postgresql/data" "pgdata" || exit 1 - backup_container_dir "$BACKUP_FOLDER" "plane-minio" "/export" "uploads" || exit 1 - backup_container_dir "$BACKUP_FOLDER" "plane-mq" "/var/lib/rabbitmq" "rabbitmq_data" || exit 1 - backup_container_dir "$BACKUP_FOLDER" "plane-redis" "/data" "redisdata" || exit 1 - - 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=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 - - 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 "$@" diff --git a/deployments/cli/community/migration-0.13-0.14.sh b/deployments/cli/community/migration-0.13-0.14.sh deleted file mode 100755 index d03f877805c..00000000000 --- a/deployments/cli/community/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/deployments/cli/community/restore-airgapped.sh b/deployments/cli/community/restore-airgapped.sh deleted file mode 100755 index 9da02fd869d..00000000000 --- a/deployments/cli/community/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/deployments/cli/community/restore.sh b/deployments/cli/community/restore.sh deleted file mode 100755 index 23b8de6cfd3..00000000000 --- a/deployments/cli/community/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/deployments/cli/community/variables.env b/deployments/cli/community/variables.env deleted file mode 100644 index 66265f9a1e8..00000000000 --- a/deployments/cli/community/variables.env +++ /dev/null @@ -1,79 +0,0 @@ -APP_DOMAIN=localhost -APP_RELEASE=stable -SSL=false - -WEB_REPLICAS=1 -SPACE_REPLICAS=1 -ADMIN_REPLICAS=1 -API_REPLICAS=1 -WORKER_REPLICAS=1 -BEAT_WORKER_REPLICAS=1 -LIVE_REPLICAS=1 - -LISTEN_HTTP_PORT=80 -LISTEN_HTTPS_PORT=443 - -WEB_URL=http://${APP_DOMAIN} -DEBUG=0 -CORS_ALLOWED_ORIGINS=http://${APP_DOMAIN} -API_BASE_URL=http://api:8000 - -#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= - -# RabbitMQ Settings -RABBITMQ_HOST=plane-mq -RABBITMQ_PORT=5672 -RABBITMQ_USER=plane -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 - -# 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 -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 - -# Force HTTPS for handling SSL Termination -MINIO_ENDPOINT_SSL=0 - -# API key rate limit -API_KEY_RATE_LIMIT=60/minute diff --git a/deployments/kubernetes/community/README.md b/deployments/kubernetes/community/README.md deleted file mode 100644 index c1000c7327c..00000000000 --- a/deployments/kubernetes/community/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Helm Chart: Plane Community - -Click on the below link to access the helm chart instructions. - -[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/makeplane)](https://artifacthub.io/packages/helm/makeplane/plane-ce) diff --git a/deployments/swarm/community/swarm.sh b/deployments/swarm/community/swarm.sh deleted file mode 100755 index d496c25e6de..00000000000 --- a/deployments/swarm/community/swarm.sh +++ /dev/null @@ -1,611 +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/deployments/cli/community" - -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 "$@"