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

Cron jobs don't work, either can modify files. Internal networking problem #8

Open
macr1408 opened this issue Sep 19, 2018 · 6 comments
Labels
reference information Contains useful reference information resolved Issue has been resolved

Comments

@macr1408
Copy link

macr1408 commented Sep 19, 2018

I'm having a problem, my Wordpress site cannot connect to itself when using cron jobs. I'm using the plugin WP Crontrol to test it, and the post call to my own site doesn't work. I get this error:

cURL error 7: Failed to connect to 127.0.0.1 port 80: Connection refused

And the same error occurs with port 447 when I'm using SSL (self-signed).

I found this solution and it worked the first time I tried it, but later I deleted my containers, re deployed them and I can't get it working again, I guess i'm editing the host file incorrectly (inside the nginx container), I don't understand what does that solution do exactly and how it should be applied.

Also, I cannot edit files from the theme/plugin editor, It says that the site couldn't connect and I should upload the files using SFTP. Again, the site cannot connect to itself.

I'm using the default compose.yml, no changes applied.

@mjstealey
Copy link
Owner

@macr1408 - Some ideas.

Not knowing your full topology, there could be a couple things to look at.

Where is cron running?

  • If on the container, then 127.0.0.1 will refer to the container's network space, and you may need to consider /etc/hosts to drive cron's knowledge of references to the world.
  • if on the host, then 127.0.0.1 will refer to the localhost of the host, and it likely has no idea what the container is b/c it'll have some internal docker address like 172.17.0.3.

Are your ports open to the world, or are they internal to the docker network only?

  • you have ports 80 and 447 of the host mapped to 80 and 443 of the nginx container, you won't be able to remap 80 and 447 of the host to anything else b/c they are already taken.
  • you could put your cron task on the same subnet as your containers if using docker, or you'd likely have to use the FQDN_OR_IP of your mapped host to get at ports 80 and 443 of the nginx container.

Will update this issue as I think of other things, but a more thorough description of your topology would be useful.

@macr1408
Copy link
Author

macr1408 commented Sep 20, 2018

@mjstealey Thanks for your reply.

The wordpress site is running inside the wordpress container. I'm not using anything outside Docker, I just downloaded this repo and started using wordpress with docker-compose up -d in the URL 127.0.0.1, so yes, I guess I should edit the /etc/hosts file inside my container, but I don't know how to do that (I don't even know if I should edit the wordpress container or the nginx container).

No, I'm not remapping the ports. As far as I know, they are internal to the docker network only.

This is what I get from docker-compose ps

  Name                Command              State                    Ports                  
-------------------------------------------------------------------------------------------
mysql       docker-entrypoint.sh mysqld    Up      3306/tcp                                
nginx       nginx -g daemon off;           Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress   docker-entrypoint.sh php-fpm   Up      9000/tcp   

This is my docker ps

CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                                      NAMES
4e31ebbc079c        nginx:latest           "nginx -g 'daemon of…"   17 hours ago        Up 17 hours         0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   nginx
ccc686827979        wordpress:php7.2-fpm   "docker-entrypoint.s…"   17 hours ago        Up 17 hours         9000/tcp                                   wordpress
1ab17eb2472c        mariadb                "docker-entrypoint.s…"   17 hours ago        Up 17 hours         3306/tcp                                   mysql

/etc/hosts from the nginx container

127.0.0.1 localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.4      4e31ebbc079c

And this is the /etc/hosts from the wordpress container

127.0.0.1 localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3      ccc686827979

@mjstealey
Copy link
Owner

mjstealey commented Sep 20, 2018

@macr1408 - Okay, figured out what is going on, and it is not what I suggested earlier.

Basically the WP-Crontrol plugin is using general settings values to do it's probe, and in docker we're confusing it's notion of what is running where. I can provide an example using macOS Docker values (reference) which would need to be modified to fit your environment.

  1. stand up site using default settings over http and set DOMAIN_NAME to 127.0.0.1 in the nginx/wordpress.conf file.

  2. Once all containers are running, create your standard Wordpress login and install the WP Control plugin

  3. validate that you get the error as described

screen shot 2018-09-20 at 6 36 54 pm

  1. Go to the General > Settings page and update the values for Wordpress Address (URL) and Site Address (URL) to be that of your host machine as DNS resolvable by docker. (for macOS this is docker.for.mac.localhost)

screen shot 2018-09-20 at 6 38 07 pm

  1. Retry the WP Crontrol jobs which should now connect as expected

screen shot 2018-09-20 at 6 40 55 pm

You'll notice that your site has also change from http://127.0.0.1 to http://docker.for.mac.localhost

Here is why - Your site is exposed to the "world" from the nginx container's port 80, not the wordpress container's port 80. Wordpress is actually running on port 9000 using a different protocol. So, in order for WP Crontrol to work, it needs to "speak to" port 80 on the nginx container which is mapped to port 80 of the host, so if we interact with port 80 of the host (docker.for.mac.localhost:80) then things should work.

If you were deploying this onto a host that had a DNS resolvable fully qualified domain name (FQDN), this wouldn't be an issue as the setting for Wordpress Address (URL) and Site Address (URL) would be that FQDN.

@mjstealey mjstealey added resolved Issue has been resolved reference information Contains useful reference information labels Sep 21, 2018
@macr1408
Copy link
Author

Thanks a lot! for the solution and for teaching. I'm using Linux so I had to use http://172.17.0.1 instead http://docker.for.mac.localhost

Cron jobs work perfectly fine now.

Plugins/Theme editor still doesn't work, but I can edit those directly from my machine, so I don't care about that.

Thanks again @mjstealey :)

@ghost
Copy link

ghost commented Sep 20, 2019

I was having a similar problem with all my cron jobs/scheduled tasks not running in a production environment.

I wrote to UpdraftPlus about this and they provided an answer that perfectly works:

"Could you try adding the following line of code to your wp-config.php file (above the ‘stop editing’ line):
define( ‘ALTERNATE_WP_CRON’, true );

This will enable the alternative WordPress Cron system. This is designed to allow scheduled tasks to be processed when the main WP Cron is not able to run."

For context, see ticket:

https://updraftplus.com/forums/topic/automatic-backups-not-working-with-dockerized-wordpress/#post-436841

Thought I would post this as everything else that @mjstealey has configured and documented works great - thanks so much for this work!

@st-182
Copy link

st-182 commented Sep 29, 2023

For those who are using Docker Desktop on linux:
The problem with docker ports there is that

  1. the default 172.17.0.1 address, which is working in headless version of docker both in containers and in the browser is not accessible from the browser when using Docker Desktop (containers internally can communicate with each other, but I wont see the wordpress because it won't point me to website - see screenshot)
    image

  2. 127.0.0.1 resolved correctly in the browser, but it is not working inside containers

  3. host.docker.internal resolves inside containers, but by default is not pointing to 127.0.0.1 in /etc/hosts file (which you can edit with nano using sudo nano /etc/hosts and then it will resolve)
    So, there are two options to solve the following problem

  4. Edit /etc/hosts and add host.docker.internal there, so it would point to 127.0.0.1

  5. We can use another default address - kubernetes.docker.internal
    image
    This way we will reach the ultimate goal - to have same port for both our native network and Docker’s network (preserve the context).
    And then we just need to add this address to Wordpress Address (URL) and Site Address (URL) as @mjstealey suggested.
    image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reference information Contains useful reference information resolved Issue has been resolved
Projects
None yet
Development

No branches or pull requests

3 participants