diff --git a/install/wger-install.sh b/install/wger-install.sh index 0e8e9ace7..cb220d4b0 100644 --- a/install/wger-install.sh +++ b/install/wger-install.sh @@ -15,8 +15,9 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y \ - apache2 \ - libapache2-mod-wsgi-py3 \ + build-essential \ + nginx \ + redis-server \ libpq-dev msg_ok "Installed Dependencies" @@ -28,93 +29,184 @@ PG_DB_NAME="wger" PG_DB_USER="wger" setup_postgresql_db fetch_and_deploy_gh_release "wger" "wger-project/wger" "tarball" "latest" "/opt/wger" +WG_IP="$(hostname -I | awk '{print $1}')" +WG_PORT="3000" +WG_URL="http://${WG_IP}:${WG_PORT}" + msg_info "Setting up wger" mkdir -p /opt/wger/{static,media} chmod o+w /opt/wger/media cd /opt/wger + $STD corepack enable $STD npm install $STD npm run build:css:sass + $STD uv venv $STD uv pip install . +$STD uv pip install gunicorn celery django-redis psycopg2-binary + 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=${WG_IP},localhost,127.0.0.1 +CSRF_TRUSTED_ORIGINS=${WG_URL} + +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=${WG_URL} 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/apache2/sites-available/wger.conf - - - Require all granted - - +msg_ok "wger configured" - - WSGIApplicationGroup %{GLOBAL} - WSGIDaemonProcess wger python-path=/opt/wger python-home=/opt/wger/.venv - WSGIProcessGroup wger - WSGIScriptAlias / /opt/wger/wsgi_wrapper.py - WSGIPassAuthorization On +msg_info "Creating Gunicorn service" +cat </etc/systemd/system/wger.service +[Unit] +Description=wger Gunicorn +After=network.target - Alias /static/ /opt/wger/static/ - - 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 - 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" +msg_ok "Gunicorn service created" + +msg_info "Creating Celery worker 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 +msg_ok "Celery worker service created" + +msg_info "Creating Celery beat service" +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 +msg_ok "Celery beat service created" + +msg_info "Configuring Nginx" + 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 + +msg_ok "Nginx configured" + +systemctl daemon-reexec +systemctl daemon-reload +systemctl enable --now redis-server nginx wger celery celery-beat + +$STD rm -f /etc/nginx/sites-enabled/default +$STD ln -sf /etc/nginx/sites-available/wger /etc/nginx/sites-enabled/wger + +systemctl restart nginx motd_ssh customize