#!/bin/bash #================================================= # GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= source _common.sh source ynh_install_ruby source /usr/share/yunohost/helpers #================================================= # MANAGE SCRIPT FAILURE #================================================= ynh_clean_setup () { ynh_clean_check_starting } # Exit if an error occurs during the execution of the script ynh_abort_if_errors #================================================= # RETRIEVE ARGUMENTS FROM THE MANIFEST #================================================= domain=$YNH_APP_ARG_DOMAIN #path_url=$YNH_APP_ARG_PATH path_url="/" admin=$YNH_APP_ARG_ADMIN is_public=$YNH_APP_ARG_IS_PUBLIC language=$YNH_APP_ARG_LANGUAGE admin_mail=$(ynh_user_get_info $admin 'mail') app=$YNH_APP_INSTANCE_NAME #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= ### About --time --weight and --time ### ynh_script_progression will show to your final users the progression of each scripts. ### In order to do that, --time --weight will represent the relative time of execution compared to the other steps in the script. ### --time is a packager option, it will show you the execution time since the previous call. ### This option should be removed before releasing your app. ### Use the execution time, given by --time, to estimate the weight of a step. ### A common way to do it is to set a weight equal to the execution time in second +1. ### The execution time is given for the duration since the previous call. So the weight should be applied to this previous call. ynh_script_progression --message="Validating installation parameters..." --time --weight=2 ### If the app uses nginx as web server (written in HTML/PHP in most cases), the final path should be "/var/www/$app". ### If the app provides an internal web server (or uses another application server such as uwsgi), the final path should be "/opt/yunohost/$app" final_path=/var/www/$app #final_path=/opt/yunohost/$app test ! -e "$final_path" || ynh_die --message="This path already contains a folder" # Register (book) web path ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url #================================================= # STORE SETTINGS FROM MANIFEST #================================================= ynh_script_progression --message="Storing installation settings..." --time --weight=2 ynh_app_setting_set --app=$app --key=domain --value=$domain ynh_app_setting_set --app=$app --key=path --value=$path_url ynh_app_setting_set --app=$app --key=admin --value=$admin ynh_app_setting_set --app=$app --key=is_public --value=$is_public ynh_app_setting_set --app=$app --key=language --value=$language #================================================= # STANDARD MODIFICATIONS #================================================= # FIND AND OPEN A PORT #================================================= ynh_script_progression --message="Configuring firewall..." --time --weight=1 ### Use these lines if you have to open a port for the application ### `ynh_find_port` will find the first available port starting from the given port. ### If you're not using these lines: ### - Remove the section "CLOSE A PORT" in the remove script # Find an available port port_web=$(ynh_find_port --port=3000) # Open the port ynh_app_setting_set --app=$app --key=port_web --value=$port_web # Optional: Expose this port publicly # (N.B. : you only need to do this if the app actually needs to expose the port publicly. # If you do this and the app doesn't actually need you are CREATING SECURITY HOLES IN THE SERVER !) # Open the port # ynh_exec_warn_less yunohost firewall allow --no-upnp TCP $port #================================================= # INSTALL DEPENDENCIES #================================================= ynh_script_progression --message="Installing dependencies..." --time --weight=7 ### `ynh_install_app_dependencies` allows you to add any "apt" dependencies to the package. ### Those deb packages will be installed as dependencies of this package. ### If you're not using this helper: ### - Remove the section "REMOVE DEPENDENCIES" in the remove script ### - Remove the variable "pkg_dependencies" in _common.sh ### - As well as the section "REINSTALL DEPENDENCIES" in the restore script ### - And the section "UPGRADE DEPENDENCIES" in the upgrade script ynh_install_app_dependencies $pkg_dependencies #================================================= # CREATE A MYSQL DATABASE #================================================= ynh_script_progression --message="Creating a MySQL database..." --time --weight=2 ### Use these lines if you need a database for the application. ### `ynh_mysql_setup_db` will create a database, an associated user and a ramdom password. ### The password will be stored as 'mysqlpwd' into the app settings, ### and will be available as $db_pwd ### If you're not using these lines: ### - Remove the section "BACKUP THE MYSQL DATABASE" in the backup script ### - Remove also the section "REMOVE THE MYSQL DATABASE" in the remove script ### - As well as the section "RESTORE THE MYSQL DATABASE" in the restore script db_name=$(ynh_sanitize_dbid --db_name=$app) db_user=$db_name ynh_app_setting_set --app=$app --key=db_name --value=$db_name ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= ynh_script_progression --message="Setting up source files..." --time --weight=2 ### `ynh_setup_source` is used to install an app from a zip or tar.gz file, ### downloaded from an upstream source, like a git repository. ### `ynh_setup_source` use the file conf/app.src ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src mkdir $final_path ynh_setup_source --dest_dir="$final_path/live" #ynh_setup_source --dest_dir="$final_path" #================================================= # NGINX CONFIGURATION #================================================= ynh_script_progression --message="Configuring nginx web server..." --time --weight=2 ### `ynh_add_nginx_config` will use the file conf/nginx.conf # Create a dedicated nginx config ynh_replace_string --match_string="proxy_pass http://127.0.0.1:__PORT__;" --replace_string="proxy_pass http://127.0.0.1:$port_web;" --target_file="../conf/nginx.conf" ynh_add_nginx_config #================================================= # CREATE DEDICATED USER #================================================= ynh_script_progression --message="Configuring system user..." --time --weight=2 # Create a system user #ynh_system_user_create --username=$app # Create a system user allowing login #ynh_system_user_create $app $final_path 1 # Create a system user ynh_system_user_create --username=$app --home_dir=$final_path #================================================= # SPECIFIC SETUP #================================================= pwd ls -al # INSTALLING RUBY AND BUNDLER #================================================= ynh_script_progression --message="Installing Ruby..." --time --weight=321 ynh_install_ruby --ruby_version=$RUBY_VERSION /opt/rbenv/versions/$RUBY_VERSION/bin/gem update --system --no-document #/opt/rbenv/versions/$RUBY_VERSION/bin/gem install bundler --no-document #================================================= # Setup #================================================= #ynh_script_progression --message="Setup..." --time --weight=780 # Set right permissions #chown -R "$app":"$app" $final_path #mkdir -p "/var/log/$app" #chown -R "$app":"$app" "/var/log/$app" #================================================= # MODIFY A CONFIG FILE #================================================= ynh_script_progression --message="Modifying a config file..." --time --weight=2 ### `ynh_replace_string` is used to replace a string in a file. ### (It's compatible with sed regular expressions syntax) cp -f ../conf/env.sample "$final_path/live/.env" config_file="$final_path/live/.env" ynh_replace_string --match_string="EXPOSED_PORT=3000" --replace_string="EXPOSED_PORT=$port_web" --target_file="$config_file" secret_key=$(ynh_string_random --length=48 | base64) ynh_replace_string --match_string="SECRET_KEY_BASE=changeme123" --replace_string="SECRET_KEY_BASE=$secret_key" --target_file="$config_file" pseudo_key=$(ynh_string_random --length=48 | base64) ynh_replace_string --match_string="PSEUDO_KEY_PARAMS_KEY=changeme456" --replace_string="PSEUDO_KEY_PARAMS_KEY=$pseudo_key" --target_file="$config_file" ynh_replace_string --match_string="RAILS_ENV=development" --replace_string="RAILS_ENV=production" --target_file="$config_file" ynh_replace_string --match_string="DB_DATABASE=standard_notes_db" --replace_string="DB_DATABASE=$db_name" --target_file="$config_file" ynh_replace_string --match_string="DB_USERNAME=std_notes_user" --replace_string="DB_USERNAME=$db_user" --target_file="$config_file" ynh_replace_string --match_string="DB_PASSWORD=changeme123" --replace_string="DB_PASSWORD=$db_pwd" --target_file="$config_file" #================================================= # INSTALLING Standard Notes - Synicing Server #================================================= ynh_script_progression --message="Installing Standard Notes - Synicing Server..." --time --weight=153 chown -R "$app": "$final_path" pushd "$final_path/live" exec_as "$app" env PATH=$PATH /opt/rbenv/versions/$RUBY_VERSION/bin/bundle config set path 'vendor/bundle' exec_as "$app" env PATH=$PATH /opt/rbenv/versions/$RUBY_VERSION/bin/bundle config set with 'development' exec_as "$app" env PATH=$PATH /opt/rbenv/versions/$RUBY_VERSION/bin/bundle install #exec_as "$app" env PATH=$PATH yarn install --pure-lockfile #exec_as "$app" echo "SAFETY_ASSURED=1">> .env.production exec_as "$app" env PATH=$PATH RAILS_ENV=production /opt/rbenv/versions/$RUBY_VERSION/bin/bundle exec rails db:create db:migrate #exec_as "$app" env PATH=$PATH RAILS_ENV=production /opt/rbenv/versions/$RUBY_VERSION/bin/bundle exec rails assets:precompile --quiet #exec_as "$app" env PATH=$PATH RAILS_ENV=production /opt/rbenv/versions/$RUBY_VERSION/bin/bundle exec rake mastodon:webpush:generate_vapid_key > key.txt #exec_as "$app" env PATH=$PATH RAILS_ENV=production bin/tootctl accounts create "$admin" --email="$admin_mail" --confirmed --role=admin > acc.txt popd #(cd "$final_path" # Install bundler, a gems installer #gem install bundler # Install without documentation #exec_as $app echo "gem: --no-ri --no-rdoc" >> "$final_path/.gemrc") # Install dependencies #exec_login_as $app bundle config set path 'vendor/bundle' #exec_login_as $app bundle config set with 'development' #exec_login_as $app bundle install # Database Migrate #exec_login_as $app rails db:create db:migrate #================================================= #================================================= # SETUP APPLICATION WITH CURL #================================================= ### Use these lines only if the app installation needs to be finalized through ### web forms. We generally don't want to ask the final user, ### so we're going to use curl to automatically fill the fields and submit the ### forms. # Set right permissions for curl install #chown -R $app: $final_path # Set the app as temporarily public for curl call #ynh_script_progression --message="Configuring SSOwat..." --time --time --weight=1 #ynh_app_setting_set --app=$app --key=skipped_uris --value="/" # Reload SSOwat config #yunohost app ssowatconf # Reload Nginx #ynh_systemd_action --service_name=nginx --action=reload # Installation with curl #ynh_script_progression --message="Finalizing installation..." --time --time --weight=1 #ynh_local_curl "/INSTALL_PATH" "key1=value1" "key2=value2" "key3=value3" # Remove the public access #if [ $is_public -eq 0 ] #then # ynh_app_setting_delete --app=$app --key=skipped_uris #fi #================================================= # SETUP SYSTEMD #================================================= ynh_script_progression --message="Configuring a systemd service..." --time --weight=2 ### `ynh_systemd_config` is used to configure a systemd script for an app. ### It can be used for apps that use sysvinit (with adaptation) or systemd. ### Have a look at the app to be sure this app needs a systemd script. ### `ynh_systemd_config` will use the file conf/systemd.service ### If you're not using these lines: ### - You can remove those files in conf/. ### - Remove the section "BACKUP SYSTEMD" in the backup script ### - Remove also the section "STOP AND REMOVE SERVICE" in the remove script ### - As well as the section "RESTORE SYSTEMD" in the restore script ### - And the section "SETUP SYSTEMD" in the upgrade script # Create a dedicated systemd config #ynh_add_systemd_config ynh_replace_string --match_string="__PORT_WEB__" --replace_string="$port_web" --target_file="../conf/systemd.service" ynh_replace_string --match_string="__RUBY_VERSION__" --replace_string="$RUBY_VERSION" --target_file="../conf/systemd.service" ynh_add_systemd_config --service="$app" --template="systemd.service" #================================================= # STORE THE CONFIG FILE CHECKSUM #================================================= ### `ynh_store_file_checksum` is used to store the checksum of a file. ### That way, during the upgrade script, by using `ynh_backup_if_checksum_is_different`, ### you can make a backup of this file before modifying it again if the admin had modified it. # Calculate and store the config file checksum into the app settings ynh_store_file_checksum --file="$config_file" #================================================= # GENERIC FINALIZATION #================================================= # SECURE FILES AND DIRECTORIES #================================================= ynh_script_progression --message="Securing files and directories..." --time --weight=1 ### For security reason, any app should set the permissions to root: before anything else. ### Then, if write authorization is needed, any access should be given only to directories ### that really need such authorization. # Set permissions to app files chown -R root: $final_path chown $app: $final_path mkdir -p $final_path/live/log chown -R $app: $final_path/live/log/ mkdir -p $final_path/live/tmp chown -R $app: $final_path/live/tmp/ #================================================= # SETUP LOGROTATE #================================================= ynh_script_progression --message="Configuring log rotation..." --time --weight=2 ### `ynh_use_logrotate` is used to configure a logrotate configuration for the logs of this app. ### Use this helper only if there is effectively a log file for this app. ### If you're not using this helper: ### - Remove the section "BACKUP LOGROTATE" in the backup script ### - Remove also the section "REMOVE LOGROTATE CONFIGURATION" in the remove script ### - As well as the section "RESTORE THE LOGROTATE CONFIGURATION" in the restore script ### - And the section "SETUP LOGROTATE" in the upgrade script mkdir -p /var/log/snserver chown -R $app: /var/log/snserver # Use logrotate to manage application logfile(s) ynh_use_logrotate --logfile="$final_path/log/production.log" ynh_use_logrotate --logfile="/var/log/snserver/snserver.log" #================================================= # INTEGRATE SERVICE IN YUNOHOST #================================================= ### `yunohost service add` integrates a service in YunoHost. It then gets ### displayed in the admin interface and through the others `yunohost service` commands. ### (N.B. : this line only makes sense if the app adds a service to the system!) ### If you're not using these lines: ### - You can remove these files in conf/. ### - Remove the section "REMOVE SERVICE FROM ADMIN PANEL" in the remove script ### - As well as the section "ADVERTISE SERVICE IN ADMIN PANEL" in the restore script yunohost service add $app --description "Standard Notes - Syncing Server" ### With YunoHost 3.8 you will then be able to: ### - specify a list of ports that needs to be publicly exposed (c.f. --needs_exposed_ports) ### which will then be checked by YunoHost's diagnosis system ### - specify a custom command to check the status of the service (c.f. --test_status) ### though it's only needed for weird cases where 'systemctl status' doesn't do a good job ### - specify a custom command to check / validate the configuration of the service (c.f. --test_conf) ### for example, the command to check the configuration of nginx is "nginx -t" #================================================= # START SYSTEMD SERVICE #================================================= ynh_script_progression --message="Starting a systemd service..." --time --weight=1 ### `ynh_systemd_action` is used to start a systemd service for an app. ### Only needed if you have configure a systemd service ### If you're not using these lines: ### - Remove the section "STOP SYSTEMD SERVICE" and "START SYSTEMD SERVICE" in the backup script ### - As well as the section "START SYSTEMD SERVICE" in the restore script ### - As well as the section"STOP SYSTEMD SERVICE" and "START SYSTEMD SERVICE" in the upgrade script ### - And the section "STOP SYSTEMD SERVICE" and "START SYSTEMD SERVICE" in the change_url script # Start a systemd service ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" #================================================= # SETUP FAIL2BAN #================================================= #ynh_script_progression --message="Configuring fail2ban..." --time --time --weight=1 # Create a dedicated fail2ban config #ynh_add_fail2ban_config --logpath="/var/log/nginx/${domain}-error.log" --failregex="Regex to match into the log for a failed login" #================================================= # SETUP SSOWAT #================================================= ynh_script_progression --message="Configuring SSOwat..." --time --weight=1 # Make app public if necessary or protect it if [ $is_public -eq 1 ] then ynh_permission_update --permission "main" --add "visitors" fi #================================================= # RELOAD NGINX #================================================= ynh_script_progression --message="Reloading nginx web server..." --time --weight=1 ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT #================================================= ynh_script_progression --message="Installation of $app completed" --time --last