Skip to content

Commit 30ecbb7

Browse files
committed
Merge branch 'feature/flexible-routines'
# Conflicts: # README.md # config/prod.env
2 parents c52d02e + 40bc5e9 commit 30ecbb7

File tree

3 files changed

+26
-358
lines changed

3 files changed

+26
-358
lines changed

README.md

Lines changed: 13 additions & 357 deletions
Original file line numberDiff line numberDiff line change
@@ -2,370 +2,26 @@
22

33

44
# docker compose stacks for wger
5-
65
Contains 3 docker compose environments:
76

87
* prod (in root of this repository)
98
* dev (uses sqlite)
109
* dev-postgres (uses postgresql)
1110

12-
## Introduction
13-
14-
The prod docker compose file starts up a production environment with gunicorn
15-
as the webserver, postgres as a database and redis for caching with nginx
16-
used as a reverse proxy.
17-
18-
The two develop environments don't use redis (caching), celery (jobs) or nginx.
19-
20-
The database, static files and uploaded images are mounted as volumes so
21-
the data is persisted. The only thing you need to do is update the docker
22-
images. Consult the docker volume command for details on how to access or
23-
backup this data.
24-
25-
It is recommended to regularly pull the latest version of the images from this
26-
repository, since sometimes new configurations or environmental variables are
27-
added.
28-
29-
# Production
30-
31-
### Configuration
32-
33-
Instead of editing the compose file or the env file directly, it is recommended
34-
to extend it. That way you can more easily pull changes from this repository.
35-
36-
For example, you might not want to run the application on port 80 because some
37-
other service in your network is already using it. For this, simply create a new
38-
file called `docker-compose.override.yml` with the following content:
39-
40-
```yml
41-
services:
42-
nginx:
43-
ports:
44-
- "8080:80"
45-
```
46-
47-
Now the port setting will be overwritten from the configured nginx service when
48-
you do a `docker compose up`. However, note that compose will concatenate both sets
49-
of values so in this case the application will be binded to 8080 (from the override)
50-
*and* 80 (from the regular compose file). It seems that at the moment the only
51-
workaround is remove the ports settings altogether from the compose file.
52-
53-
The same applies to the env variables, just create a new file called e.g. `my.env`
54-
and add it after the provided `prod.env` for the web service (again, this is
55-
`docker-compose.override.yml`). There you add the settings that you changed, and only
56-
those, which makes it easier to troubleshoot, etc.:
57-
58-
```yml
59-
web:
60-
env_file:
61-
- ./config/prod.env
62-
- ./config/my.env
63-
```
64-
65-
To add a web interface for the celery queue, add a new service to the override file:
66-
67-
```yml
68-
celery_flower:
69-
image: wger/server:latest
70-
container_name: wger_celery_flower
71-
command: /start-flower
72-
env_file:
73-
- ./config/prod.env
74-
ports:
75-
- "5555:5555"
76-
healthcheck:
77-
test: wget --no-verbose --tries=1 http://localhost:5555/healthcheck
78-
interval: 10s
79-
timeout: 5s
80-
retries: 5
81-
depends_on:
82-
celery_worker:
83-
condition: service_healthy
84-
```
85-
86-
For more information and possibilities consult <https://docs.docker.com/compose/extends/>
87-
88-
### 1 - Start
89-
90-
1. Cd into the environment of your choice.
91-
2. To start all services:
92-
93-
```sh
94-
docker compose up -d
95-
```
96-
97-
Optionally download current exercises, exercise images and the ingredients
98-
from wger.de. Please note that `load-online-fixtures` will overwrite any local
99-
changes you might have while `sync-ingredients` should be used afterward once
100-
you have imported the initial fixtures:
101-
102-
```sh
103-
docker compose exec web python3 manage.py sync-exercises
104-
docker compose exec web python3 manage.py download-exercise-images
105-
docker compose exec web python3 manage.py download-exercise-videos
106-
107-
# Loads a base set of ingredients
108-
docker compose exec web wger load-online-fixtures
109-
110-
# optionally run this afterwards to sync all the ingredients (around 1GB,
111-
# this process takes a loooong time):
112-
docker compose exec web python3 manage.py sync-ingredients-async
113-
```
114-
115-
(these steps are configured by default to run regularly in the background, but
116-
can also run on startup as well, see the options in `prod.env`.)
117-
118-
119-
Then open <http://localhost> (or your server's IP) and log in as: **admin**,
120-
password **adminadmin**
121-
122-
123-
### 2 - Update the application
124-
125-
Just remove the containers and pull the newest version:
126-
127-
```sh
128-
docker compose down
129-
docker compose pull
130-
docker compose up
131-
```
132-
133-
### 3 - Lifecycle Management
134-
135-
To stop all services issue a stop command, this will preserve all containers
136-
and volumes:
137-
138-
```sh
139-
docker compose stop
140-
```
141-
142-
To start everything up again:
143-
144-
```sh
145-
docker compose start
146-
```
147-
148-
To remove all containers (except for the volumes)
149-
150-
```sh
151-
docker compose down
152-
```
153-
154-
To view the logs:
155-
156-
```sh
157-
docker compose logs -f
158-
```
159-
160-
You might need to issue other commands or do other manual work in the container,
161-
e.g.
162-
163-
```sh
164-
docker compose exec web yarn install
165-
docker compose exec --user root web /bin/bash
166-
docker compose exec --user postgres db psql wger -U wger
167-
```
168-
169-
## Deployment
170-
171-
The easiest way to deploy this application to prod is to use a reverse proxy like
172-
nginx or traefik. You can change the port this application exposes and reverse proxy
173-
your domain to it. For this just edit the "nginx" service in docker-compose.yml and
174-
set the port to some value, e.g. `"8080:80"` then configure your proxy to forward
175-
requests to it, e.g. for nginx (no other ports need to be changed, they are used
176-
only within the application's docker network):
177-
178-
Also notice that the application currently needs to run on its own (sub)domain
179-
and not in a subdirectory, so `location /wger {` will probably only mostly work.
180-
181-
182-
```nginx
183-
upstream wger {
184-
server 123.456.789.0:8080;
185-
}
186-
187-
server {
188-
listen 80;
189-
listen [::]:443 ssl;
190-
listen 443 ssl;
191-
192-
location / {
193-
proxy_pass http://wger;
194-
proxy_set_header Host $http_host;
195-
proxy_set_header X-Real-IP $remote_addr;
196-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
197-
proxy_set_header X-Forwarded-Proto $scheme;
198-
proxy_redirect off;
199-
}
200-
201-
server_name my.domain.example.com;
202-
203-
ssl_certificate /path/to/https/certificate.crt;
204-
ssl_certificate_key /path/to/https/certificate.key;
205-
}
206-
```
207-
208-
### If you get CSRF errors
209-
210-
If you want to use HTTPS like in the example config you need to add some
211-
additional configurations. Since the HTTPS connections are reversed proxied,
212-
the secure connection terminates there, the application will receive a regular
213-
HTTP request and django's [CSRF protection](https://docs.djangoproject.com/en/4.1/ref/csrf/)
214-
will kick in.
215-
216-
To solve this, update the env file and either
217-
218-
* manually set a list of your domain names and/or server IPs
219-
`CSRF_TRUSTED_ORIGINS=https://my.domain.example.com,https://118.999.881.119:8008`
220-
If you are unsure what origin to add here, set the debug setting to true, restart
221-
and try again, the error message that appears will have the origin prominently
222-
displayed. Note: the port is important!
223-
* or set the `X-Forwarded-Proto` header like in the example and set
224-
`X_FORWARDED_PROTO_HEADER_SET=True`. If you do this consult the
225-
[documentation](https://docs.djangoproject.com/en/4.1/ref/settings/#secure-proxy-ssl-header)
226-
as there are some security considerations.
227-
228-
You might want to set `DJANGO_DEBUG` to true while you are debugging this is you
229-
encounter errors.
230-
231-
232-
### Automatically start service
233-
234-
If everything works correctly, you will want to start the compose file as a
235-
service so that it auto restarts when you reboot the server. If you use systemd,
236-
this can be done with a simple file. Create the file `/etc/systemd/system/wger.service`
237-
and enter the following content (check where the absolute path of the docker
238-
command is with `which docker`)
239-
240-
```ini
241-
[Unit]
242-
Description=wger docker compose service
243-
PartOf=docker.service
244-
After=docker.service
245-
246-
[Service]
247-
Type=oneshot
248-
RemainAfterExit=true
249-
WorkingDirectory=/path/to/the/docker/compose/
250-
ExecStart=/usr/bin/docker compose up -d --remove-orphans
251-
ExecStop=/usr/bin/docker compose down
252-
253-
[Install]
254-
WantedBy=multi-user.target
255-
```
256-
257-
Read the file with `systemctl daemon-reload` and start it with
258-
`systemctl start wger`. If there are no errors and `systemctl status wger`
259-
shows that the service is active (this might take some time), everything went
260-
well. With `systemctl enable wger` the service will be automatically restarted
261-
after a reboot.
262-
263-
### Backup
264-
265-
**Database volume:** The most important thing to backup. For this just make
266-
a dump and restore it when needed
267-
268-
```sh
269-
# Stop all other containers so the db is not changed while you export it
270-
docker compose stop web nginx cache celery_worker celery_beat
271-
docker compose exec db pg_dumpall --clean --username wger > backup.sql
272-
docker compose start
273-
274-
# When you need to restore it
275-
docker compose stop
276-
docker volume remove docker_postgres-data
277-
docker compose up db
278-
cat backup.sql | docker compose exec -T db psql --username wger --dbname wger
279-
docker compose up
280-
```
281-
282-
**Media volume:** If you haven't uploaded any own images (exercises, gallery),
283-
you don't need to backup this, the contents can just be downloaded again. If
284-
you have, please consult these possibilities:
285-
286-
* <https://www.docker.com/blog/back-up-and-share-docker-volumes-with-this-extension/>
287-
* <https://github.com/BretFisher/docker-vackup>
288-
289-
290-
**Static volume:** The contents of this volume are 100% generated and recreated
291-
on startup, no need to backup anything
292-
293-
### Postgres Upgrade
294-
295-
It is sadly not possible to automatically upgrade between postgres versions,
296-
you need to perform the upgrade manually. Since the amount of data the app
297-
generates is small a simple dump and restore is the simplest way to do this.
298-
299-
If you pulled new changes from this repo and got the error message "The data
300-
directory was initialized by PostgreSQL version 12, which is not compatible
301-
with this version 15." this is for you.
302-
303-
See also <https://github.com/docker-library/postgres/issues/37>
304-
305-
306-
```bash
307-
# Checkout the last version of the composer file that uses postgres 12
308-
git checkout pg-12
309-
310-
# Stop all other containers
311-
docker compose stop web nginx cache celery_worker celery_beat
312-
313-
# Make a dump of the database and remove the container and volume
314-
docker compose exec db pg_dumpall --clean --username wger > backup.sql
315-
docker compose stop db
316-
docker compose down
317-
docker volume remove docker_postgres-data
318-
319-
# Checkout current version, import the dump and start everything
320-
git checkout master
321-
docker compose up db
322-
cat backup.sql | docker compose exec -T db psql --username wger --dbname wger
323-
docker compose exec -T db psql --username wger --dbname wger -c "ALTER USER wger WITH PASSWORD 'wger'"
324-
docker compose up
325-
rm backup.sql
326-
```
327-
328-
## Building
329-
330-
If you want to build the images yourself, clone the wger repository and follow
331-
the instructions for the devel image in the `extras/docker` folder.
332-
333-
# Development environments
334-
335-
Note: the docker images assume a wger user id of 1000. Since we mount the code
336-
and write from the image into your code repository, you may run into permission errors
337-
if your user id is not 1000. We don't have a good solution for such situation yet.
338-
Check your user id with `echo $UID`.
339-
340-
1. Clone https://github.com/wger-project/wger to a folder of your choice.
341-
2. `cd` into the environment of your choice (dev or dev-postgres)
342-
3. Copy `.env.example` to `.env` and set the path to correspond to the location where
343-
you have checked out the wger server git repo.
344-
345-
346-
```shell
347-
docker compose up
348-
docker compose exec web /bin/bash
349-
cp extras/docker/production/settings.py .
350-
351-
wger bootstrap # this creates initial db tables, runs yarn install, yarn build:css:sass, etc
352-
python3 manage.py migrate # safe to ignore: Your models in app(s): 'exercises', 'nutrition' have changes that are not yet reflected in a migration, and so won't be applied.
353-
python3 manage.py sync-exercises # pull exercises from wger.de (or other source you have defined)
354-
wger load-online-fixtures # pull nutrition information
11+
The production Docker Compose file initializes a production environment with the
12+
application server, a reverse proxy, a database, a caching server, and a Celery
13+
queue, all configured. Data is persisted in volumes, if you want to use folders,
14+
read the warning in the env file.
35515

356-
# if you use sqlite, at this time you can make a backup if you want
357-
# such that if you mess something up, you don't have to start from scratch
358-
cp /home/wger/db/database.sqlite /home/wger/db/database.sqlite.orig
16+
**TLDR:** just do `docker compose up -d`
35917

360-
# finally, this is important, start the actual server!
361-
python3 manage.py runserver 0.0.0.0:8000
362-
```
18+
For more details, consult the documentation (and the config files):
36319

364-
You can now login on http://localhost:8000 - there is one user account: admin, with password adminadmin
365-
The server should restart automatically when you change code, etc.
20+
* production: <https://wger.readthedocs.io/en/latest/production/docker.html>
21+
* development: <https://wger.readthedocs.io/en/latest/development/docker.html>
36622

367-
If you use `dev` you can use the `sqlite3` program to execute queries against the database file.
368-
For `postgres-sqlite` you can use `pgcli -h localhost -p 5432 -u wger` on your host, with password `wger`
23+
It is recommended to regularly pull the latest version of the compose file,
24+
since sometimes new configurations or environmental variables are added.
36925

37026
## Contact
37127

@@ -374,9 +30,9 @@ didn't behave as you expected. We can't fix what we don't know about, so please
37430
report liberally. If you're not sure if something is a bug or not, feel free to
37531
file a bug anyway.
37632

377-
* discord: <https://discord.gg/rPWFv6W>
378-
* issue tracker: <https://github.com/wger-project/docker/issues>
379-
* twitter: <https://twitter.com/wger_project>
33+
* Mastodon: <https://fosstodon.org/@wger>
34+
* Discord: <https://discord.gg/rPWFv6W>
35+
* Issue tracker: <https://github.com/wger-project/docker/issues>
38036

38137

38238
## Sources

0 commit comments

Comments
 (0)