How the docker workflow works
Docker is not a virtual machine, it’s a container that runs a (usually minimal GNU/linux) system inside, somewhat isolated from the outside world. Having said that, Docker runs in a virtual machine on Windows, because Windows is not compatible with Linux binaries. In our case we use Ubuntu on WSL2. Other distros can be used, but instructions are for Ubuntu.
There’s a problem with the Docker volume bind to the Windows file system that means that on Windows all project files, and development workflow should be done inside Ubuntu, or its native file system. The downside to this is added complexity for file access and such, but the upside is that since the workflow is running on Linux, all instructions are identical.
Docker basics
When debugging problems in docker, it might be important to know a bit about how docker works, from an end-user perspective. This is a very simple explanation and might not be entirely how things work under the hood, but more of how you can think of things.
Images
These are the created images that are downloaded to your machine. They are the same for all projects, and they are read only, in the sense that they only change if a new image is downloaded. They are the base state the containers start from.
Containers
These are created per project, and they are a "layer" on top of the images that keep the "state" of the container. They represent a running "machine". jcore stop and jcore clean delete project or all containers respectively.
Volumes
Volumes are like disks that docker uses to store data on. They are more persistent than containers, and survive reboots of both containers and the host machine.
Bind folders
These are folders on the host machine that act very similar to volumes. This is in essence what the project files are. You can edit files on the host and have them change in the container. These are mostly tracked by GIT, except for the files in the project .jcore folder.
The container images
The workflow uses docker compose to control and tie together the docker containers. All this is defined in the docker-compose.yml file in the project root. This is a list of the containers, and what they do:
wordpress
This container is based on the php-fpm container, and is the main container for our workflow. WordPress and all PHP code is run on this container. This container installs WordPress by default, if it’s not already installed. It doesn't have a web server, and is not “visible” to the host machine, but this is the container that jcore shell command runs a shell on.
db
This container runs the MariaDB database. This one is exposed to wordpress and adminer containers. It contains all the WP database data.
adminer
This container runs an (optional) adminer front end to access the db container. It's exposed on port 1080. It doesn't have TLS. Can be accessed with http://127.0.0.1:1080.
(all the fields can be filled in with wordpress (username, password, db))
nginx
This is the web server container. It accesses file assets directly, and PHP on wordpress via fastCGI on internal port 9000. It also uses a cached proxy that accesses images and such from the upstream server under /wp-content/uploads folder. It serves TLS (https) with certs generated by the tlscerts container.
tlscerts
This container runs only when docker compose is started and generates TLS certs if they don’t exist. It then exits, as it is no longer needed. But if something is wrong with the web server, this one should be checked for errors, as nginx needs the certs in order to start.