Update The Mysterious 404 Issue

steffeydev 2025-01-16 21:05:09 +00:00
parent 9eac9dc0b2
commit 2135ff710c

@ -4,6 +4,6 @@ Every time a docker build is done, a new `frappe-bench/sites/assets` folder is c
The `frappe-bench/sites` folder is mounted in docker as a volume, because `frappe-bench/sites` contains instance-specific information like the host name and the DB creds that need to be persisted. This is awkward, since the `frappe-bench/sites/assets` should not be persisted and should always come from the current docker build. If you do persist it, you create the opportunity for the `assets.json` file to "point" to files that don't exist, thus leading to the 404 errors. The `frappe-bench/sites` folder is mounted in docker as a volume, because `frappe-bench/sites` contains instance-specific information like the host name and the DB creds that need to be persisted. This is awkward, since the `frappe-bench/sites/assets` should not be persisted and should always come from the current docker build. If you do persist it, you create the opportunity for the `assets.json` file to "point" to files that don't exist, thus leading to the 404 errors.
Frappe's official docker image and compose file solved this issue by declaring both `frappe-bench/sites` and `frappe-bench/sites/assets` as volumes in the Dockerfile, but only connecting `frappe-bench/sites` to a named volume in the compose file. This means that docker would always create an anonymous volume for `frappe-bench/sites/assets`. Anonymous volumes are created fresh every time the compose file is brought up. When a volume is created, docker gets it's initial content from the base image. So, when the `frappe-bench/sites` named volume was first created, it got the assets folder from the original image, and when the `frappe-bench/sites/assets` each time, it picks up the latest assets from the base image and mounts them. In this way, most of the `frappe-bench/sites` is persisted, but `frappe-bench/sites/assets` always shows the files from the underlying image instead of the parent volume. A clever hack that takes advantage of how docker anonymous volumes operate. However, if that anonymous volume is unmounted for whatever reason, or ends up pulling it's initial data from the parent volume instead of the base image, the `frappe-bench/sites/assets/assets.json` will revert to being the first version deployed on this server, and cause the 404 error. Unfortunately, I was not able to determine exactly what went wrong, only that it was related to this anonymous volume. Frappe's official docker image and compose file solved this issue by declaring both `frappe-bench/sites` and `frappe-bench/sites/assets` as volumes in the Dockerfile, but only connecting `frappe-bench/sites` to a named volume in the compose file. This means that docker would always create an anonymous volume for `frappe-bench/sites/assets`. Anonymous volumes are created fresh every time the compose file is brought up. When a volume is created, docker gets it's initial content from the base image. So, when the `frappe-bench/sites` named volume was first created, it got the assets folder from the original image, and when the `frappe-bench/sites/assets` is created each time, it picks up the latest assets from the base image and mounts them. In this way, most of the `frappe-bench/sites` is persisted, but `frappe-bench/sites/assets` always shows the files from the underlying image instead of the parent volume. A clever hack that takes advantage of how docker anonymous volumes operate. However, if that anonymous volume is unmounted for whatever reason, or ends up pulling it's initial data from the parent volume instead of the base image, the `frappe-bench/sites/assets/assets.json` will revert to being the first version deployed on this server, and cause the 404 error. Unfortunately, I was not able to determine exactly what went wrong, only that it was related to this anonymous volume.
My safer solution is to move `frappe-bench/sites/assets` to `frappe-bench/assets` during the image build and remove the `frappe-bench/sites/assets` volume from the Dockerfile. Then, in the `configurator` scripts, I remove anything currently at `frappe-bench/sites/assets` inside the volume and replace it with a symlink to `frappe-bench/assets`. In this way, the assets folder will always be in sync with the actual assets, I don't have to worry about docker creating 7 new anonymous volumes every time I update the image, and everything still works. You can see these changes in 5601d97782. My safer solution is to move `frappe-bench/sites/assets` to `frappe-bench/assets` during the image build and remove the `frappe-bench/sites/assets` volume from the Dockerfile. Then, in the `configurator` scripts, I remove anything currently at `frappe-bench/sites/assets` inside the volume and replace it with a symlink to `frappe-bench/assets`. In this way, the assets folder will always be in sync with the actual assets, I don't have to worry about docker creating 7 new anonymous volumes every time I update the image, and everything still works. You can see these changes in 5601d97782.