Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After the recent Docker image update, maildev/maildev fails with error 'EACCES: permission denied 0.0.0.0:80' #402

Closed
adoprog opened this issue Apr 1, 2022 · 8 comments

Comments

@adoprog
Copy link

adoprog commented Apr 1, 2022

MailDev using directory /tmp/maildev-1
MailDev webapp running at http://0.0.0.0:80
node:events:504
      throw er; // Unhandled 'error' event
      ^
Error: listen EACCES: permission denied 0.0.0.0:80
    at Server.setupListenHandle [as _listen2] (node:net:1313:21)
    at listenInCluster (node:net:1378:12)
    at doListen (node:net:1516:7)
    at processTicksAndRejections (node:internal/process/task_queues:84:21)
Emitted 'error' event on Server instance at:
    at emitErrorNT (node:net:1357:8)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  code: 'EACCES',
  errno: -13,
  syscall: 'listen',
  address: '0.0.0.0',
  port: 80
}

Does it require extra permissions or configuration?

@timotheeg
Copy link

The internal ports for the new docker images are 1025 for the smtp server and 1080 for the web interface (ports were 25 and 80 previously)

The documentation is confusing now, listing a mixture of both old and new ports, so I don't know if the change of ports was intended.

It's easily fixable by updating config to use the new ports, or pinning your docker image to the older stable 1.1.0

@djfarrelly
Copy link
Member

Hey @adoprog. @timotheeg is 100% correct that the default ports changed so Maildev did not need to be run on secure ports. This port change was originally slated to be a 2.0 change as it was breaking, but it slipped in. 1.1.1 as well - I'm sorry about that!

You can use @timotheeg's suggested solution of pinning to the 1.1.0 image version or changing your port mapping to match the newer ports. I would always recommend pinning to a specific Docker image version anyway instead of using latest, so here's what it would look like:

docker run -p 1080:1080 -p 1025:1025 maildev/maildev:2.0.2

Otherwise, If you want to use port 80 and maildev 2.x, you can pass an environment variable to your container and set the port to whatever you want, e.g. MAILDEV_WEB_PORT=80 (the default is 1080).

I hope this helps. This issue will be closed when the updated documentation PR (#406) is merged.

@loranger
Copy link

I'm afraid passing environment variable does not work, maildev still uses the default ports.

I'm using the latest maildev image

cat docker-compose.yaml
...

  maildev:
    image: maildev/maildev:latest
    container_name: ${APP_PROJECT}-maildev
    environment:
      - TZ=Europe/Paris
      - MAILDEV_WEB_PORT=80
      - MAILDEV_SMTP_PORT=25
    labels:
      - "traefik.http.routers.maildev-${APP_PROJECT}.rule=Host(`maildev.${APP_DOMAIN}`)"
      - "traefik.http.services.maildev-${APP_PROJECT}-service.loadbalancer.server.port=80"
      - "com.centurylinklabs.watchtower.enable=true"
      - "diun.enable=true"

...
docker-compose pull maildev
[+] Running 1/1
 ⠿ maildev Pulled
docker-compose up -d
[+] Running 8/8
 ⠿ Container myproject-mysql     Started                                                                                                                                                                                                                0.7s
 ⠿ Container myproject-npm       Started                                                                                                                                                                                                                1.6s
 ⠿ Container myproject-composer  Started                                                                                                                                                                                                                0.8s
 ⠿ Container myproject-adminer   Started                                                                                                                                                                                                                1.6s
 ⠿ Container myproject-maildev   Started                                                                                                                                                                                                                0.7s
 ⠿ Container myproject-php-fpm   Started                                                                                                                                                                                                                1.6s
 ⠿ Container myproject-artisan   Started                                                                                                                                                                                                                1.2s
 ⠿ Container myproject-apache    Started
docker-compose logs maildev
myproject-maildev  | MailDev using directory /tmp/maildev-1
myproject-maildev  | MailDev webapp running at http://0.0.0.0:80
myproject-maildev  | MailDev SMTP Server running at 0.0.0.0:25
docker inspect myproject-maildev --format='{{range $p, $conf := .Config.ExposedPorts}} {{$p}} {{end}}'
 1025/tcp  1080/tcp

@djfarrelly
Copy link
Member

@loranger, it looks like you are correctly setting the ports for Maildev to run on within the container to 80 and 25 respectively, but that's different from the ports that are being exposed on the host machine (e.g. your laptop) - see ExposedPorts.

You will need to expose these ports explicitly via expose or ports. Only 1025 and 1080 are exposed by default (source code).

To expose maildev these ports to the other containers in your compose setup (reference: Compose docs)

  maildev:
    image: maildev/maildev:2.0.5 # I strongly recommend using a particular version over "latest"
    container_name: ${APP_PROJECT}-maildev
    environment:
      - TZ=Europe/Paris
      - MAILDEV_WEB_PORT=80
      - MAILDEV_SMTP_PORT=25
    expose:
      - "80" # This will expose port 80 on your host machine to port 80 in the container
      - "25"

Alternatively, you may want to just keep running maildev on it's default port and map them to different ports for other linked containers (see Compose docs link above). If you want to do that you can do this:

  maildev:
    image: maildev/maildev:2.0.5 # I strongly recommend using a particular version over "latest"
    container_name: ${APP_PROJECT}-maildev
    environment:
      - TZ=Europe/Paris
    ports:
      - "80:1080" # This will map and expose port 80 on your host machine to port 1080 in the container
      - "25:1025"

Beyond exposing and mapping ports, it will likely get into specifics of your project's setup and your traefik or apache configuration.

@loranger
Copy link

loranger commented Jun 22, 2022

Thanks @djfarrelly for your support.
Whereas your answer seems logic and obvious, I still struggle to make it work, even with a downsized project :

.env
APP_PROJECT=struggling
APP_DOMAIN=attempt.docker
docker-compose.yml
version: '3'

services:

  nginx:
    container_name: ${APP_PROJECT}-nginx
    image: nginx:stable-alpine
    env_file:
      - .env
    labels:
      - "traefik.http.routers.${APP_PROJECT}.rule=Host(`${APP_DOMAIN}`)"
      - "traefik.http.services.${APP_PROJECT}-service.loadbalancer.server.port=80"

  maildev:
    image: maildev/maildev:2.0.5
    container_name: ${APP_PROJECT}-maildev
    environment:
      - MAILDEV_WEB_PORT=2080
      - MAILDEV_SMTP_PORT=2025
    expose:
      - "2080"
      - "2025"
    labels:
      - "traefik.http.routers.${APP_PROJECT}-maildev.rule=Host(`maildev.${APP_DOMAIN}`)"
      - "traefik.http.services.${APP_PROJECT}-maildev-service.loadbalancer.server.port=2080"

  adminer:
    container_name: ${APP_PROJECT}-adminer
    image: adminer:latest
    labels:
      - "traefik.http.routers.${APP_PROJECT}-adminer.rule=Host(`adminer.${APP_DOMAIN}`)"
      - "traefik.http.services.${APP_PROJECT}-adminer-service.loadbalancer.server.port=8080"

networks:
  default:
      name: web

As you understood, I use traefik as reverse proxy and does not map ports in order to avoid conflicts with other opened ports. I use a traefik based network web in order to expose services.
I also have a dns rewrite rule redirecting *.docker to 127.0.0.1
So everything should be running flawlesly, but it's not.

When I start the container, I ain't got no error

docker-compose up
[+] Running 3/3
 ⠿ Container struggling-nginx    Created                                   0.0s
 ⠿ Container struggling-adminer  Recreat...                                0.1s
 ⠿ Container struggling-maildev  Recreat...                                0.1s
Attaching to struggling-adminer, struggling-maildev, struggling-nginx
struggling-adminer  | [Wed Jun 22 16:51:02 2022] PHP 7.4.30 Development Server (http://[::]:8080) started
struggling-nginx    | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
struggling-nginx    | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
struggling-nginx    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
struggling-nginx    | 10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled
struggling-nginx    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
struggling-nginx    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
struggling-nginx    | /docker-entrypoint.sh: Configuration complete; ready for start up
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: using the "epoll" event method
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: nginx/1.22.0
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: built by gcc 11.2.1 20220219 (Alpine 11.2.1_git20220219)
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: OS: Linux 5.10.104-linuxkit
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: start worker processes
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: start worker process 24
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: start worker process 25
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: start worker process 26
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: start worker process 27
struggling-nginx    | 2022/06/22 16:51:02 [notice] 1#1: start worker process 28
struggling-maildev  | MailDev using directory /tmp/maildev-1
struggling-maildev  | MailDev webapp running at http://0.0.0.0:2080
struggling-maildev  | MailDev SMTP Server running at 0.0.0.0:2025

but maildev does not respond

❯ curl -I attempt.docker
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 615
Content-Type: text/html
Date: Wed, 22 Jun 2022 16:57:10 GMT
Etag: "628dfe65-267"
Last-Modified: Wed, 25 May 2022 10:01:09 GMT
Server: nginx/1.22.0

❯ curl -I maildev.attempt.docker
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Wed, 22 Jun 2022 16:57:12 GMT
Content-Length: 19

❯ curl -I adminer.attempt.docker
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-Nzk5YzQ5MjRkN2Y4MjI3MDZkZGJhMzJlZTdlZDI4MmU=' 'strict-dynamic'; connect-src 'self'; frame-src https://www.adminer.org; object-src 'none'; base-uri 'none'; form-action 'self'
Content-Type: text/html; charset=utf-8
Date: Wed, 22 Jun 2022 16:57:16 GMT
Host: adminer.attempt.docker
Referrer-Policy: origin-when-cross-origin
Set-Cookie: adminer_sid=fbbe6728e37871b3626c15c00565a924; path=/; HttpOnly
Set-Cookie: adminer_key=bd5872fe326eae13bb6bd1169bfa5326; path=/; HttpOnly; SameSite=lax
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-Powered-By: PHP/7.4.30
X-Xss-Protection: 0

The 404 error code is returned by traefik which cannot route anywhere, and I have to admit I can't see no running maildev router in traefik (I surrounded maildev with nginx and adminer in order to test I don't know… service parsing or something)

Capture d’écran 2022-06-22 à 18 59 12

For some reason, the maildev service seems to never being up and running and thus never being reachable… At least with different ports than its defaults. As soon as I fall back to the default value, everything is fine

  maildev:
    image: maildev/maildev:2.0.5
    container_name: ${APP_PROJECT}-maildev
    environment:
      - MAILDEV_WEB_PORT=1080
      - MAILDEV_SMTP_PORT=1025
    labels:
      - "traefik.http.routers.${APP_PROJECT}-maildev.rule=Host(`maildev.${APP_DOMAIN}`)"
      - "traefik.http.services.${APP_PROJECT}-maildev-service.loadbalancer.server.port=1080"
❯ curl -I maildev.attempt.docker
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Content-Length: 8390
Content-Type: text/html; charset=UTF-8
Date: Wed, 22 Jun 2022 17:18:04 GMT
Etag: W/"20c6-17fd74fedb0"
Last-Modified: Tue, 29 Mar 2022 20:13:34 GMT
X-Powered-By: Express

Capture d’écran 2022-06-22 à 19 19 07

If you ever have a clue for me, I would be really grateful
(If you want me to open a new issue instead of polluating this one, just tell me)

@loranger
Copy link

I notice there was a little delay between the availability (and appearance in traefik dashboard) of the other services and maildev.
Could the healthcheck create this delay and forbid maildev image with a different port to be up and available ?

@loranger
Copy link

@djfarrelly I did test again and can confirm the issue comes from the healthcheck.
There is a (dead simple) pending pull request #409 resolving this bug.

@loranger
Copy link

loranger commented Jul 5, 2022

@djfarrelly There is a few PR trying to resolve this healthcheck issue: #419, #409 , #407
Could you please take a moment in order to review them and unblock us ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants