diff --git a/ct/invoiceninja.sh b/ct/invoiceninja.sh new file mode 100644 index 000000000..01fa08d2c --- /dev/null +++ b/ct/invoiceninja.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://invoiceninja.com/ + +APP="InvoiceNinja" +var_tags="${var_tags:-invoicing;business}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-8}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -d /opt/invoiceninja ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "invoiceninja" "invoiceninja/invoiceninja"; then + msg_info "Stopping Services" + systemctl stop supervisor nginx php8.4-fpm + msg_ok "Stopped Services" + + msg_info "Creating Backup" + mkdir -p /tmp/invoiceninja_backup + cp /opt/invoiceninja/.env /tmp/invoiceninja_backup/ + cp -r /opt/invoiceninja/storage /tmp/invoiceninja_backup/ 2>/dev/null || true + cp -r /opt/invoiceninja/public/storage /tmp/invoiceninja_backup/public_storage 2>/dev/null || true + msg_ok "Created Backup" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "invoiceninja" "invoiceninja/invoiceninja" "prebuild" "latest" "/opt/invoiceninja" "invoiceninja.tar.gz" + + msg_info "Restoring Data" + cp /tmp/invoiceninja_backup/.env /opt/invoiceninja/ + cp -r /tmp/invoiceninja_backup/storage/* /opt/invoiceninja/storage/ 2>/dev/null || true + cp -r /tmp/invoiceninja_backup/public_storage/* /opt/invoiceninja/public/storage/ 2>/dev/null || true + rm -rf /tmp/invoiceninja_backup + msg_ok "Restored Data" + + msg_info "Running Migrations" + cd /opt/invoiceninja + $STD php artisan migrate --force + $STD php artisan config:clear + $STD php artisan cache:clear + $STD php artisan optimize + chown -R www-data:www-data /opt/invoiceninja + chmod -R 755 /opt/invoiceninja/storage + msg_ok "Ran Migrations" + + msg_info "Starting Services" + systemctl start php8.4-fpm nginx supervisor + msg_ok "Started Services" + + msg_ok "Updated Successfully" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080/setup${CL}" diff --git a/frontend/public/json/invoiceninja.json b/frontend/public/json/invoiceninja.json new file mode 100644 index 000000000..10c178e93 --- /dev/null +++ b/frontend/public/json/invoiceninja.json @@ -0,0 +1,48 @@ +{ + "name": "InvoiceNinja", + "slug": "invoiceninja", + "categories": [ + 3 + ], + "date_created": "2025-12-09", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 8080, + "documentation": "https://invoiceninja.github.io/selfhost.html", + "config_path": "/opt/invoiceninja/.env", + "website": "https://invoiceninja.com/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/invoice-ninja.webp", + "description": "Invoice Ninja is a free, open-source invoicing, quotes, expenses and time-tracking application for freelancers and businesses. Features include recurring invoices, online payments, client portal, and multi-company support.", + "install_methods": [ + { + "type": "default", + "script": "ct/invoiceninja.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "Debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "First visit http://IP:8080/setup to complete the initial configuration", + "type": "info" + }, + { + "text": "Database credentials are stored in ~/invoiceninja.creds", + "type": "info" + }, + { + "text": "Configure SMTP settings in /opt/invoiceninja/.env for email functionality", + "type": "warning" + } + ] +} diff --git a/install/invoiceninja-install.sh b/install/invoiceninja-install.sh new file mode 100644 index 000000000..1e6eb224a --- /dev/null +++ b/install/invoiceninja-install.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://invoiceninja.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt install -y \ + nginx \ + supervisor +msg_ok "Installed Dependencies" + +setup_mariadb +MARIADB_DB_NAME="invoiceninja" MARIADB_DB_USER="invoiceninja" setup_mariadb_db +PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,gmp,imagick,intl,mbstring,mysql,soap,xml,zip" setup_php +import_local_ip +fetch_and_deploy_gh_release "invoiceninja" "invoiceninja/invoiceninja" "prebuild" "latest" "/opt/invoiceninja" "invoiceninja.tar.gz" + +msg_info "Configuring InvoiceNinja" +cd /opt/invoiceninja +APP_KEY=$(php artisan key:generate --show) +cat </opt/invoiceninja/.env +APP_NAME="Invoice Ninja" +APP_ENV=production +APP_KEY=${APP_KEY} +APP_DEBUG=false +APP_URL=http://${LOCAL_IP}:8080 + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=${MARIADB_DB_NAME} +DB_USERNAME=${MARIADB_DB_USER} +DB_PASSWORD=${MARIADB_DB_PASS} + +MULTI_DB_ENABLED=false +DEMO_MODE=false + +BROADCAST_DRIVER=log +LOG_CHANNEL=stack +CACHE_DRIVER=file +QUEUE_CONNECTION=database +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +MAIL_MAILER=log +MAIL_HOST=null +MAIL_PORT=null +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="noreply@localhost" +MAIL_FROM_NAME="Invoice Ninja" + +REQUIRE_HTTPS=false +NINJA_ENVIRONMENT=selfhost +PDF_GENERATOR=snappdf + +TRUSTED_PROXIES=* +INTERNAL_QUEUE_ENABLED=false +EOF + +mkdir -p /opt/invoiceninja/bootstrap/cache +mkdir -p /opt/invoiceninja/storage/{app/public,framework/{cache/data,sessions,views},logs} +chown -R www-data:www-data /opt/invoiceninja +chmod -R 775 /opt/invoiceninja/storage /opt/invoiceninja/bootstrap/cache +msg_ok "Configured InvoiceNinja" + +msg_info "Setting up Database" +cd /opt/invoiceninja +$STD php artisan config:clear +$STD php artisan cache:clear +$STD php artisan route:clear +$STD php artisan view:clear +$STD php artisan migrate --force +$STD php artisan db:seed --force +$STD php artisan optimize +msg_ok "Set up Database" + +msg_info "Configuring Nginx" +cat <<'EOF' >/etc/nginx/sites-available/invoiceninja +server { + listen 8080; + server_name _; + root /opt/invoiceninja/public; + index index.php; + + client_max_body_size 50M; + charset utf-8; + + gzip on; + gzip_types application/javascript application/x-javascript text/javascript text/plain application/xml application/json; + gzip_proxied no-cache no-store private expired auth; + gzip_min_length 1000; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /index.php { + fastcgi_pass unix:/run/php/php8.4-fpm.sock; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + fastcgi_read_timeout 300; + } + + location ~ \.php$ { + return 403; + } + + location ~ /\.ht { + deny all; + } + + error_log /var/log/nginx/invoiceninja_error.log; + access_log /var/log/nginx/invoiceninja_access.log; +} +EOF + +ln -sf /etc/nginx/sites-available/invoiceninja /etc/nginx/sites-enabled/ +rm -f /etc/nginx/sites-enabled/default +$STD systemctl reload nginx +msg_ok "Configured Nginx" + +msg_info "Setting up Queue Worker" +cat <<'EOF' >/etc/supervisor/conf.d/invoiceninja-worker.conf +[program:invoiceninja-worker] +process_name=%(program_name)s_%(process_num)02d +command=php /opt/invoiceninja/artisan queue:work --sleep=3 --tries=3 --max-time=3600 +autostart=true +autorestart=true +stopasgroup=true +killasgroup=true +user=www-data +numprocs=2 +redirect_stderr=true +stdout_logfile=/var/log/invoiceninja-worker.log +stopwaitsecs=3600 +EOF + +touch /var/log/invoiceninja-worker.log +chown www-data:www-data /var/log/invoiceninja-worker.log +$STD supervisorctl reread +$STD supervisorctl update +msg_ok "Set up Queue Worker" + +msg_info "Setting up Cron" +cat <<'EOF' >/etc/cron.d/invoiceninja +* * * * * www-data cd /opt/invoiceninja && php artisan schedule:run >> /dev/null 2>&1 +EOF +msg_ok "Set up Cron" + +msg_info "Enabling Services" +systemctl enable -q --now php8.4-fpm nginx supervisor +msg_ok "Enabled Services" + +motd_ssh +customize +cleanup_lxc