11[variables ]
2+ # -- General Settings --#
23main_domain = " ${domain}"
4+ timezone = " Europe/Berlin"
5+ min_account_age_to_trust = " 21"
6+ download_ingredients_from = " WGER"
7+
8+ # -- Application Behavior --#
9+ allow_registration = " True"
10+ allow_guest_users = " True"
11+ allow_upload_videos = " True"
12+
13+ # -- Sync Settings (Celery) --#
14+ sync_exercises_celery = " True"
15+ sync_exercise_images_celery = " True"
16+ sync_exercise_videos_celery = " True"
17+ sync_ingredients_celery = " True"
18+
19+ # -- Celery --#
20+ use_celery = " True"
21+
22+ # -- Database Credentials (Auto-generated) --#
323postgres_user = " wger"
424postgres_password = " ${password:32}"
525postgres_db = " wger"
6- timezone = " Europe/Berlin"
7- django_secret_key = " ${password:64}"
8- redis_password = " ${password:32}"
26+
27+ # -- Security Keys (Auto-generated) --#
28+ secret_key = " ${password:64}"
29+ signing_key = " ${password:64}"
30+ flower_password = " ${password:16}"
31+
32+ # -- Email Settings (Optional) --#
33+ enable_email = " False"
34+ email_host = " smtp.gmail.com"
35+ email_port = " 587"
36+ email_host_user = " noreply@wger.de"
37+ email_host_password = " "
38+ email_use_tls = " True"
39+ from_email = " noreply@wger.de"
40+
41+ # -- Auth Proxy (Optional) --#
42+ auth_proxy_header = " "
43+ auth_proxy_trusted_ips = " "
44+ auth_proxy_create_unknown_user = " False"
45+ auth_proxy_user_email_header = " "
46+ auth_proxy_user_name_header = " "
947
1048[config ]
1149[[config .domains ]]
@@ -14,51 +52,195 @@ port = 80
1452host = " ${main_domain}"
1553
1654[config .env ]
17- POSTGRES_USER = " ${postgres_user}"
18- POSTGRES_PASSWORD = " ${postgres_password}"
19- POSTGRES_DB = " ${postgres_db}"
20- TIMEZONE = " ${timezone}"
55+ # Django's secret key, change to a 50 character random string if you are running
56+ # this instance publicly. For an online generator, see e.g. https://djecrety.ir/
57+ SECRET_KEY =" ${secret_key}"
2158
22- [[config .mounts ]]
23- filePath = " config/prod.env"
24- content = """
25- # Django configuration
26- DEBUG=False
27- SECRET_KEY=${django_secret_key}
28- ALLOWED_HOSTS=${main_domain},localhost,127.0.0.1
29- CSRF_TRUSTED_ORIGINS=https://${main_domain},http://${main_domain}
30-
31- # Database configuration
32- DATABASE_URL=postgresql://${postgres_user}:${postgres_password}@db:5432/${postgres_db}
33-
34- # Cache configuration
35- CACHE_URL=redis://cache:6379/1
36-
37- # Celery configuration
38- CELERY_BROKER_URL=redis://cache:6379/2
39- CELERY_RESULT_BACKEND=redis://cache:6379/3
40-
41- # Email configuration (optional - configure for password reset functionality)
42- # EMAIL_HOST=
43- # EMAIL_PORT=587
44- # EMAIL_HOST_USER=
45- # EMAIL_HOST_PASSWORD=
46- # EMAIL_USE_TLS=True
47- # FROM_EMAIL=noreply@${main_domain}
48-
49- # Media and static files
50- MEDIA_URL=/media/
51- STATIC_URL=/static/
52-
53- # Application settings
54- TIME_ZONE=${timezone}
55- LANGUAGE_CODE=en-us
56- USE_TZ=True
57-
58- # Security settings
59- SECURE_SSL_REDIRECT=False
60- SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,https
61- """
59+ # Signing key used for JWT, use something different than the secret key
60+ SIGNING_KEY =" ${signing_key}"
61+
62+ # The server's timezone, for a list of possible names:
63+ # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
64+ TIME_ZONE =" ${timezone}"
65+ TZ =" ${timezone}"
66+
67+ #
68+ # If you get CSRF errors set your domain here
69+ # Consult the docs for more details:
70+ # https://wger.readthedocs.io/en/latest/production/docker.html#if-you-get-csrf-errors
71+ # CSRF_TRUSTED_ORIGINS=https://my.domain.example.com,https://118.999.881.119
72+ # X_FORWARDED_PROTO_HEADER_SET=True
73+
74+ #
75+ # Static files
76+ # If you are running the application behind a reverse proxy or changed the port, the
77+ # links for some images *might* break (specially in the mobile app). Also note that
78+ # the API response is cached and contains the host, if you change this setting, just run
79+ # docker compose exec web python3 manage.py warmup-exercise-api-cache --force
80+ # MEDIA_URL=https://your-domain.example.com/media/
81+ # STATIC_URL=https://your-domain.example.com/static/
82+
83+ #
84+ # Application
85+ WGER_INSTANCE =" https://wger.de" # Wger instance from which to sync exercises, images, etc.
86+ ALLOW_REGISTRATION =" ${allow_registration}"
87+ ALLOW_GUEST_USERS =" ${allow_guest_users}"
88+ ALLOW_UPLOAD_VIDEOS =" ${allow_upload_videos}"
89+
90+ # Users won't be able to contribute to exercises if their account age is
91+ # lower than this amount in days.
92+ MIN_ACCOUNT_AGE_TO_TRUST =" ${min_account_age_to_trust}"
93+
94+ # Synchronzing exercises
95+ # It is recommended to keep the local database synchronized with the wger
96+ # instance specified in WGER_INSTANCE since there are new added or translations
97+ # improved. For this you have different possibilities:
98+ # - Sync exercises on startup:
99+ # SYNC_EXERCISES_ON_STARTUP=True
100+ # DOWNLOAD_EXERCISE_IMAGES_ON_STARTUP=True
101+ # - Sync them in the background with celery. This will setup a job that will run
102+ # once a week at a random time (this time is selected once when starting the server)
103+ SYNC_EXERCISES_CELERY =" ${sync_exercises_celery}"
104+ SYNC_EXERCISE_IMAGES_CELERY =" ${sync_exercise_images_celery}"
105+ SYNC_EXERCISE_VIDEOS_CELERY =" ${sync_exercise_videos_celery}"
106+ # - Manually trigger the process as needed:
107+ # docker compose exec web python3 manage.py sync-exercises
108+ # docker compose exec web python3 manage.py download-exercise-images
109+ # docker compose exec web python3 manage.py download-exercise-videos
110+
111+ # Synchronzing ingredients
112+ # You can also syncronize the ingredients from a remote wger instance, and have
113+ # basically the same options as for the ingredients:
114+ # - Sync them in the background with celery. This will setup a job that will run
115+ # once a week at a random time (this time is selected once when starting the server)
116+ SYNC_INGREDIENTS_CELERY =" ${sync_ingredients_celery}"
117+ # - Manually trigger the process as needed:
118+ # docker compose exec web python3 manage.py sync-ingredients
119+
120+ # This option controls whether to download ingredients and their images from the
121+ # configured wger instance. When scanning products with the barcode scanner, it is
122+ # possible to dynamically fetch the ingredient if it is not known in the local database.
123+ # Possible values: WGER or None. Requires USE_CELERY to be set to true.
124+ DOWNLOAD_INGREDIENTS_FROM =" ${download_ingredients_from}"
125+
126+ # Whether celery is configured and should be used. Can be left to true with
127+ # this setup but can be deactivated if you are using the app in some other way
128+ USE_CELERY =" ${use_celery}"
129+
130+ #
131+ # Celery
132+ CELERY_BROKER =" redis://cache:6379/2"
133+ CELERY_BACKEND =" redis://cache:6379/2"
134+ CELERY_FLOWER_PASSWORD =" ${flower_password}"
135+
136+ #
137+ # Database
138+ DJANGO_DB_ENGINE =" django.db.backends.postgresql"
139+ DJANGO_DB_DATABASE =" ${postgres_db}"
140+ DJANGO_DB_USER =" ${postgres_user}"
141+ DJANGO_DB_PASSWORD =" ${postgres_password}"
142+ DJANGO_DB_HOST =" db"
143+ DJANGO_DB_PORT =" 5432"
144+ DJANGO_PERFORM_MIGRATIONS =" True" # Perform any new database migrations on startup
145+
146+ #
147+ # Cache
148+ DJANGO_CACHE_BACKEND =" django_redis.cache.RedisCache"
149+ DJANGO_CACHE_LOCATION =" redis://cache:6379/1"
150+ DJANGO_CACHE_TIMEOUT =" 1296000" # in seconds - 60*60*24*15, 15 Days
151+ DJANGO_CACHE_CLIENT_CLASS =" django_redis.client.DefaultClient"
152+ # DJANGO_CACHE_CLIENT_PASSWORD=abcde... # Only if you changed the redis config
153+ # DJANGO_CACHE_CLIENT_SSL_KEYFILE=/path/to/ssl_keyfile # Path to an ssl private key.
154+ # DJANGO_CACHE_CLIENT_SSL_CERTFILE=/path/to/ssl_certfile # Path to an ssl certificate.
155+ # DJANGO_CACHE_CLIENT_SSL_CERT_REQS=<none | optional | required> # The string value for the verify_mode.
156+ # DJANGO_CACHE_CLIENT_SSL_CHECK_HOSTNAME=False # If set, match the hostname during the SSL handshake.
157+
158+ #
159+ # Brute force login attacks
160+ # https://django-axes.readthedocs.io/en/latest/index.html
161+ AXES_ENABLED =" True"
162+ AXES_FAILURE_LIMIT =" 10"
163+ AXES_COOLOFF_TIME =" 30" # in minutes
164+ AXES_HANDLER =" axes.handlers.cache.AxesCacheHandler"
165+ AXES_LOCKOUT_PARAMETERS =" ip_address"
166+ AXES_IPWARE_PROXY_COUNT =" 1"
167+ AXES_IPWARE_META_PRECEDENCE_ORDER =" HTTP_X_FORWARDED_FOR,REMOTE_ADDR"
168+
169+ #
170+ # Others
171+ DJANGO_DEBUG =" False"
172+ WGER_USE_GUNICORN =" True"
173+ EXERCISE_CACHE_TTL =" 18000" # in seconds - 5*60*60, 5 hours
174+ SITE_URL =" http://localhost"
175+
176+ #
177+ # JWT auth
178+ ACCESS_TOKEN_LIFETIME =" 10" # The lifetime duration of the access token, in minutes
179+ REFRESH_TOKEN_LIFETIME =" 24" # The lifetime duration of the refresh token, in hours
180+
181+ #
182+ # Auth Proxy Authentication
183+ #
184+ # Please read the documentation before enabling this feature:
185+ # https://wger.readthedocs.io/en/latest/administration/auth_proxy.html
186+ AUTH_PROXY_HEADER =" ${auth_proxy_header}"
187+ AUTH_PROXY_TRUSTED_IPS =" ${auth_proxy_trusted_ips}"
188+ AUTH_PROXY_CREATE_UNKNOWN_USER =" ${auth_proxy_create_unknown_user}"
189+ AUTH_PROXY_USER_EMAIL_HEADER =" ${auth_proxy_user_email_header}"
190+ AUTH_PROXY_USER_NAME_HEADER =" ${auth_proxy_user_name_header}"
191+
192+ #
193+ # Other possible settings
194+ # Log level: possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL
195+ LOG_LEVEL_PYTHON =" INFO"
196+
197+ # Recaptcha keys. You will need to create an account and register your domain
198+ # https://www.google.com/recaptcha/
199+ # RECAPTCHA_PUBLIC_KEY=abcde...
200+ # RECAPTCHA_PRIVATE_KEY=abcde...
201+ USE_RECAPTCHA =" False"
202+
203+ # Clears the static files before copying the new ones (i.e. just calls collectstatic
204+ # with the appropriate flag: "manage.py collectstatic --no-input --clear"). Usually
205+ # This can be left like this but if you have problems and new static files are not
206+ # being copied correctly, clearing everything might help
207+ DJANGO_CLEAR_STATIC_FIRST =" False"
208+
209+ #
210+ # Email
211+ # https://docs.djangoproject.com/en/4.1/topics/email/#smtp-backend
212+ ENABLE_EMAIL =" ${enable_email}"
213+ EMAIL_HOST =" ${email_host}"
214+ EMAIL_PORT =" ${email_port}"
215+ EMAIL_HOST_USER =" ${email_host_user}"
216+ EMAIL_HOST_PASSWORD =" ${email_host_password}"
217+ EMAIL_USE_TLS =" ${email_use_tls}"
218+ # EMAIL_USE_SSL=False
219+ FROM_EMAIL =" wger Workout Manager <${from_email}>"
220+
221+ # Set your name and email to be notified if an internal server error occurs.
222+ # Needs a working email configuration
223+ # DJANGO_ADMINS=your name,email@example.com
224+
225+ # Whether to compress css and js files into one (of each)
226+ # COMPRESS_ENABLED=True
227+
228+ #
229+ # Django Rest Framework
230+ # The number of proxies in front of the application. In the default configuration
231+ # only nginx is. Change as approtriate if your setup differs. Also note that this
232+ # is only used when throttling API requests.
233+ NUMBER_OF_PROXIES =" 1"
234+
235+ #
236+ # Gunicorn
237+ #
238+ # Additional gunicorn options, change as needed.
239+ # For the number of workers to spawn, a usually recommended value is (2 x $num_cores) + 1
240+ # see:
241+ # - https://docs.gunicorn.org/en/stable/settings.html
242+ # - https://github.com/wger-project/wger/blob/master/extras/docker/production/entrypoint.sh#L95
243+ GUNICORN_CMD_ARGS =" --workers 3 --threads 2 --worker-class gthread --proxy-protocol True --timeout 240"
62244
63245[[config .mounts ]]
64246filePath = " config/nginx.conf"
@@ -92,12 +274,6 @@ server {
92274 expires 7d;
93275 add_header Cache-Control "public";
94276 }
95-
96- # Security headers
97- add_header X-Frame-Options "SAMEORIGIN" always;
98- add_header X-Content-Type-Options "nosniff" always;
99- add_header X-XSS-Protection "1; mode=block" always;
100- add_header Referrer-Policy "strict-origin-when-cross-origin" always;
101277}
102278"""
103279
@@ -129,4 +305,5 @@ protected-mode no
129305
130306# Memory management
131307maxmemory-policy allkeys-lru
132- """
308+ """
309+
0 commit comments