diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..290e3f9738 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,87 @@ +FROM debian:buster + +LABEL maintainer="tech@appsmith.com" + +# Set workdir to /opt/appsmith +WORKDIR /opt/appsmith + +# Update APK packages - Base Layer +RUN apt-get update && apt-get install --no-install-recommends -y \ + supervisor curl cron certbot nginx gnupg \ + redis wget gettext openjdk-11-jre \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install MongoDB v4.0.5, Redis - Service Layer +RUN wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add - +RUN echo "deb [ arch=amd64,arm64 ]http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list \ + && apt-get remove wget -y + +# Install node v14 - Service Layer +RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \ + && apt-get -y install --no-install-recommends -y mongodb-org=4.4.6 nodejs \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Clean up cache file - Service layer +RUN rm -rf \ + /root/.cache \ + /root/.npm \ + /root/.pip \ + /usr/local/share/doc \ + /usr/share/doc \ + /usr/share/man \ + /var/lib/apt/lists/* \ + /tmp/* + +# Define volumes - Service Layer +VOLUME [ "/appsmith-stacks" ] + +# ------------------------------------------------------------------------ +# Add backend server - Application Layer +ARG JAR_FILE=./app/server/appsmith-server/target/server-*.jar +ARG PLUGIN_JARS=./app/server/appsmith-plugins/*/target/*.jar +ARG APPSMITH_SEGMENT_CE_KEY +ENV APPSMITH_SEGMENT_CE_KEY=${APPSMITH_SEGMENT_CE_KEY} +#Create the plugins directory +RUN mkdir -p ./backend ./editor ./rts ./backend/plugins ./templates ./utils + +#Add the jar to the container +COPY ${JAR_FILE} backend/server.jar +COPY ${PLUGIN_JARS} backend/plugins/ + +# Add client UI - Application Layer +COPY ./app/client/build editor/ + +# Add RTS - Application Layer +COPY ./app/rts/package.json ./app/rts/dist/* rts/ +COPY ./app/rts/node_modules rts/node_modules + +# Nginx & MongoDB config template - Configuration layer +COPY ./deploy/fat_container/templates/nginx_app.conf.sh ./deploy/fat_container/templates/mongo-init.js.sh ./deploy/fat_container/templates/docker.env.sh templates/ + +# Add bootstrapfile +COPY ./deploy/fat_container/entrypoint.sh ./deploy/fat_container/scripts/* ./ + +# Add uitl tools +COPY ./deploy/fat_container/utils ./utils +RUN cd ./utils && npm install && npm install -g . + +# Add process config to be run by supervisord +COPY ./deploy/fat_container/templates/supervisord.conf /etc/supervisor/supervisord.conf +COPY ./deploy/fat_container/templates/supervisord/ templates/supervisord/ + +# Add defined cron job +COPY ./deploy/fat_container/templates/cron.d /etc/cron.d/ +RUN chmod 0644 /etc/cron.d/* + +RUN chmod +x entrypoint.sh renew-certificate.sh + +# Update path to load appsmith utils tool as default +ENV PATH /opt/appsmith/utils/node_modules/.bin:$PATH + +EXPOSE 80 +EXPOSE 443 +EXPOSE 9001 +ENTRYPOINT [ "/opt/appsmith/entrypoint.sh" ] +CMD ["/usr/bin/supervisord" ,"-n"] \ No newline at end of file diff --git a/deploy/fat_container/.gitignore b/deploy/fat_container/.gitignore new file mode 100644 index 0000000000..51b4a89f32 --- /dev/null +++ b/deploy/fat_container/.gitignore @@ -0,0 +1,2 @@ +test/* +stacks/* \ No newline at end of file diff --git a/deploy/fat_container/README.md b/deploy/fat_container/README.md new file mode 100644 index 0000000000..0237b86da5 --- /dev/null +++ b/deploy/fat_container/README.md @@ -0,0 +1,104 @@ + +# I. Getting started +You can begin using appsmith via our cloud instance or by deploying appsmith yourself + +* [Using Appsmith Cloud](quick-start.md#appsmith-cloud) **\(recommended\):** Create a new application with just one click +* [Using Docker](quick-start.md#docker): Deploy anywhere using docker + +## Appsmith Cloud + +The fastest way to get started with appsmith is using our cloud-hosted version. It's as easy as + +1. [Create an Account](https://app.appsmith.com/user/signup) +2. [Start Building](core-concepts/building-the-ui/) + +# II. Setup Appsmith use fat container +## 1. Prerequisites +- Ensure `docker` and `docker-compose` is installed and currently running: + - Install Docker: [https://docs.docker.com/engine/install/](https://docs.docker.com/engine/install/) + - Install Docker Compose: [https://docs.docker.com/compose/install/](https://docs.docker.com/compose/install/) +## 2. Step to setup +- 1. Create `docker-compose.yaml` and copy the following content into it +``` +version: "3" +services: + appsmith: + image: appsmith_fat + container_name: appsmith_fat + ports: + - "80:80" + - "443:443" + - "9001:9001" + volumes: + - ./stacks:/appsmith-stacks + auto_update: + image: containrrr/watchtower + volumes: + - /var/run/docker.sock:/var/run/docker.sock + # Update check interval in seconds. + command: --interval 300 --label-enable --cleanup +``` +2. Start application +``` +docker-compose up -d +``` +- It takes several minutes to pull the docker image and initialize the application +3. Check if application running correctly. +``` +docker ps +#Output should look like this +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +3b8f2c9638d0 appsmith/appsmith "/opt/appsmith/entrypoint.sh" 17 minutes ago Up 17 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp appsmith +``` +## 3. Custom Domain & Config application +To host Appsmith on a custom domain, you can contact your domain registrar and update your DNS records. Most domain registrars have documentation on how you can do this yourself. + +* [GoDaddy](https://in.godaddy.com/help/create-a-subdomain-4080) +* [Amazon Route 53](https://aws.amazon.com/premiumsupport/knowledge-center/create-subdomain-route-53/) +* [Digital Ocean](https://www.digitalocean.com/docs/networking/dns/how-to/add-subdomain/) +* [NameCheap](https://www.namecheap.com/support/knowledgebase/article.aspx/9776/2237/how-to-create-a-subdomain-for-my-domain) +* [Domain.com](https://www.domain.com/help/article/domain-management-how-to-update-subdomains) + +Then, you can update your custom domain from the application's configuration UI +## 4. Instance Management Utilities +> Fat container provide some utils to support you easy to maintenance application +### 4.1 Export database +Our container also supports exporting data from the internal database for backup or reuse purpose + +Export the internal database (You can use command `docker ps` to check the name or the ID of container) +``` +docker exec appsmith_fat appsmith export_db +``` +The output file will be stored in mounted directory `/data/backup/data.archive` + +In case of you have changed the mounted point in the docker-compose file, please change the prefix `./deploy/fat_container/stacks` to the correct one + +Now, you can use this output file as a backup or as a migration file +### 4.2 Import database +It is also available to import data from another database into application's internal database + +First of all, you need to copy or move the gzip file to the container's mounted folder `/data/restore/data.archive` +(*Note: file name must be `data.archive` to ensure the absolute path works as expected*) + +Or you can copy directly to the running container using `docker cp` command +``` +docker cp appsmith_fat:/appsmith-stacks/data/restore +``` + +Then, simply run following command to import data to internal database +``` +docker exec appsmith_fat appsmith import_db +``` +### 4.3 Supervisord UI +To manage the application's processes using supervisord, you can use the supervisord UI + +You can use the browser to access port `9001` of the host (`http://localhost:9001` if you run the container on your local machine) +

+ +

+ +In this UI, you can manage your application's process. You should stop application's service (MongoDB, Redis) in case of using external service +## Troubleshooting +If at any time you encounter an error during the installation process, reach out to **support@appsmith.com** or join our [Discord Server](https://discord.com/invite/rBTTVJp) + +If you know the error and would like to reinstall Appsmith, simply delete the installation folder and the templates folder and execute the script again \ No newline at end of file diff --git a/deploy/fat_container/docker-compose.yml b/deploy/fat_container/docker-compose.yml new file mode 100644 index 0000000000..f181872afe --- /dev/null +++ b/deploy/fat_container/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3" +services: + appsmith: + build: + context: ../../ + container_name: appsmith_fat + ports: + - "80:80" + - "443:443" + - "9001:9001" + volumes: + - ./stacks:/appsmith-stacks + auto_update: + image: containrrr/watchtower + volumes: + - /var/run/docker.sock:/var/run/docker.sock + # Update check interval in seconds. + command: --interval 300 --label-enable --cleanup diff --git a/deploy/fat_container/entrypoint.sh b/deploy/fat_container/entrypoint.sh new file mode 100755 index 0000000000..e35d2b89e0 --- /dev/null +++ b/deploy/fat_container/entrypoint.sh @@ -0,0 +1,198 @@ +#!/usr/bin/env bash + +set -e + +check_initialized_db() { + echo 'Check initialized database' + shouldPerformInitdb=1 + for path in \ + "$MONGO_DB_PATH/WiredTiger" \ + "$MONGO_DB_PATH/journal" \ + "$MONGO_DB_PATH/local.0" \ + "$MONGO_DB_PATH/storage.bson"; do + if [ -e "$path" ]; then + shouldPerformInitdb=0 + return + fi + done + echo "Should initialize database" +} + +init_mongodb() { + echo "Init database" + MONGO_DB_PATH="/appsmith-stacks/data/mongodb" + MONGO_LOG_PATH="$MONGO_DB_PATH/log" + MONGO_DB_KEY="$MONGO_DB_PATH/key" + mkdir -p "$MONGO_DB_PATH" + touch "$MONGO_LOG_PATH" + + check_initialized_db + + if [[ $shouldPerformInitdb -gt 0 ]]; then + # Start installed MongoDB service - Dependencies Layer + mongod --fork --port 27017 --dbpath "$MONGO_DB_PATH" --logpath "$MONGO_LOG_PATH" + echo "Waiting 10s for mongodb init" + sleep 10 + bash "/opt/appsmith/templates/mongo-init.js.sh" "$APPSMITH_MONGO_USERNAME" "$APPSMITH_MONGO_PASSWORD" >"/appsmith-stacks/configuration/mongo-init.js" + mongo "127.0.0.1/${APPSMITH_MONGO_DATABASE}" /appsmith-stacks/configuration/mongo-init.js + echo "Seeding db done" + + echo "Enable replica set" + mongod --dbpath "$MONGO_DB_PATH" --shutdown || true + echo "Fork process" + openssl rand -base64 756 >"$MONGO_DB_KEY" + chmod go-rwx,u-wx "$MONGO_DB_KEY" + mongod --fork --port 27017 --dbpath "$MONGO_DB_PATH" --logpath "$MONGO_LOG_PATH" --replSet mr1 --keyFile "$MONGO_DB_KEY" --bind_ip localhost + echo "Waiting 10s for mongodb init with replica set" + sleep 10 + mongo "$APPSMITH_MONGODB_URI" --eval 'rs.initiate()' + mongod --dbpath "$MONGO_DB_PATH" --shutdown || true + fi +} + +init_ssl_cert() { + local domain="$1" + NGINX_SSL_CMNT="" + + local rsa_key_size=4096 + local data_path="/appsmith-stacks/data/certificate" + + mkdir -p "$data_path" "$data_path"/{conf,www} + + if ! [[ -e "$data_path/conf/options-ssl-nginx.conf" && -e "$data_path/conf/ssl-dhparams.pem" ]]; then + echo "Downloading recommended TLS parameters..." + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf >"$data_path/conf/options-ssl-nginx.conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem >"$data_path/conf/ssl-dhparams.pem" + echo + fi + + echo "Re-generating nginx config template with domain" + bash "/opt/appsmith/templates/nginx_app.conf.sh" "$NGINX_SSL_CMNT" "$APPSMITH_CUSTOM_DOMAIN" >"/etc/nginx/conf.d/nginx_app.conf.template" + + echo "Generating nginx configuration" + cat /etc/nginx/conf.d/nginx_app.conf.template | envsubst "$(printf '$%s,' $(env | grep -Eo '^APPSMITH_[A-Z0-9_]+'))" | sed -e 's|\${\(APPSMITH_[A-Z0-9_]*\)}||g' >/etc/nginx/sites-available/default + + local live_path="/etc/letsencrypt/live/$domain" + if [[ -e "$live_path" ]]; then + echo "Existing certificate for domain $domain" + nginx -s reload + return + fi + + echo "Creating certificate for '$domain'" + + echo "Requesting Let's Encrypt certificate for '$domain'..." + echo "Generating OpenSSL key for '$domain'..." + + mkdir -p "$live_path" && openssl req -x509 -nodes -newkey rsa:2048 -days 1 \ + -keyout "$live_path/privkey.pem" \ + -out "$live_path/fullchain.pem" \ + -subj "/CN=localhost" + + echo "Reload Nginx" + nginx -s reload + + echo "Removing key now that validation is done for $domain..." + rm -Rfv /etc/letsencrypt/live/$domain /etc/letsencrypt/archive/$domain /etc/letsencrypt/renewal/$domain.conf + + echo "Generating certification for domain $domain" + mkdir -p "$data_path/certbot" + certbot certonly --webroot --webroot-path="$data_path/certbot" \ + --register-unsafely-without-email \ + --domains $domain \ + --rsa-key-size $rsa_key_size \ + --agree-tos \ + --force-renewal + + echo "Reload nginx" + nginx -s reload +} + +configure_ssl() { + NGINX_SSL_CMNT="#" + + echo "Mounting Let's encrypt folder" + rm -rf /etc/letsencrypt + mkdir -p /appsmith-stacks/letsencrypt + ln -s /appsmith-stacks/letsencrypt /etc/letsencrypt + + echo "Generating nginx config template without domain" + bash "/opt/appsmith/templates/nginx_app.conf.sh" "$NGINX_SSL_CMNT" "$APPSMITH_CUSTOM_DOMAIN" > "/etc/nginx/conf.d/nginx_app.conf.template" + + echo "Generating nginx configuration" + cat /etc/nginx/conf.d/nginx_app.conf.template | envsubst "$(printf '$%s,' $(env | grep -Eo '^APPSMITH_[A-Z0-9_]+'))" | sed -e 's|\${\(APPSMITH_[A-Z0-9_]*\)}||g' > /etc/nginx/sites-available/default + nginx + + if [[ -n $APPSMITH_CUSTOM_DOMAIN ]]; then + init_ssl_cert "$APPSMITH_CUSTOM_DOMAIN" + fi + nginx -s stop +} + +configure_supervisord() { + SUPERVISORD_CONF_PATH="/opt/appsmith/templates/supervisord" + if [[ -f "/etc/supervisor/conf.d/"*.conf ]]; then + rm "/etc/supervisor/conf.d/"* + fi + + cp -f "$SUPERVISORD_CONF_PATH/application_process/"*.conf /etc/supervisor/conf.d + if [[ "$APPSMITH_MONGODB_URI" = "mongodb://appsmith:$APPSMITH_MONGO_PASSWORD@localhost/appsmith" ]]; then + cp "$SUPERVISORD_CONF_PATH/mongodb.conf" /etc/supervisor/conf.d/ + fi + if [[ "$APPSMITH_REDIS_URL" = "redis://127.0.0.1:6379" ]]; then + cp "$SUPERVISORD_CONF_PATH/redis.conf" /etc/supervisor/conf.d/ + fi +} + +echo 'Checking configuration file' +CONF_PATH="/appsmith-stacks/configuration" +ENV_PATH="$CONF_PATH/docker.env" +if ! [[ -e "$ENV_PATH" ]]; then + echo "Generating default configuration file" + mkdir -p "$CONF_PATH" + AUTO_GEN_MONGO_PASSWORD=$(tr -dc A-Za-z0-9 "$ENV_PATH" +fi + +if [[ -f /appsmith-stacks/configuration/docker.env ]]; then + echo 'Load environment configuration' + set -o allexport + . /appsmith-stacks/configuration/docker.env + set +o allexport +fi + +# Check for enviroment vairalbes +echo 'Checking environment configuration' +if [[ -z "${APPSMITH_MAIL_ENABLED}" ]]; then + unset APPSMITH_MAIL_ENABLED # If this field is empty is might cause application crash +fi + +if [[ -z "${APPSMITH_OAUTH2_GITHUB_CLIENT_ID}" ]] || [[ -z "${APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET}" ]]; then + unset APPSMITH_OAUTH2_GITHUB_CLIENT_ID # If this field is empty is might cause application crash + unset APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET +fi + +if [[ -z "${APPSMITH_OAUTH2_GOOGLE_CLIENT_ID}" ]] || [[ -z "${APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET}" ]]; then + unset APPSMITH_OAUTH2_GOOGLE_CLIENT_ID # If this field is empty is might cause application crash + unset APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET +fi + +if [[ -z "${APPSMITH_GOOGLE_MAPS_API_KEY}" ]]; then + unset APPSMITH_GOOGLE_MAPS_API_KEY +fi + +if [[ -z "${APPSMITH_RECAPTCHA_SITE_KEY}" ]] || [[ -z "${APPSMITH_RECAPTCHA_SECRET_KEY}" ]] || [[ -z "${APPSMITH_RECAPTCHA_ENABLED}" ]]; then + unset APPSMITH_RECAPTCHA_SITE_KEY # If this field is empty is might cause application crash + unset APPSMITH_RECAPTCHA_SECRET_KEY + unset APPSMITH_RECAPTCHA_ENABLED +fi + +# Main Section +init_mongodb +configure_ssl +configure_supervisord + +# Handle CMD command +exec "$@" \ No newline at end of file diff --git a/deploy/fat_container/images/appsmith_supervisord_ui.png b/deploy/fat_container/images/appsmith_supervisord_ui.png new file mode 100644 index 0000000000..523ff950de Binary files /dev/null and b/deploy/fat_container/images/appsmith_supervisord_ui.png differ diff --git a/deploy/fat_container/scripts/renew-certificate.sh b/deploy/fat_container/scripts/renew-certificate.sh new file mode 100644 index 0000000000..20a384d0ef --- /dev/null +++ b/deploy/fat_container/scripts/renew-certificate.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -e + +if [[ -f /appsmith-stacks/configuration/docker.env ]]; then + echo 'Load environment configuration' + set -o allexport + . /appsmith-stacks/configuration/docker.env + set +o allexport +fi + +if [[ -n $CUSTOM_DOMAIN ]]; then + #then run script + local data_path="/appsmith-stacks/data/certificate" + domain="$CUSTOM_DOMAIN" + local rsa_key_size=4096 + + certbot certonly --webroot --webroot-path="$data_path/certbot" \ + --register-unsafely-without-email \ + --domains $domain \ + --rsa-key-size $rsa_key_size \ + --agree-tos \ + --force-renewal + supervisorctl restart editor +else + echo 'Custom domain not configured. Cannot enable SSL without a custom domain.' >&2 +fi \ No newline at end of file diff --git a/deploy/fat_container/templates/cron.d/renew-certificate b/deploy/fat_container/templates/cron.d/renew-certificate new file mode 100644 index 0000000000..61e46e5b47 --- /dev/null +++ b/deploy/fat_container/templates/cron.d/renew-certificate @@ -0,0 +1 @@ +* * * * 0 root exec /opt/appsmith/renew-certificate.sh diff --git a/deploy/fat_container/templates/docker.env.sh b/deploy/fat_container/templates/docker.env.sh new file mode 100644 index 0000000000..8d1c9ab343 --- /dev/null +++ b/deploy/fat_container/templates/docker.env.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +set -o nounset + +MONGO_PASSWORD="$1" +ENCRYPTION_PASSWORD="$2" +ENCRYPTION_SALT="$3" + +cat < 0) { + shell.echo('application is not running, starting supervisord') + shell.exec('/usr/bin/supervisord') + } + }) + + shell.echo('stop backend & rts application before export database') + stop_application() + export_database() + shell.echo('start backend & rts application after export database') + shell.echo() + shell.echo('\033[0;33m++++++++++++++++++++ NOTE ++++++++++++++++++++') + shell.echo() + shell.echo('Please remember to also copy APPSMITH_ENCRYPTION_SALT and APPSMITH_ENCRYPTION_PASSWORD variables from the docker.env file to the target instance where you intend to import this database dump.') + shell.echo() + shell.echo('++++++++++++++++++++++++++++++++++++++++++++++\033[0m') + shell.echo() + } catch (err) { + shell.echo(err) + errorCode = 1 + } finally { + start_application(); + process.exit(errorCode); + } +} + +module.exports = { + runExportDatabase: main +}; \ No newline at end of file diff --git a/deploy/fat_container/utils/bin/import_db.js b/deploy/fat_container/utils/bin/import_db.js new file mode 100644 index 0000000000..8770b66eaa --- /dev/null +++ b/deploy/fat_container/utils/bin/import_db.js @@ -0,0 +1,49 @@ +// Init function export mongodb +var shell = require('shelljs') + +// Load env configuration +const RESTORE_PATH = '/appsmith-stacks/data/restore' + +function import_database() { + console.log('import_database ....') + const cmd = `mongorestore --uri='${process.env.APPSMITH_MONGODB_URI}' --gzip --archive=${RESTORE_PATH}/data.archive` + shell.exec(cmd) + console.log('import_database done') +} + +function stop_application() { + shell.exec('/usr/bin/supervisorctl stop backend rts') +} + +function start_application() { + shell.exec('/usr/bin/supervisorctl start backend rts') +} + +// Main application workflow +function main() { + let errorCode = 0 + try { + check_supervisord_status_cmd = '/usr/bin/supervisorctl' + shell.exec(check_supervisord_status_cmd, function (code) { + if (code > 0) { + shell.echo('application is not running, starting supervisord') + shell.exec('/usr/bin/supervisord') + } + }) + + shell.echo('stop backend & rts application before import database') + stop_application() + import_database() + shell.echo('start backend & rts application after import database') + } catch (err) { + shell.echo(err) + errorCode = 1 + } finally { + start_application(); + process.exit(errorCode); + } +} + +module.exports = { + runImportDatabase: main +}; \ No newline at end of file diff --git a/deploy/fat_container/utils/bin/index.js b/deploy/fat_container/utils/bin/index.js new file mode 100755 index 0000000000..9d1cecc48e --- /dev/null +++ b/deploy/fat_container/utils/bin/index.js @@ -0,0 +1,34 @@ +#! /usr/bin/env node + +const utils = require('./utils') +const export_db = require('./export_db.js') +const import_db = require('./import_db.js') +const yargs = require("yargs"); + +const APPLICATION_CONFIG_PATH='/appsmith-stacks/configuration/docker.env' + +// Loading latest application configuration +require('dotenv').config( + { path: APPLICATION_CONFIG_PATH } +) + +if(yargs.argv._[0] == 'export_db' || yargs.argv._[0] == 'ex'){ + console.log('Exporting database') + export_db.runExportDatabase(); + console.log('Export database done') + return; +} + +if(yargs.argv._[0] == 'import_db' || yargs.argv._[0] == 'im'){ + console.log('Importing database') + import_db.runImportDatabase(); + console.log('Importing database done') + return; +} + +if(yargs.argv._[0] == null){ + utils.showHelp(); + return; +} +utils.showHelp(); +return; \ No newline at end of file diff --git a/deploy/fat_container/utils/bin/utils.js b/deploy/fat_container/utils/bin/utils.js new file mode 100644 index 0000000000..dca9c70e56 --- /dev/null +++ b/deploy/fat_container/utils/bin/utils.js @@ -0,0 +1,14 @@ +const chalk = require('chalk') +const usage = chalk.hex('#83aaff')("\nUsage: appsmith to interactive with appsmith utils toool"); +module.exports = {showHelp: showHelp}; + + + +function showHelp() { + console.log(usage); + console.log('\nOptions:\r') + console.log('\tex, export_db\t\tExport interal database.\r') + console.log('\tim, import_db\t\tImport interal database.\r') + console.log('\t--help\t\t\t'+ 'Show help.' + '\t\t\t' + '[boolean]\n') +} + diff --git a/deploy/fat_container/utils/package-lock.json b/deploy/fat_container/utils/package-lock.json new file mode 100644 index 0000000000..af767ef55e --- /dev/null +++ b/deploy/fat_container/utils/package-lock.json @@ -0,0 +1,364 @@ +{ + "name": "appsmith_utils", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "boxen": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.1.tgz", + "integrity": "sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA==", + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.0", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz", + "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==", + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "requires": { + "string-width": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz", + "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + } + } +} diff --git a/deploy/fat_container/utils/package.json b/deploy/fat_container/utils/package.json new file mode 100644 index 0000000000..f49c5d54f2 --- /dev/null +++ b/deploy/fat_container/utils/package.json @@ -0,0 +1,24 @@ +{ + "name": "appsmith_utils", + "version": "1.0.0", + "description": "appsmith utils tool", + "main": "bin/index.js", + "author": "", + "license": "Apache-2.0", + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/appsmithorg/appsmith.git", + "directory": "deploy/fat_container" + }, + "dependencies": { + "boxen": "^5.0.1", + "chalk": "^4.1.2", + "dotenv": "^10.0.0", + "shelljs": "^0.8.4", + "yargs": "^17.1.1" + }, + "bin": { + "appsmith": "./bin/index.js" + } +}