beromir / Servas

A self-hosted bookmark management tool.
https://servas.app
GNU General Public License v3.0
562 stars 32 forks source link

Permission error when running `docker exec -it servas php artisan key:generate --force` #81

Closed ibrahimbayyinah closed 8 months ago

ibrahimbayyinah commented 9 months ago

When running docker exec -it servas php artisan key:generate --force I get the following error:

   ErrorException 

  file_put_contents(/var/www/html/.env): Failed to open stream: Permission denied

  at vendor/laravel/framework/src/Illuminate/Foundation/Console/KeyGenerateCommand.php:109
    105▕ 
    106▕             return false;
    107▕         }
    108▕ 
  ➜ 109▕         file_put_contents($this->laravel->environmentFilePath(), $replaced);
    110▕ 
    111▕         return true;
    112▕     }
    113▕ 

      +15 vendor frames 

  16  artisan:35
      Illuminate\Foundation\Console\Kernel::handle()

Steps to reproduce:

  1. Download docker-compose.prod.yaml and .env.prod.example into an empty directory.
  2. Rename to docker-compose.yaml and .env respectively.
  3. Make edits to .env (see contents of both files below).
  4. Run docker-compose up -d successfully. I get the following output:
    [+] Running 4/4
    ✔ Network servas_mariadb_default          Created                                                                       0.0s 
    ✔ Volume "servas_mariadb_servas-db-data"  Created                                                                       0.0s 
    ✔ Container servas_mariadb-db-1           Started                                                                       0.0s 
    ✔ Container servas                        Started                                                                       0.0s 
  5. Run docker exec -it servas php artisan key:generate --force, which gives the above mentioned error.

I tried with the SQLite container and got the same problem.

I also tried several approaches, like:

Unfortunately, nothing was able to solve the problem. Reading from the error, I assume it's a problem with the .env file not being writeable in the container, however I am not familiar enough with containers and PHP/Laravel to be able to solve it on my own. I'd love to use this bookmarks manager as it seems to be the only one I found which meets my needs (self-hosted + nested groups). Thanks in advance for your time to help me solve this.

.env content:

APP_NAME=Servas
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=http://localhost

SERVAS_ENABLE_REGISTRATION=true

# MySQL
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=servas_db
DB_USERNAME=servas_db_user
DB_PASSWORD=password

docker-compose.yaml (it's identical to the default):

version: "3"

services:
  db:
    image: mariadb:10.7.3
    restart: unless-stopped
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_bin
    environment:
      - MARIADB_ROOT_PASSWORD=${DB_PASSWORD}
      - MARIADB_USER=${DB_USERNAME}
      - MARIADB_PASSWORD=${DB_PASSWORD}
      - MARIADB_DATABASE=${DB_DATABASE}
    volumes:
      - servas-db-data:/var/lib/mysql

  servas:
    image: beromir/servas
    container_name: servas
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "8080:80"
    volumes:
      - ./.env:/var/www/html/.env

volumes:
  servas-db-data:

General info about my system:

ibrahimbayyinah commented 9 months ago

I managed to solve this (with the help of ChatGPT) by opening a shell inside the container and manually changing the ownership of the .env file (below I outline the steps for those who face the same problem and want a quick fix).

However, I wonder if this is the best solution. I am running it locally now, so there are no security concerns. But is this solution still good if I were to run it on a VPS? In other words: would it be a potential problem if the owner of the .env file is the web server user (www-data)?

Steps of the quick fix:

  1. Open shell inside the container: docker exec -it servas sh.
  2. For me, that opened a shell in /var/www/html/. The .env file is in that directory.
  3. Change ownership of that file to www-data (the web server user): chown www-data:www-data /var/www/html/.env.
  4. Exit the shell with the exit command.
  5. Run docker exec -it servas php artisan key:generate --force and follow the rest of the installation steps.
beromir commented 9 months ago

Thank you for the detailed bug report. I have tried to reproduce your described permission issue. However, it worked on my local machine. I cannot say what is the problem here, maybe it has something to do with how you installed Docker. Can you install Servas again? And after the first docker compose up -d, can you enter the container with docker exec -it servas bin/sh and check the owner and file permissions of the .env file?

ibrahimbayyinah commented 9 months ago

Hey beromir, thanks for your quick reply. I honestly thought I'd have to wait several days and I appreciate your willingness to help! I'm sorry if I'm late to reply, but I currently have exams, so I don't check github as often.

That said, it's owned by 1000:1000 and has read-write permissions for the owner and read for everyone else (see output below).

/var/www/html # ls -l .env
-rw-r--r--    1 1000     1000           348 Jan 21 08:29 .env

Also, minor point: I think you forgot the first slash in /bin/sh. For me, bin/sh didn't work. I had to use /bin/sh.

ghostbuster1002 commented 9 months ago

Faced the same issue! Permissions are exactly how Ibrahim describes for me too!

beromir commented 8 months ago

I was able to reproduce the error. The problem is the different file ownership on the host machine. To generate the application key, just run docker exec -it -u 1000 servas php artisan key:generate --force on the host. This step is required only once, so you should be fine after that.