invoiceninja / dockerfiles

Docker files for Invoice Ninja
https://hub.docker.com/r/invoiceninja/invoiceninja
GNU General Public License v2.0
392 stars 255 forks source link

Connection reset by peer- docker-compose with external webserver #205

Closed maxiride closed 3 years ago

maxiride commented 3 years ago

I've tried to deploy invoiceninja 5 using the suggested docker-compose with a slight modification since I already have a Caddy container running. After deploying the invoice ninja stack I joined the "app" to the caddy docker network for proper DNS resolution however I am getting a connection reset either when accessing the docker host IP:765 and when trying to access it from the external TLD.

docker-compose

version: '3.7'

services:
  app:
    image: invoiceninja/invoiceninja:5
    restart: always
    ports:
      - '765:9000'
    cap_add:
      - SYS_ADMIN
    environment:
      - APP_DEBUG=1
      - APP_URL=snip
      - APP_KEY=snip
      - MULTI_DB_ENABLED=false
      - DB_HOST1=db
    volumes:
      -  public:/var/www/app/public
      -  storage:/var/www/app/storage
    depends_on:
      - db
    networks:
      - net

  db:
    image: mysql:5
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=ninjaAdm1nPassword
      - MYSQL_USER=ninja
      - MYSQL_PASSWORD=ninja
      - MYSQL_DATABASE=ninja
    volumes:
      - mysql-data:/var/lib/mysql:rw
    networks:
      - net

volumes:
  mysql-data:
  public:
  storage:

networks:
  net:
ubuntu@docker:~$

Caddyfile:

TLD {
        reverse_proxy invoiceninja5_app_1:9000
}

Invoice Ninja logs (notice that no incoming connection is shown, should at least log it?):

Configuration cache cleared!,
Configuration cached successfully!,
Configuration cache cleared!,
Configuration cached successfully!,
Route cache cleared!,
Routes cached successfully!,
les cached successfully!,
[23-Oct-2020 09:57:10] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root,
[23-Oct-2020 09:57:10] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root,
[23-Oct-2020 09:57:10] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root,
[23-Oct-2020 09:57:10] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root,
[23-Oct-2020 09:57:10] NOTICE: fpm is running, pid 1,
[23-Oct-2020 09:57:10] NOTICE: ready to handle connections,

Caddy logs:

{"remote_addr":"snip snip","proto":"HTTP/2.0","method":"GET","host":"snip snip TLD","uri":"/favicon.ico","headers":{"Accept":["image/webp,*/*"],"Accept-Language":["it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3"],"Accept-Encoding":["gzip, deflate, br"],"Dnt":["1"],"Referer":["snip snip"],"Sec-Gpc":["1"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","proto_mutual":true,"server_name":"snip snip"}},"duration":0.001858917,"status":502,"err_id":"91vjvzwht","err_trace":"reverseproxy.(*Handler).ServeHTTP (reverseproxy.go:441)"},

Just as a test I also tried to deploy the stack "as is" using the default docker-compose file, adding only the generated app key with the same results.

LivingWithHippos commented 3 years ago

I have the same issue but with nginx. I noticed that when mounting volumes to a local folder, storage and public remained empty, but even removing all the volume directives nothing happens. I also get 502 in the logs

turbo124 commented 3 years ago

I found that I also needed to add these env vars to the environment: to get the app working

      - DB_USERNAME1=ninja
      - DB_PASSWORD1=ninja
      - DB_DATABASE1=ninja

also storage linking resolved issues with PDFs

docker-compose exec app php artisan storage:link
LivingWithHippos commented 3 years ago

I do have those set but it's still not working. This is my docker-compose.yml:

version: '3.7'

services:
  app:
    image: invoiceninja/invoiceninja:5.0.17
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    environment:
      - APP_URL=${APP_URL}
      - APP_KEY=${APP_KEY}
      - MULTI_DB_ENABLED=false
      - DB_HOST1=db
      - DB_USERNAME1=${DB_USER}
      - DB_PASSWORD1=${DB_PASSWORD}
      - DB_DATABASE1=ninja
    depends_on:
      - db
    ports:
      - 6788:9000
      - 6789:80
    networks:
      - letsencrypt_default
      - backend

  db:
    image: mysql:5
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - MYSQL_DATABASE=ninja
    networks:
      - backend

networks:
  letsencrypt_default:
    external: true
  backend:
    name: ninja_backend
    driver: bridge

This version has no data mounted to avoid permission issues. Parameters are loaded from a .env file, networks are for reverse proxy even if here I am mapping ports directly, to check if the issue lied with nginx

dokime7 commented 3 years ago

Hi, Have you found a solution? I've the same issue :-(

maxiride commented 3 years ago

Hi, Have you found a solution? I've the same issue :-(

I don't know if it is a solution or a workaround but I set the env variable "TRUSTED_PROXYES=*"

dokime7 commented 3 years ago

No changes with TRUSTED_PROXYES... php-fpm seems to deny connections even inside container :

$ docker-compose exec app sh
~ $ 
~ $ curl http://localhost:9000
curl: (56) Recv failure: Connection reset by peer
LivingWithHippos commented 3 years ago

The problem is that invoiceninja is a php application that has different needs from a classic docker application. We need to adapt the reverse proxy configuration for that, just following the configuration already present in this repo should be enough. In the first post for example the Caddyfile is

TLD {
        reverse_proxy invoiceninja5_app_1:9000
}

which is not going to work.

HOW DO APPS LIKE THIS WORK

Supposing everything is in docker

  1. You need a reverse proxy container (either your own or one like caddy in this docker, I don't think it's optional because it has to serve the app) and a container with php (in this case it's invoiceninja/invoiceninja)

  2. The app folder must be mounted in the same path for both containers (see in the original dockerfile public:/var/www/app/public it's the same for caddy and invoiceninja) otherwise there will be issues with paths. If you're using your own reverse proxy in a different compose file you can import the same public container like this:

    services:
    caddy:
    image: caddy:2
    ...
    volumes:
      - invoiceninja_public:/var/www/app/public
    volumes:
    invoiceninja_public:
    external: true

    Mapping to a folder is not going to work, use a volume, it could probably be fixed updating how the original Dockerfile works. Use docker volume ls to get the complete volume name.

  3. The reverse proxy must be configured to serve it as a php app and not directly; for caddy this means

{$APP_URL} {
    root * /var/www/app/public
    php_fastcgi container_name:9000
    encode zstd gzip
    file_server browse
}

as shown in the config folder. Nginx is the same. Nginx proxy manager can't do this if I'm not wrong but you should be able to manually edit the conf file.

SO NOW DOES IT WORK?

No, it still does not, I get a 500 server error, but it's served by the app and the invoiceninja favicon is correctly loaded. I'd need more logs but the containers are not cooperating (php.ini is write protected)

EDIT: it does work, thanks to this stackoverflow answer -> go to your app url/setup to complete the setup

php-fpm seems to deny connections even inside container

apparently curl works only with http/s so it will always return curl: (56) Recv failure: Connection reset by peer against a php executable

TL:DR -> your reverse proxy config is wrong, and after fixing it, the first time you need to go to https://invoiceninja_url/setup

dokime7 commented 3 years ago

Hi, I finaly found where is the problem. On my server, docker dns doesn't resolve the good IP for the 'app' container, it seems that there is a conflict on 'app' container name, so I have renaming the 'app' container to 'ninja' in docker-compose.yml like:

version: '3.7'

services:
  ninja:
    image: invoiceninja/invoiceninja:5.0.17
    restart: unless-stopped
    ....