diff --git a/ct/wger.sh b/ct/wger.sh index 8629b4de3..845745ff5 100644 --- a/ct/wger.sh +++ b/ct/wger.sh @@ -31,7 +31,7 @@ function update_script() { if check_for_gh_release "wger" "wger-project/wger"; then msg_info "Stopping Service" - systemctl stop apache2 + systemctl stop redis-server nginx celery celery-beat wger msg_ok "Stopped Service" msg_info "Backing up Data" @@ -45,6 +45,7 @@ function update_script() { cp -r /opt/wger_media_backup/. /opt/wger/media cp /opt/wger_env_backup /opt/wger/.env rm -rf /opt/wger_media_backup /opt/wger_env_backup + msg_ok "Restored Data" msg_info "Updating wger" @@ -56,9 +57,9 @@ function update_script() { $STD uv run python manage.py collectstatic --no-input msg_ok "Updated wger" - msg_info "Starting Service" - systemctl start apache2 - msg_ok "Started Service" + msg_info "Starting Services" + systemctl start redis-server nginx celery celery-beat wger + msg_ok "Started Services" msg_ok "Updated Successfully" fi exit @@ -71,4 +72,4 @@ 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}${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}" diff --git a/frontend/public/json/wger.json b/frontend/public/json/wger.json new file mode 100644 index 000000000..804ef56ef --- /dev/null +++ b/frontend/public/json/wger.json @@ -0,0 +1,40 @@ +{ + "name": "wger", + "slug": "wger", + "categories": [ + 24 + ], + "date_created": "2025-02-24", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3000, + "documentation": "https://wger.readthedocs.io/en/latest/index.html", + "website": "https://wger.de", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/wger.webp", + "config_path": "/opt/wger/wger.env", + "description": "wger (ˈvɛɡɐ) Workout Manager is a free, open source web application that helps you manage your personal workouts, weight and diet plans and can also be used as a simple gym management utility. It offers a REST API as well, for easy integration with other projects and tools.", + "install_methods": [ + { + "type": "default", + "script": "ct/wger.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": "admin", + "password": "adminadmin" + }, + "notes": [ + { + "text": "This LXC also runs Celery and Redis to synchronize workouts and ingredients", + "type": "info" + } + ] +} diff --git a/install/wger-install.sh b/install/wger-install.sh index 0e8e9ace7..df8a089d0 100644 --- a/install/wger-install.sh +++ b/install/wger-install.sh @@ -14,18 +14,18 @@ network_check update_os msg_info "Installing Dependencies" -$STD apt-get install -y \ - apache2 \ - libapache2-mod-wsgi-py3 \ +$STD apt install -y \ + build-essential \ + nginx \ + redis-server \ libpq-dev msg_ok "Installed Dependencies" +import_local_ip NODE_VERSION="22" NODE_MODULE="sass" setup_nodejs setup_uv - PG_VERSION="16" setup_postgresql PG_DB_NAME="wger" PG_DB_USER="wger" setup_postgresql_db - fetch_and_deploy_gh_release "wger" "wger-project/wger" "tarball" "latest" "/opt/wger" msg_info "Setting up wger" @@ -36,85 +36,147 @@ $STD corepack enable $STD npm install $STD npm run build:css:sass $STD uv venv -$STD uv pip install . +$STD uv pip install . --group docker SECRET_KEY=$(openssl rand -base64 40) cat </opt/wger/.env +DJANGO_SETTINGS_MODULE=settings.main +PYTHONPATH=/opt/wger + DJANGO_DB_ENGINE=django.db.backends.postgresql DJANGO_DB_DATABASE=${PG_DB_NAME} DJANGO_DB_USER=${PG_DB_USER} DJANGO_DB_PASSWORD=${PG_DB_PASS} DJANGO_DB_HOST=localhost DJANGO_DB_PORT=5432 +DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME} + DJANGO_MEDIA_ROOT=/opt/wger/media DJANGO_STATIC_ROOT=/opt/wger/static +DJANGO_STATIC_URL=/static/ + +ALLOWED_HOSTS=${LOCAL_IP},localhost,127.0.0.1 +CSRF_TRUSTED_ORIGINS=http://${LOCAL_IP}:3000 + +USE_X_FORWARDED_HOST=True +SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,http + +DJANGO_CACHE_BACKEND=django_redis.cache.RedisCache +DJANGO_CACHE_LOCATION=redis://127.0.0.1:6379/1 +DJANGO_CACHE_TIMEOUT=300 +DJANGO_CACHE_CLIENT_CLASS=django_redis.client.DefaultClient +AXES_CACHE_ALIAS=default + +USE_CELERY=True +CELERY_BROKER=redis://127.0.0.1:6379/2 +CELERY_BACKEND=redis://127.0.0.1:6379/2 + +SITE_URL=http://${LOCAL_IP}:3000 SECRET_KEY=${SECRET_KEY} EOF -cat <<'WSGI' >/opt/wger/wsgi_wrapper.py -import os -from pathlib import Path - -env_file = Path('/opt/wger/.env') -if env_file.exists(): - for line in env_file.read_text().splitlines(): - if line.strip() and not line.startswith('#') and '=' in line: - key, value = line.split('=', 1) - os.environ.setdefault(key.strip(), value.strip()) - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.main') - -from wger.wsgi import application -WSGI set -a && source /opt/wger/.env && set +a -export DJANGO_SETTINGS_MODULE=settings.main -$STD uv run python manage.py migrate -$STD uv run python manage.py loaddata languages -$STD uv run python manage.py loaddata gym_config -$STD uv run python manage.py loaddata groups -$STD uv run python manage.py loaddata site +$STD uv run wger bootstrap $STD uv run python manage.py collectstatic --no-input cat </etc/systemd/system/wger.service +[Unit] +Description=wger Gunicorn +After=network.target -msg_info "Creating Service" -cat </etc/apache2/sites-available/wger.conf - - - Require all granted - - +[Service] +User=root +WorkingDirectory=/opt/wger +EnvironmentFile=/opt/wger/.env +ExecStart=/opt/wger/.venv/bin/gunicorn \ + --bind 127.0.0.1:8000 \ + --workers 3 \ + --threads 2 \ + --timeout 120 \ + wger.wsgi:application +Restart=always - - WSGIApplicationGroup %{GLOBAL} - WSGIDaemonProcess wger python-path=/opt/wger python-home=/opt/wger/.venv - WSGIProcessGroup wger - WSGIScriptAlias / /opt/wger/wsgi_wrapper.py - WSGIPassAuthorization On - - Alias /static/ /opt/wger/static/ - - Require all granted - - - Alias /media/ /opt/wger/media/ - - Require all granted - - - ErrorLog /var/log/apache2/wger-error.log - CustomLog /var/log/apache2/wger-access.log combined - +[Install] +WantedBy=multi-user.target EOF -$STD a2dissite 000-default.conf -$STD a2ensite wger -systemctl restart apache2 -msg_ok "Created Service" +cat </etc/systemd/system/celery.service +[Unit] +Description=wger Celery Worker +After=network.target redis-server.service +Requires=redis-server.service + +[Service] +WorkingDirectory=/opt/wger +EnvironmentFile=/opt/wger/.env +ExecStart=/opt/wger/.venv/bin/celery -A wger worker -l info +Restart=always + +[Install] +WantedBy=multi-user.target +EOF + +mkdir -p /var/lib/wger/celery +chmod 700 /var/lib/wger/celery +cat </etc/systemd/system/celery-beat.service +[Unit] +Description=wger Celery Beat +After=network.target redis-server.service +Requires=redis-server.service + +[Service] +WorkingDirectory=/opt/wger +EnvironmentFile=/opt/wger/.env +ExecStart=/opt/wger/.venv/bin/celery -A wger beat -l info \ + --schedule /var/lib/wger/celery/celerybeat-schedule +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +cat <<'EOF' >/etc/nginx/sites-available/wger +server { + listen 3000; + server_name _; + + client_max_body_size 20M; + + location /static/ { + alias /opt/wger/static/; + expires 30d; + } + + location /media/ { + alias /opt/wger/media/; + } + + location / { + proxy_pass http://127.0.0.1:8000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + } +} +EOF +$STD rm -f /etc/nginx/sites-enabled/default +$STD ln -sf /etc/nginx/sites-available/wger /etc/nginx/sites-enabled/wger +systemctl enable -q --now redis-server nginx wger celery celery-beat +systemctl restart nginx +msg_ok "Created Config and Services" motd_ssh customize