diff --git a/build/common/commands/new.py b/build/common/commands/new.py index b54bfc18..b3484aa1 100644 --- a/build/common/commands/new.py +++ b/build/common/commands/new.py @@ -24,33 +24,43 @@ except ImportError: def main(): config = get_config() - db_type = 'mariadb' - db_port = config.get('db_port', 3306) - db_host = config.get('db_host') - site_name = os.environ.get("SITE_NAME", 'site1.localhost') - db_root_username = os.environ.get("DB_ROOT_USER", 'root') - mariadb_root_password = get_password("MYSQL_ROOT_PASSWORD", 'admin') + db_type = "mariadb" + db_port = config.get("db_port", 3306) + db_host = config.get("db_host") + site_name = os.environ.get("SITE_NAME", "site1.localhost") + db_root_username = os.environ.get("DB_ROOT_USER", "root") + mariadb_root_password = get_password("MYSQL_ROOT_PASSWORD", "admin") postgres_root_password = get_password("POSTGRES_PASSWORD") db_root_password = mariadb_root_password if postgres_root_password: - db_type = 'postgres' + db_type = "postgres" db_host = os.environ.get("POSTGRES_HOST") db_port = 5432 db_root_password = postgres_root_password if not db_host: - db_host = config.get('db_host') - print('Environment variable POSTGRES_HOST not found.') - print('Using db_host from common_site_config.json') + db_host = config.get("db_host") + print("Environment variable POSTGRES_HOST not found.") + print("Using db_host from common_site_config.json") sites_path = os.getcwd() common_site_config_path = os.path.join(sites_path, COMMON_SITE_CONFIG_FILE) - update_site_config("root_login", db_root_username, validate = False, site_config_path = common_site_config_path) - update_site_config("root_password", db_root_password, validate = False, site_config_path = common_site_config_path) + update_site_config( + "root_login", + db_root_username, + validate=False, + site_config_path=common_site_config_path, + ) + update_site_config( + "root_password", + db_root_password, + validate=False, + site_config_path=common_site_config_path, + ) force = True if os.environ.get("FORCE", None) else False install_apps = os.environ.get("INSTALL_APPS", None) - install_apps = install_apps.split(',') if install_apps else [] + install_apps = install_apps.split(",") if install_apps else [] frappe.init(site_name, new_site=True) if semantic_version.Version(frappe.__version__).major > 11: @@ -59,7 +69,7 @@ def main(): site_name, mariadb_root_username=db_root_username, mariadb_root_password=db_root_password, - admin_password=get_password("ADMIN_PASSWORD", 'admin'), + admin_password=get_password("ADMIN_PASSWORD", "admin"), verbose=True, install_apps=install_apps, source_sql=None, @@ -75,7 +85,7 @@ def main(): site_name, mariadb_root_username=db_root_username, mariadb_root_password=db_root_password, - admin_password=get_password("ADMIN_PASSWORD", 'admin'), + admin_password=get_password("ADMIN_PASSWORD", "admin"), verbose=True, install_apps=install_apps, source_sql=None, @@ -83,16 +93,23 @@ def main(): reinstall=False, ) - if db_type == "mariadb": site_config = get_site_config(site_name) - db_name = site_config.get('db_name') - db_password = site_config.get('db_password') + db_name = site_config.get("db_name") + db_password = site_config.get("db_password") - mysql_command = ["mysql", f"-h{db_host}", f"-u{db_root_username}", f"-p{mariadb_root_password}", "-e"] + mysql_command = [ + "mysql", + "-h{db_host}".format(db_host=db_host), + "-u{db_root_username}".format(db_root_username=db_root_username), + "-p{mariadb_root_password}".format(mariadb_root_password=mariadb_root_password), + "-e", + ] # Drop User if exists - command = mysql_command + [f"DROP USER IF EXISTS '{db_name}'; FLUSH PRIVILEGES;"] + command = mysql_command + [ + "DROP USER IF EXISTS '{db_name}'; FLUSH PRIVILEGES;".format(db_name=db_name) + ] run_command(command) # Grant permission to database and set password @@ -102,10 +119,16 @@ def main(): if config.get(RDS_DB) or site_config.get(RDS_DB): grant_privileges = RDS_PRIVILEGES - command = mysql_command + [f"\ + command = mysql_command + [ + "\ CREATE USER IF NOT EXISTS '{db_name}'@'%' IDENTIFIED BY '{db_password}'; \ GRANT {grant_privileges} ON `{db_name}`.* TO '{db_name}'@'%'; \ - FLUSH PRIVILEGES;"] + FLUSH PRIVILEGES;".format( + db_name=db_name, + db_password=db_password, + grant_privileges=grant_privileges, + ) + ] run_command(command) if frappe.redis_server: diff --git a/build/common/commands/restore_backup.py b/build/common/commands/restore_backup.py index 9989d18d..32917fa4 100644 --- a/build/common/commands/restore_backup.py +++ b/build/common/commands/restore_backup.py @@ -10,7 +10,7 @@ from frappe.installer import ( make_conf, get_conf_params, make_site_dirs, - update_site_config + update_site_config, ) from constants import COMMON_SITE_CONFIG_FILE, DATE_FORMAT, RDS_DB, RDS_PRIVILEGES from utils import ( @@ -25,69 +25,59 @@ from utils import ( def get_backup_dir(): - return os.path.join( - os.path.expanduser('~'), - 'backups' - ) + return os.path.join(os.path.expanduser("~"), "backups") def decompress_db(database_file, site): command = ["gunzip", "-c", database_file] with open(database_file.replace(".gz", ""), "w") as db_file: - print('Extract Database GZip for site {}'.format(site)) + print("Extract Database GZip for site {}".format(site)) run_command(command, stdout=db_file) def restore_database(files_base, site_config_path, site): # restore database - database_file = files_base + '-database.sql.gz' + database_file = files_base + "-database.sql.gz" decompress_db(database_file, site) config = get_config() # Set db_type if it exists in backup site_config.json - set_key_in_site_config('db_type', site, site_config_path) + set_key_in_site_config("db_type", site, site_config_path) # Set db_host if it exists in backup site_config.json - set_key_in_site_config('db_host', site, site_config_path) + set_key_in_site_config("db_host", site, site_config_path) # Set db_port if it exists in backup site_config.json - set_key_in_site_config('db_port', site, site_config_path) + set_key_in_site_config("db_port", site, site_config_path) # get updated site_config site_config = get_site_config(site) # if no db_type exists, default to mariadb - db_type = site_config.get('db_type', 'mariadb') + db_type = site_config.get("db_type", "mariadb") is_database_restored = False - if db_type == 'mariadb': + if db_type == "mariadb": restore_mariadb( - config=config, - site_config=site_config, - database_file=database_file) - is_database_restored = True - elif db_type == 'postgres': - restore_postgres( - config=config, - site_config=site_config, - database_file=database_file) + config=config, site_config=site_config, database_file=database_file + ) is_database_restored = True if is_database_restored: # Set encryption_key if it exists in backup site_config.json - set_key_in_site_config('encryption_key', site, site_config_path) + set_key_in_site_config("encryption_key", site, site_config_path) def restore_files(files_base): - public_files = files_base + '-files.tar' + public_files = files_base + "-files.tar" # extract tar public_tar = tarfile.open(public_files) - print('Extracting {}'.format(public_files)) + print("Extracting {}".format(public_files)) public_tar.extractall() def restore_private_files(files_base): - private_files = files_base + '-private-files.tar' + private_files = files_base + "-private-files.tar" private_tar = tarfile.open(private_files) - print('Extracting {}'.format(private_files)) + print("Extracting {}".format(private_files)) private_tar.extractall() @@ -96,15 +86,15 @@ def pull_backup_from_s3(): # https://stackoverflow.com/a/54672690 s3 = boto3.resource( - 's3', - region_name=os.environ.get('REGION'), - aws_access_key_id=os.environ.get('ACCESS_KEY_ID'), - aws_secret_access_key=os.environ.get('SECRET_ACCESS_KEY'), - endpoint_url=os.environ.get('ENDPOINT_URL') + "s3", + region_name=os.environ.get("REGION"), + aws_access_key_id=os.environ.get("ACCESS_KEY_ID"), + aws_secret_access_key=os.environ.get("SECRET_ACCESS_KEY"), + endpoint_url=os.environ.get("ENDPOINT_URL"), ) - bucket_dir = os.environ.get('BUCKET_DIR') - bucket_name = os.environ.get('BUCKET_NAME') + bucket_dir = os.environ.get("BUCKET_DIR") + bucket_name = os.environ.get("BUCKET_NAME") bucket = s3.Bucket(bucket_name) # Change directory to /home/frappe/backups @@ -118,10 +108,10 @@ def pull_backup_from_s3(): for obj in bucket.objects.filter(Prefix=bucket_dir): if obj.get()["ContentType"] == "application/x-directory": continue - backup_file = obj.key.replace(os.path.join(bucket_dir, ''), '') + backup_file = obj.key.replace(os.path.join(bucket_dir, ""), "") backup_files.append(backup_file) - site_name, timestamp, backup_type = backup_file.split('/') - site_timestamp = site_name + '/' + timestamp + site_name, timestamp, backup_type = backup_file.split("/") + site_timestamp = site_name + "/" + timestamp sites.add(site_name) site_timestamps.add(site_timestamp) @@ -129,13 +119,11 @@ def pull_backup_from_s3(): for site in sites: backup_timestamps = [] for site_timestamp in site_timestamps: - site_name, timestamp = site_timestamp.split('/') + site_name, timestamp = site_timestamp.split("/") if site == site_name: - timestamp_datetime = datetime.datetime.strptime( - timestamp, DATE_FORMAT - ) + timestamp_datetime = datetime.datetime.strptime(timestamp, DATE_FORMAT) backup_timestamps.append(timestamp) - download_backups.append(site + '/' + max(backup_timestamps)) + download_backups.append(site + "/" + max(backup_timestamps)) # Only download latest backups for backup_file in backup_files: @@ -143,89 +131,53 @@ def pull_backup_from_s3(): if backup in backup_file: if not os.path.exists(os.path.dirname(backup_file)): os.makedirs(os.path.dirname(backup_file)) - print('Downloading {}'.format(backup_file)) - bucket.download_file(bucket_dir + '/' + backup_file, backup_file) + print("Downloading {}".format(backup_file)) + bucket.download_file(bucket_dir + "/" + backup_file, backup_file) - os.chdir(os.path.join(os.path.expanduser('~'), 'frappe-bench', 'sites')) - - -def restore_postgres(config, site_config, database_file): - # common config - common_site_config_path = os.path.join(os.getcwd(), COMMON_SITE_CONFIG_FILE) - - db_root_user = config.get('root_login') - if not db_root_user: - postgres_user = os.environ.get('DB_ROOT_USER') - if not postgres_user: - print('Variable DB_ROOT_USER not set') - exit(1) - - db_root_user = postgres_user - update_site_config( - "root_login", - db_root_user, - validate=False, - site_config_path=common_site_config_path) - - db_root_password = config.get('root_password') - if not db_root_password: - root_password = get_password('POSTGRES_PASSWORD') - if not root_password: - print('Variable POSTGRES_PASSWORD not set') - exit(1) - - db_root_password = root_password - update_site_config( - "root_password", - db_root_password, - validate=False, - site_config_path=common_site_config_path) - - # site config - db_host = site_config.get('db_host') - db_port = site_config.get('db_port', 5432) - db_name = site_config.get('db_name') - db_password = site_config.get('db_password') - - psql_command = ["psql"] - psql_uri = f"postgres://{db_root_user}:{db_root_password}@{db_host}:{db_port}" - - print('Restoring PostgreSQL') - run_command(psql_command + [psql_uri, "-c", f"DROP DATABASE IF EXISTS \"{db_name}\""]) - run_command(psql_command + [psql_uri, "-c", f"DROP USER IF EXISTS {db_name}"]) - run_command(psql_command + [psql_uri, "-c", f"CREATE DATABASE \"{db_name}\""]) - run_command(psql_command + [psql_uri, "-c", f"CREATE user {db_name} password '{db_password}'"]) - run_command(psql_command + [psql_uri, "-c", f"GRANT ALL PRIVILEGES ON DATABASE \"{db_name}\" TO {db_name}"]) - with open(database_file.replace('.gz', ''), 'r') as db_file: - run_command(psql_command + [f"{psql_uri}/{db_name}", "<"], stdin=db_file) + os.chdir(os.path.join(os.path.expanduser("~"), "frappe-bench", "sites")) def restore_mariadb(config, site_config, database_file): - db_root_password = get_password('MYSQL_ROOT_PASSWORD') + db_root_password = get_password("MYSQL_ROOT_PASSWORD") if not db_root_password: - print('Variable MYSQL_ROOT_PASSWORD not set') + print("Variable MYSQL_ROOT_PASSWORD not set") exit(1) - db_root_user = os.environ.get("DB_ROOT_USER", 'root') + db_root_user = os.environ.get("DB_ROOT_USER", "root") - db_host = site_config.get('db_host', config.get('db_host')) - db_port = site_config.get('db_port', config.get('db_port', 3306)) - db_name = site_config.get('db_name') - db_password = site_config.get('db_password') + db_host = site_config.get("db_host", config.get("db_host")) + db_port = site_config.get("db_port", config.get("db_port", 3306)) + db_name = site_config.get("db_name") + db_password = site_config.get("db_password") # mysql command prefix - mysql_command = ["mysql", f"-u{db_root_user}", f"-h{db_host}", f"-p{db_root_password}", f"-P{db_port}"] + mysql_command = [ + "mysql", + "-u{db_root_user}".format(db_root_user=db_root_user), + "-h{db_host}".format(db_host=db_host), + "-p{db_root_password}".format(db_root_password=db_root_password), + "-P{db_port}".format(db_port=db_port), + ] # drop db if exists for clean restore - drop_database = mysql_command + ["-e", f"DROP DATABASE IF EXISTS `{db_name}`;"] + drop_database = mysql_command + ["-e", "DROP DATABASE IF EXISTS `{db_name}`;".format(db_name=db_name)] run_command(drop_database) # create db - create_database = mysql_command + ["-e", f"CREATE DATABASE IF NOT EXISTS `{db_name}`;"] + create_database = mysql_command + [ + "-e", + "CREATE DATABASE IF NOT EXISTS `{db_name}`;".format(db_name=db_name), + ] run_command(create_database) # create user - create_user = mysql_command + ["-e", f"CREATE USER IF NOT EXISTS '{db_name}'@'%' IDENTIFIED BY '{db_password}'; FLUSH PRIVILEGES;"] + create_user = mysql_command + [ + "-e", + "CREATE USER IF NOT EXISTS '{db_name}'@'%' IDENTIFIED BY '{db_password}'; FLUSH PRIVILEGES;".format( + db_name=db_name, + db_password=db_password, + ), + ] run_command(create_user) # grant db privileges to user @@ -236,12 +188,19 @@ def restore_mariadb(config, site_config, database_file): if config.get(RDS_DB) or site_config.get(RDS_DB): grant_privileges = RDS_PRIVILEGES - grant_privileges_command = mysql_command + ["-e", f"GRANT {grant_privileges} ON `{db_name}`.* TO '{db_name}'@'%' IDENTIFIED BY '{db_password}'; FLUSH PRIVILEGES;"] + grant_privileges_command = mysql_command + [ + "-e", + "GRANT {grant_privileges} ON `{db_name}`.* TO '{db_name}'@'%' IDENTIFIED BY '{db_password}'; FLUSH PRIVILEGES;".format( + grant_privileges=grant_privileges, + db_name=db_name, + db_password=db_password, + ), + ] run_command(grant_privileges_command) - print('Restoring MariaDB') - with open(database_file.replace('.gz', ''), 'r') as db_file: - run_command(mysql_command + [f"{db_name}"], stdin=db_file) + print("Restoring MariaDB") + with open(database_file.replace(".gz", ""), "r") as db_file: + run_command(mysql_command + ["{db_name}".format(db_name=db_name)], stdin=db_file) def main(): @@ -251,35 +210,38 @@ def main(): pull_backup_from_s3() for site in list_directories(backup_dir): - site_slug = site.replace('.', '_') - backups = [datetime.datetime.strptime(backup, DATE_FORMAT) for backup in list_directories(os.path.join(backup_dir, site))] + site_slug = site.replace(".", "_") + backups = [ + datetime.datetime.strptime(backup, DATE_FORMAT) + for backup in list_directories(os.path.join(backup_dir, site)) + ] latest_backup = max(backups).strftime(DATE_FORMAT) - files_base = os.path.join(backup_dir, site, latest_backup, '') - files_base += latest_backup + '-' + site_slug - site_config_path = files_base + '-site_config_backup.json' + files_base = os.path.join(backup_dir, site, latest_backup, "") + files_base += latest_backup + "-" + site_slug + site_config_path = files_base + "-site_config_backup.json" if not os.path.exists(site_config_path): - site_config_path = os.path.join(backup_dir, site, 'site_config.json') + site_config_path = os.path.join(backup_dir, site, "site_config.json") if site in get_sites(): - print('Overwrite site {}'.format(site)) + print("Overwrite site {}".format(site)) restore_database(files_base, site_config_path, site) restore_private_files(files_base) restore_files(files_base) else: site_config = get_conf_params( - db_name='_' + hashlib.sha1(site.encode()).hexdigest()[:16], - db_password=random_string(16) + db_name="_" + hashlib.sha1(site.encode()).hexdigest()[:16], + db_password=random_string(16), ) frappe.local.site = site frappe.local.sites_path = os.getcwd() - frappe.local.site_path = os.getcwd() + '/' + site + frappe.local.site_path = os.getcwd() + "/" + site make_conf( - db_name=site_config.get('db_name'), - db_password=site_config.get('db_password'), + db_name=site_config.get("db_name"), + db_password=site_config.get("db_password"), ) make_site_dirs() - print('Create site {}'.format(site)) + print("Create site {}".format(site)) restore_database(files_base, site_config_path, site) restore_private_files(files_base) restore_files(files_base) diff --git a/build/common/commands/utils.py b/build/common/commands/utils.py index eaa9a2cf..8c359f10 100644 --- a/build/common/commands/utils.py +++ b/build/common/commands/utils.py @@ -19,9 +19,9 @@ def run_command(command, stdout=None, stdin=None, stderr=None): out, error = process.communicate() if process.returncode: print("Something went wrong:") - print(f"return code: {process.returncode}") - print(f"stdout:\n{out}") - print(f"\nstderr:\n{error}") + print("return code: {returncode}".format(returncode=process.returncode)) + print("stdout:\n{out}".format(out=out)) + print("\nstderr:\n{error}".format(error=error)) exit(process.returncode) @@ -105,7 +105,7 @@ def save_config(config): def get_password(env_var, default=None): - return os.environ.get(env_var) or get_password_from_secret(f"{env_var}_FILE") or default + return os.environ.get(env_var) or get_password_from_secret("{env_var}_FILE".format(env_var=env_var)) or default def get_password_from_secret(env_var): diff --git a/build/common/worker/install_app.sh b/build/common/worker/install_app.sh index d7de0842..3ab00a5b 100755 --- a/build/common/worker/install_app.sh +++ b/build/common/worker/install_app.sh @@ -7,4 +7,4 @@ APP_BRANCH=${3} [[ -n "${APP_BRANCH}" ]] && BRANCH="-b ${APP_BRANCH}" git clone --depth 1 -o upstream ${APP_REPO} ${BRANCH} /home/frappe/frappe-bench/apps/${APP_NAME} -/home/frappe/frappe-bench/env/bin/pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/${APP_NAME} +/home/frappe/frappe-bench/env/bin/pip install --no-cache-dir -e /home/frappe/frappe-bench/apps/${APP_NAME} diff --git a/build/erpnext-nginx/Dockerfile b/build/erpnext-nginx/Dockerfile index 31abf795..468237e5 100644 --- a/build/erpnext-nginx/Dockerfile +++ b/build/erpnext-nginx/Dockerfile @@ -1,26 +1,14 @@ -ARG NODE_IMAGE_TAG=14-buster-slim +ARG IMAGE_TAG=v10 ARG DOCKER_REGISTRY_PREFIX=frappe -ARG IMAGE_TAG=develop - -FROM node:${NODE_IMAGE_TAG} - -ARG GIT_REPO=https://github.com/frappe/erpnext -ARG GIT_BRANCH=develop -ARG FRAPPE_BRANCH=${GIT_BRANCH} +FROM ${DOCKER_REGISTRY_PREFIX}/erpnext-worker:${IMAGE_TAG} COPY build/erpnext-nginx/install_app.sh /install_app -RUN chmod +x /install_app && \ - apt-get update -y && \ - apt-get install build-essential git python2 -y && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* -RUN /install_app erpnext ${GIT_REPO} ${GIT_BRANCH} ${FRAPPE_BRANCH} +RUN /install_app FROM ${DOCKER_REGISTRY_PREFIX}/frappe-nginx:${IMAGE_TAG} -COPY --from=0 /home/frappe/frappe-bench/sites/ /var/www/html/ -COPY --from=0 /rsync /rsync +COPY --from=0 /home/frappe/sites /var/www/html RUN echo "erpnext" >> /var/www/html/apps.txt VOLUME [ "/assets" ] diff --git a/build/erpnext-nginx/install_app.sh b/build/erpnext-nginx/install_app.sh index d3e30769..4526dc26 100755 --- a/build/erpnext-nginx/install_app.sh +++ b/build/erpnext-nginx/install_app.sh @@ -1,43 +1,12 @@ #!/bin/bash -APP_NAME=${1} -APP_REPO=${2} -APP_BRANCH=${3} -FRAPPE_BRANCH=${4} - -[ "${APP_BRANCH}" ] && BRANCH="-b ${APP_BRANCH}" - -mkdir -p /home/frappe/frappe-bench/sites/assets -cd /home/frappe/frappe-bench -echo -ne "frappe\n${APP_NAME}" >/home/frappe/frappe-bench/sites/apps.txt - -mkdir -p apps -cd apps -git clone --depth 1 https://github.com/frappe/frappe -b ${FRAPPE_BRANCH} -git clone --depth 1 ${APP_REPO} ${BRANCH} ${APP_NAME} - -echo "Install frappe NodeJS dependencies . . ." +npm i yarn -g cd /home/frappe/frappe-bench/apps/frappe -yarn -echo "Install ${APP_NAME} NodeJS dependencies . . ." -cd /home/frappe/frappe-bench/apps/${APP_NAME} -yarn -echo "Build browser assets . . ." -cd /home/frappe/frappe-bench/apps/frappe -yarn production --app ${APP_NAME} -echo "Install frappe NodeJS production dependencies . . ." -cd /home/frappe/frappe-bench/apps/frappe -yarn install --production=true -echo "Install ${APP_NAME} NodeJS production dependencies . . ." -cd /home/frappe/frappe-bench/apps/${APP_NAME} -yarn install --production=true - -mkdir -p /home/frappe/frappe-bench/sites/assets/${APP_NAME} -cp -R /home/frappe/frappe-bench/apps/${APP_NAME}/${APP_NAME}/public/* /home/frappe/frappe-bench/sites/assets/${APP_NAME} - -# Add frappe and all the apps available under in frappe-bench here -echo "rsync -a --delete /var/www/html/assets/frappe /assets" >/rsync -echo "rsync -a --delete /var/www/html/assets/${APP_NAME} /assets" >>/rsync -chmod +x /rsync - -rm /home/frappe/frappe-bench/sites/apps.txt +rm -fr node_modules && yarn +cd /home/frappe/frappe-bench/sites +echo "frappe" > /home/frappe/frappe-bench/sites/apps.txt +echo "erpnext" >> /home/frappe/frappe-bench/sites/apps.txt +/home/frappe/frappe-bench/env/bin/python -c "import frappe; frappe.init(''); import frappe.build; frappe.build.setup(); frappe.build.make_asset_dirs(make_copy=True)" +node --use_strict ../apps/frappe/frappe/build.js --build +mkdir -p /home/frappe/sites +cp -R assets /home/frappe/sites diff --git a/build/erpnext-worker/Dockerfile b/build/erpnext-worker/Dockerfile index 8b1e16f0..3531bc52 100644 --- a/build/erpnext-worker/Dockerfile +++ b/build/erpnext-worker/Dockerfile @@ -1,8 +1,8 @@ -ARG IMAGE_TAG=develop +ARG IMAGE_TAG=v10 ARG DOCKER_REGISTRY_PREFIX=frappe FROM ${DOCKER_REGISTRY_PREFIX}/frappe-worker:${IMAGE_TAG} ARG GIT_REPO=https://github.com/frappe/erpnext -ARG GIT_BRANCH=develop +ARG GIT_BRANCH=v10.x.x RUN install_app erpnext ${GIT_REPO} ${GIT_BRANCH} diff --git a/build/frappe-nginx/Dockerfile b/build/frappe-nginx/Dockerfile index 5c5a607d..36372740 100644 --- a/build/frappe-nginx/Dockerfile +++ b/build/frappe-nginx/Dockerfile @@ -2,58 +2,31 @@ # This is done to ensures that node-sass binary remains common. # node-sass is required to enable website theme feature used # by Website Manager role in Frappe Framework -FROM python:3.7-slim-buster +ARG IMAGE_TAG=v10 +ARG DOCKER_REGISTRY_PREFIX=frappe +FROM ${DOCKER_REGISTRY_PREFIX}/frappe-worker:${IMAGE_TAG} -ARG GIT_REPO=https://github.com/frappe/frappe -ARG GIT_BRANCH=develop - -ENV NVM_DIR=/root/.nvm -ENV NODE_VERSION=14.17.0 -ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}" -RUN apt-get update -y \ - && apt-get install wget python2 git build-essential -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && wget https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh \ - && chmod +x install.sh \ - && ./install.sh \ - && . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION} \ - && nvm use v${NODE_VERSION} && npm install -g yarn - -WORKDIR /home/frappe/frappe-bench -RUN mkdir -p /home/frappe/frappe-bench/sites \ - && echo "frappe" > /home/frappe/frappe-bench/sites/apps.txt - -RUN mkdir -p apps sites/assets/css \ - && cd apps \ - && git clone --depth 1 ${GIT_REPO} --branch $GIT_BRANCH - -RUN cd /home/frappe/frappe-bench/apps/frappe \ - && yarn \ - && yarn run production \ - && yarn install --production=true - -RUN node --version \ - && npm --version \ - && yarn --version +RUN npm i yarn -g \ + && cd /home/frappe/frappe-bench/apps/frappe \ + && rm -fr node_modules && yarn \ + && cd /home/frappe/frappe-bench/sites \ + && echo "frappe" > /home/frappe/frappe-bench/sites/apps.txt \ + && /home/frappe/frappe-bench/env/bin/python -c "import frappe; frappe.init(''); import frappe.build; frappe.build.setup(); frappe.build.make_asset_dirs(make_copy=True)" \ + && node --use_strict ../apps/frappe/frappe/build.js --build \ + && mkdir -p /home/frappe/sites \ + && cp -R assets /home/frappe/sites RUN git clone --depth 1 https://github.com/frappe/bench /tmp/bench \ - && mkdir -p /var/www/error_pages \ - && cp -r /tmp/bench/bench/config/templates /var/www/error_pages - -RUN mkdir -p /home/frappe/frappe-bench/sites/assets/frappe/ \ - && cp -R /home/frappe/frappe-bench/apps/frappe/frappe/public/* /home/frappe/frappe-bench/sites/assets/frappe \ - && cp -R /home/frappe/frappe-bench/apps/frappe/node_modules /home/frappe/frappe-bench/sites/assets/frappe/ + && mkdir -p /home/frappe/www/error_pages \ + && cp -r /tmp/bench/bench/config/templates /home/frappe/www/error_pages FROM nginx:latest -COPY --from=0 /home/frappe/frappe-bench/sites /var/www/html/ -COPY --from=0 /var/www/error_pages /var/www/ +COPY --from=0 /home/frappe/sites /var/www/html +COPY --from=0 /home/frappe/www/error_pages /var/www/ COPY build/common/nginx-default.conf.template /etc/nginx/conf.d/default.conf.template COPY build/frappe-nginx/docker-entrypoint.sh / -RUN apt-get update && apt-get install -y rsync && apt-get clean \ - && echo "#!/bin/bash" > /rsync \ - && chmod +x /rsync +RUN apt-get update && apt-get install -y rsync && apt-get clean VOLUME [ "/assets" ] diff --git a/build/frappe-nginx/docker-entrypoint.sh b/build/frappe-nginx/docker-entrypoint.sh index e1a29277..4ba602d5 100755 --- a/build/frappe-nginx/docker-entrypoint.sh +++ b/build/frappe-nginx/docker-entrypoint.sh @@ -6,8 +6,6 @@ rsync -a --delete /var/www/html/assets/* /assets -/rsync - touch /var/www/html/sites/.build -r "$(ls -td /assets/* | head -n 1)" [[ -z "${FRAPPE_PY}" ]] && FRAPPE_PY='0.0.0.0' diff --git a/build/frappe-socketio/Dockerfile b/build/frappe-socketio/Dockerfile index e7b72e09..6e8e09f4 100644 --- a/build/frappe-socketio/Dockerfile +++ b/build/frappe-socketio/Dockerfile @@ -1,11 +1,11 @@ FROM alpine/git ARG GIT_REPO=https://github.com/frappe/frappe.git -ARG GIT_BRANCH=develop +ARG GIT_BRANCH=v10.x.x RUN git clone ${GIT_REPO} /opt/frappe -b ${GIT_BRANCH} --depth 1 -FROM node:buster-slim +FROM node:8-slim # Add frappe user RUN useradd -ms /bin/bash frappe @@ -15,9 +15,8 @@ RUN mkdir -p /home/frappe/frappe-bench/sites /home/frappe/frappe-bench/apps/frap && chown -R frappe:frappe /home/frappe # Download socketio and purge curl package -COPY build/frappe-socketio/package.json /home/frappe/frappe-bench/apps/frappe COPY --from=0 /opt/frappe/socketio.js /home/frappe/frappe-bench/apps/frappe/socketio.js -COPY --from=0 /opt/frappe/node_utils.js /home/frappe/frappe-bench/apps/frappe/node_utils.js +COPY --from=0 /opt/frappe/package.json /home/frappe/frappe-bench/apps/frappe/package.json RUN cd /home/frappe/frappe-bench/apps/frappe \ && npm install --only=production \ @@ -30,7 +29,7 @@ RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat USER frappe -WORKDIR /home/frappe/frappe-bench/sites +WORKDIR /home/frappe/frappe-bench ENTRYPOINT ["docker-entrypoint.sh"] CMD ["start"] diff --git a/build/frappe-worker/Dockerfile b/build/frappe-worker/Dockerfile index ada2bda3..4c1c4d50 100644 --- a/build/frappe-worker/Dockerfile +++ b/build/frappe-worker/Dockerfile @@ -1,14 +1,14 @@ -FROM python:3.7-slim-buster +FROM python:2.7-stretch # Add non root user without password RUN useradd -ms /bin/bash frappe ARG GIT_REPO=https://github.com/frappe/frappe -ARG GIT_BRANCH=develop +ARG GIT_BRANCH=v10.x.x ARG ARCH=amd64 ENV PYTHONUNBUFFERED 1 ENV NVM_DIR=/home/frappe/.nvm -ENV NODE_VERSION=14.17.0 +ENV NODE_VERSION=8.17.0 ENV PATH="/home/frappe/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}" # Install dependencies @@ -17,7 +17,6 @@ RUN apt-get update -y && apt-get install \ # for frappe framework git \ mariadb-client \ - postgresql-client \ gettext-base \ wget \ wait-for-it \ @@ -43,8 +42,8 @@ RUN apt-get update -y && apt-get install \ # Detect arch, download and install wkhtmltox && if [ `uname -m` = 'aarch64' ]; then export ARCH=arm64; fi \ && if [ `uname -m` = 'x86_64' ]; then export ARCH=amd64; fi \ - && wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_${ARCH}.deb \ - && dpkg -i wkhtmltox_0.12.6-1.buster_${ARCH}.deb && rm wkhtmltox_0.12.6-1.buster_${ARCH}.deb \ + && wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.stretch_${ARCH}.deb \ + && dpkg -i wkhtmltox_0.12.6-1.stretch_${ARCH}.deb && rm wkhtmltox_0.12.6-1.stretch_${ARCH}.deb \ && wget https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh \ && chown -R frappe:frappe /home/frappe @@ -64,13 +63,13 @@ RUN bash install.sh \ RUN mkdir -p apps logs commands sites /home/frappe/backups # Setup python environment -RUN python -m venv env \ +RUN virtualenv env \ && . env/bin/activate \ - && pip3 install --upgrade pip \ - && pip3 install gevent \ + && pip install --upgrade pip \ + && pip install gevent \ && cd apps \ && git clone --depth 1 -o upstream ${GIT_REPO} --branch ${GIT_BRANCH} \ - && pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe + && pip install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe # Copy scripts and templates COPY build/common/commands/* /home/frappe/frappe-bench/commands/