wger-project / docker

Production...ish docker-compose image for wger

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Docker Compose Trouble - Server app - Permission Denied ./static/django_extensions

Judman opened this issue · comments

commented

I am attempting to get the prod image running though docker compose. The driving issues is the webpage not loading after the stack starts. Going to the host IP I get redirected to 'hostIP/en/software/features'.

The error from the server logs:
PermissionError: [Errno 13] Permission denied: '/home/wger/static/django_extensions'

image

I really hope this is enough to get some troubleshooting started! Thanks for the project and the support.

Version:
Docker - 20.10.23
Compose - 2.15.1
OS - Debian GNU/Linux 11 (bullseye)

Server Logs

yarn install v1.22.19
[1/5] Validating package.json...
[2/5] Resolving packages...
[3/5] Fetching packages...
[4/5] Linking dependencies...
[5/5] Building fresh packages...
Done in 18.37s.
yarn run v1.22.19
$ sass wger/core/static/scss/main.scss:wger/core/static/yarn/bootstrap-compiled.css
Done in 8.84s.
Running in production mode, running collectstatic now
Traceback (most recent call last):
  File "/home/wger/src/manage.py", line 25, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 402, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 448, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.10/dist-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 209, in handle
    collected = self.collect()
  File "/usr/local/lib/python3.10/dist-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 135, in collect
    handler(path, prefixed_path, storage)
  File "/usr/local/lib/python3.10/dist-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 378, in copy_file
    self.storage.save(prefixed_path, source_file)
  File "/usr/local/lib/python3.10/dist-packages/django/core/files/storage.py", line 56, in save
    name = self._save(name, content)
  File "/usr/local/lib/python3.10/dist-packages/django/core/files/storage.py", line 295, in _save
    os.makedirs(directory, exist_ok=True)
  File "/usr/lib/python3.10/os.py", line 215, in makedirs
    makedirs(head, exist_ok=exist_ok)
  File "/usr/lib/python3.10/os.py", line 225, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/home/wger/static/django_extensions'
Performing database migrations
Operations to perform:
  Apply all migrations: actstream, auth, authtoken, axes, config, contenttypes, core, easy_thumbnails, exercises, gallery, gym, mailer, manager, measurements, nutrition, sessions, sites, weight
Running migrations:
  No migrations to apply.
  Your models in app(s): 'config' have changes that are not yet reflected in a migration, and so won't be applied.
  Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
Set site URL to http://localhost
Using gunicorn...
[2023-01-27 22:35:41 +0000] [89] [INFO] Starting gunicorn 20.1.0
[2023-01-27 22:35:41 +0000] [89] [INFO] Listening at: http://0.0.0.0:8000 (89)
[2023-01-27 22:35:41 +0000] [89] [INFO] Using worker: sync
[2023-01-27 22:35:41 +0000] [90] [INFO] Booting worker with pid: 90

nginx logs

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/01/27 22:34:59 [notice] 1#1: using the "epoll" event method
2023/01/27 22:34:59 [notice] 1#1: nginx/1.22.1
2023/01/27 22:34:59 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
2023/01/27 22:34:59 [notice] 1#1: OS: Linux 5.15.64-1-pve
2023/01/27 22:34:59 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 524288:524288
2023/01/27 22:34:59 [notice] 1#1: start worker processes
2023/01/27 22:34:59 [notice] 1#1: start worker process 28
2023/01/27 22:34:59 [notice] 1#1: start worker process 29
2023/01/27 22:34:59 [notice] 1#1: start worker process 30
2023/01/27 22:34:59 [notice] 1#1: start worker process 31
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET / HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /en/ HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /en/software/features HTTP/1.1" 500 2767 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
2023/01/27 22:40:28 [error] 29#29: *1 open() "/wger/static/css/workout-manager.css" failed (2: No such file or directory), client: 10.0.20.13, server: , request: "GET /static/css/workout-manager.css HTTP/1.1", host: "10.0.20.65", referrer: "http://10.0.20.65/en/software/features"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /static/css/workout-manager.css HTTP/1.1" 404 153 "http://10.0.20.65/en/software/features" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /static/yarn/bootstrap-compiled.css HTTP/1.1" 404 153 "http://10.0.20.65/en/software/features" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
2023/01/27 22:40:28 [error] 29#29: *1 open() "/wger/static/yarn/bootstrap-compiled.css" failed (2: No such file or directory), client: 10.0.20.13, server: , request: "GET /static/yarn/bootstrap-compiled.css HTTP/1.1", host: "10.0.20.65", referrer: "http://10.0.20.65/en/software/features"
2023/01/27 22:40:28 [error] 30#30: *5 open() "/wger/static/css/bootstrap-custom.css" failed (2: No such file or directory), client: 10.0.20.13, server: , request: "GET /static/css/bootstrap-custom.css HTTP/1.1", host: "10.0.20.65", referrer: "http://10.0.20.65/en/software/features"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /static/css/bootstrap-custom.css HTTP/1.1" 404 153 "http://10.0.20.65/en/software/features" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /static/yarn/shariff/dist/shariff.min.js HTTP/1.1" 404 153 "http://10.0.20.65/en/software/features" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
2023/01/27 22:40:28 [error] 30#30: *5 open() "/wger/static/yarn/shariff/dist/shariff.min.js" failed (2: No such file or directory), client: 10.0.20.13, server: , request: "GET /static/yarn/shariff/dist/shariff.min.js HTTP/1.1", host: "10.0.20.65", referrer: "http://10.0.20.65/en/software/features"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /static/images/logos/logo-bg-white.png HTTP/1.1" 404 153 "http://10.0.20.65/en/software/features" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
2023/01/27 22:40:28 [error] 30#30: *5 open() "/wger/static/images/logos/logo-bg-white.png" failed (2: No such file or directory), client: 10.0.20.13, server: , request: "GET /static/images/logos/logo-bg-white.png HTTP/1.1", host: "10.0.20.65", referrer: "http://10.0.20.65/en/software/features"
2023/01/27 22:40:28 [error] 29#29: *1 open() "/wger/static/images/favicon.png" failed (2: No such file or directory), client: 10.0.20.13, server: , request: "GET /static/images/favicon.png HTTP/1.1", host: "10.0.20.65", referrer: "http://10.0.20.65/en/software/features"
10.0.20.13 - - [27/Jan/2023:22:40:28 +0000] "GET /static/images/favicon.png HTTP/1.1" 404 153 "http://10.0.20.65/en/software/features" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"

db logs

PostgreSQL Database directory appears to contain a database; Skipping initialization

2023-01-27 22:34:47.292 UTC [1] LOG:  starting PostgreSQL 12.13 on x86_64-pc-linux-musl, compiled by gcc (Alpine 12.2.1_git20220924-r4) 12.2.1 20220924, 64-bit

2023-01-27 22:34:47.292 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432

2023-01-27 22:34:47.292 UTC [1] LOG:  listening on IPv6 address "::", port 5432

2023-01-27 22:34:47.296 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"

2023-01-27 22:34:47.330 UTC [21] LOG:  database system was shut down at 2023-01-27 22:22:36 UTC

2023-01-27 22:34:47.340 UTC [1] LOG:  database system is ready to accept connections

cache logs

1:C 27 Jan 2023 22:34:47.153 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 27 Jan 2023 22:34:47.153 # Redis version=7.0.8, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 27 Jan 2023 22:34:47.153 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 27 Jan 2023 22:34:47.155 * monotonic clock: POSIX clock_gettime
1:M 27 Jan 2023 22:34:47.157 * Running mode=standalone, port=6379.
1:M 27 Jan 2023 22:34:47.157 # Server initialized
1:M 27 Jan 2023 22:34:47.157 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 27 Jan 2023 22:34:47.158 * Ready to accept connections
1:M 27 Jan 2023 22:39:48.082 * 100 changes in 300 seconds. Saving...
1:M 27 Jan 2023 22:39:48.083 * Background saving started by pid 219
219:C 27 Jan 2023 22:39:48.089 * DB saved on disk
219:C 27 Jan 2023 22:39:48.090 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
1:M 27 Jan 2023 22:39:48.183 * Background saving terminated with success
1:M 27 Jan 2023 22:44:49.047 * 100 changes in 300 seconds. Saving...
1:M 27 Jan 2023 22:44:49.047 * Background saving started by pid 428
428:C 27 Jan 2023 22:44:49.055 * DB saved on disk
428:C 27 Jan 2023 22:44:49.056 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
1:M 27 Jan 2023 22:44:49.148 * Background saving terminated with success
1:M 27 Jan 2023 22:49:50.055 * 100 changes in 300 seconds. Saving...
1:M 27 Jan 2023 22:49:50.055 * Background saving started by pid 635
635:C 27 Jan 2023 22:49:50.069 * DB saved on disk
635:C 27 Jan 2023 22:49:50.070 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
1:M 27 Jan 2023 22:49:50.156 * Background saving terminated with success

docker-compose.yml

#
# Please consult the `Deployment` section in the readme if you want to deploy
# this. You need to keep this nginx service, even if you have your own, otherwise
# the static files will not be served correctly!
#

services:
  web:
    image: wger/server:latest
    container_name: wger_server
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_healthy
    env_file:
      - ./config/prod.env
    volumes:
      - ./static:/home/wger/static
      - ./media:/home/wger/media
      # For development, mount your local git checkout
      # - type: bind
      #  source: /path/to/wger/sourcecode
      #  target: /home/wger/src/
    ports:
      - "8000"
    healthcheck:
      test: wget --no-verbose --tries=1 --spider http://localhost:8000
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  nginx:
    image: nginx:stable
    container_name: wger_nginx
    depends_on:
      - web
    volumes:
      - ./config/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./static:/wger/static:ro
      - ./media:/wger/media:ro
    ports:
      - "80:80"
    healthcheck:
      test: service nginx status
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  db:
    image: postgres:12-alpine
    container_name: wger_db
    environment:
      - POSTGRES_USER=wger
      - POSTGRES_PASSWORD=wger
      - POSTGRES_DB=wger
    volumes:
      - ./postgres-data:/var/lib/postgresql/data/
    expose:
      - 5432
    healthcheck:
      test: pg_isready -U wger
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  cache:
    image: redis
    container_name: wger_cache
    expose:
      - 6379
    healthcheck:
      test: redis-cli ping
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  postgres-data:
  static:
  media:

networks:
  default:
    name: wger_network

nginx.conf

upstream wger {
    server web:8000;
}

server {

    listen 80;

    location / {
        proxy_pass http://wger;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_redirect off;
    }

    location /static/ {
        alias /wger/static/;
    }

    location /media/ {
        alias /wger/media/;
    }

    # Increase max body size to allow for video uploads
    client_max_body_size 100M;
}

prod.env

# Django's secret key, change to a 50 character random string if you are running
# this instance publicly. For an online generator, see e.g. https://djecrety.ir/
SECRET_KEY=**[censored]**

# Signing key used for JWT, use something different than the secret key
SIGNING_KEY=**[censored]**

# The 'from' address used when sending emails
FROM_EMAIL=**[censored]**

# The server's timezone, for a list of possible names:
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TIME_ZONE=**[censored]**


#
# Consult the deployment section in the readme if you are running this behind a
# reverse proxy with HTTPS enabled
#

# CSRF_TRUSTED_ORIGINS=https://my.domain.example.com,https://118.999.881.119
# X_FORWARDED_PROTO_HEADER_SET=True


#
# These settings usually don't need changing
#


#
# Application
ALLOW_REGISTRATION=True
ALLOW_GUEST_USERS=True
ALLOW_UPLOAD_VIDEOS=True
# Users won't be able to contribute to exercises if their account age is
# lower than this amount in days.
MIN_ACCOUNT_AGE_TO_TRUST=21
# Note that setting these to true will always perform a sync during startup,
# even if the data is already current and will take some time. Usually you don't
# need to perform these steps so often and a manual trigger (see README) is
# usually enough.
SYNC_EXERCISES_ON_STARTUP=False
DOWNLOAD_EXERCISE_IMAGES_ON_STARTUP=False


#
# Database
DJANGO_DB_ENGINE=django.db.backends.postgresql
DJANGO_DB_DATABASE=wger
DJANGO_DB_USER=wger
DJANGO_DB_PASSWORD=wger
DJANGO_DB_HOST=db
DJANGO_DB_PORT=5432
# Perform any new database migrations on startup
DJANGO_PERFORM_MIGRATIONS=True


#
# Cache
DJANGO_CACHE_BACKEND=django_redis.cache.RedisCache
DJANGO_CACHE_LOCATION=redis://cache:6379/1
# 60*60*24*15, 15 Days
DJANGO_CACHE_TIMEOUT=12
DJANGO_CACHE_CLIENT_CLASS=django_redis.client.DefaultClient

#
# Brute force login attacks
# https://django-axes.readthedocs.io/en/latest/index.html
AXES_ENABLED=True
AXES_FAILURE_LIMIT=10
# in minutes
AXES_COOLOFF_TIME=30
AXES_HANDLER=axes.handlers.cache.AxesCacheHandler

#
# Others
DJANGO_DEBUG=False
WGER_USE_GUNICORN=True
EXERCISE_CACHE_TTL=10
SITE_URL=http://localhost

#
# JWT auth
# The lifetime duration of the access token, in minutes
ACCESS_TOKEN_LIFETIME=10
# The lifetime duration of the refresh token, in hours
REFRESH_TOKEN_LIFETIME=24


#
# Other possible settings

# RECAPTCHA_PUBLIC_KEY
# RECAPTCHA_PRIVATE_KEY
# NOCAPTCHA

# https://docs.djangoproject.com/en/4.1/topics/email/#smtp-backend
# ENABLE_EMAIL
# EMAIL_HOST
# EMAIL_PORT
# EMAIL_HOST_USER
# EMAIL_HOST_PASSWORD
# EMAIL_USE_TLS
# EMAIL_USE_SSL

# DJANGO_MEDIA_ROOT
# DJANGO_STATIC_ROOT

commented

So I think I found my mistake in the docker compose file.

I am still new to docker and dangerous enough to break things when I think I can make them better. I changed the static and media volumes in web and nginx to start with a ./ thinking it would keep those files in my wger directory.

Turns out it breaks everything and causes the above issues. I went back, cleaned out the images and volumes then put in a clean compose file with no edits. After pulling new images the server grabbed all the static files and the site is running flawlessly.

Thanks a ton for this project! Hope this helps someone else.

Hi! These are the kind of issues I love to get, exemplary logs and when you want to reply, they are already solved 😄