Building in Public: Deploy a PHP Application with Kamal, part 3

This is the third part of a series about deploying a non-Rails application with Kamal 2. Read the previous article here. Follow this journey at https://github.com/jjeffers/sherldoc.

Quitters don’t win and winners don’t quit. Or until they pass out from blood loss.

Deploying a Queue Worker

I need to provision a “version” of sherldoc that will handle workers to process asynchronous jobs for the web application. The original sherldoc docker compose layout used a shared docker volume and the same sherldoc web container to run the queue workers.

In our configuration the containers don’t share a mounted volume at runtime. Instead, each image uses the same container image with similar post-run commands. The final docker entrypoint commands will diverge, with the queue worker starting the artisan worker process instead of the web application server steps.

Our deploy.yml includes the following additional server entry:

...
image: sherldoc-web 
...  
servers:
  web:
    hosts:
      - 159.203.76.193
    cmd: bash -c "/app/prepare_app.sh && cd /app/public; frankenphp php-server"

  workers:
    hosts:
      - 159.203.76.193
...

Kamal uses every server entry to deploy a container of the image entry, “sherldoc-web”. I can override the “workers” container with a new CMD.

After a another deploy I check kamal app details :

kamal app details -c ./deploy.yml 
  INFO [006857a0] Running docker ps --filter label=service=sherldoc --filter label=role=web on 159.203.76.193
  INFO [006857a0] Finished in 2.108 seconds with exit status 0 (successful).
App Host: 159.203.76.193
CONTAINER ID   IMAGE                                                                                                                          COMMAND                  CREATED              STATUS              PORTS              NAMES
bc7b3029bda6   registry.digitalocean.com/team-james-demo/sherldoc-web:[...]   "docker-php-entrypoi…"   About a minute ago   Up About a minute   80/tcp, 9000/tcp   sherldoc-web-[...]

  INFO [4c339292] Running docker ps --filter label=service=sherldoc --filter label=role=workers on 159.203.76.193
  INFO [4c339292] Finished in 0.229 seconds with exit status 0 (successful).
App Host: 159.203.76.193
CONTAINER ID   IMAGE                                                                                                                          COMMAND                  CREATED              STATUS              PORTS              NAMES
a913b7fcd417   registry.digitalocean.com/team-james-demo/sherldoc-web:[...]   "docker-php-entrypoi…"   About a minute ago   Up About a minute   80/tcp, 9000/tcp   sherldoc-workers-[...]

Both containers are up, but the container with the name “sherldoc-workers” started with the artisan queue:work command.

Why No Supervisor?

“If I can’t see you working, how do I know if you are getting anything done?”

I debated adding the supervisor (the process control utility) indicated in the source project’s docker compose configuration.

I suspect if sherldoc-workers container halted kamal-proxy would then restart it. I am not aware of any restart policy set for the docker containers on the server. Any restart would have to be external to the docker engine.

I tested this theory, attaching to the sherldoc-worker container and killing the main process, artisan queue:work. Within a few moments a new sherldoc-workers container was up and running.

Given this, I decide not to install or run supervisor.

Booting Additional Accessories

Next, I stand up Redis and Apache Tika.

...
accessories:
  ...
  redis:
     host: 159.203.76.193
     image: redis:6
     directories:
      - data.redis:/data

  tika:
    image: apache/tika:2.9.2.1-full
    ports:
      - 9998:9998

With that configuration change I start the redis instance:

kamal accessory boot redis -c ./deploy.yml 
  INFO [2f687e13] Running /usr/bin/env mkdir -p .kamal on 159.203.76.193
  INFO [2f687e13] Finished in 1.466 seconds with exit status 0 (successful).
Acquiring the deploy lock...
  INFO [bdb656a9] Running docker login registry.digitalocean.com/team-james-demo -u [REDACTED] -p [REDACTED] on 159.203.76.193
  INFO [bdb656a9] Finished in 0.936 seconds with exit status 0 (successful).
  INFO [34829155] Running docker network create kamal on 159.203.76.193
  INFO [16f49764] Running /usr/bin/env mkdir -p $PWD/sherldoc-redis/data.redis on 159.203.76.193
  INFO [16f49764] Finished in 0.210 seconds with exit status 0 (successful).
  INFO [bf65cb9c] Running /usr/bin/env mkdir -p .kamal/apps/sherldoc/env/accessories on 159.203.76.193
  INFO [bf65cb9c] Finished in 0.171 seconds with exit status 0 (successful).
  INFO Uploading .kamal/apps/sherldoc/env/accessories/redis.env 100.0%
  INFO [f431adff] Running docker run --name sherldoc-redis --detach --restart unless-stopped --network kamal --log-opt max-size="10m" --env-file .kamal/apps/sherldoc/env/accessories/redis.env --volume $PWD/sherldoc-redis/data.redis:/data --label service="sherldoc-redis" redis:6 on 159.203.76.193
  INFO [f431adff] Finished in 1.865 seconds with exit status 0 (successful).
Releasing the deploy lock...

And finally, I spin up the Tika instance:

kamal accessory boot tika -c ./deploy.yml 
  INFO [32435277] Running /usr/bin/env mkdir -p .kamal on 159.203.76.193
  INFO [32435277] Finished in 1.398 seconds with exit status 0 (successful).
Acquiring the deploy lock...
  INFO [42be2d9b] Running docker login registry.digitalocean.com/team-james-demo -u [REDACTED] -p [REDACTED] on 159.203.76.193
  INFO [42be2d9b] Finished in 0.537 seconds with exit status 0 (successful).
  INFO [e9abb23f] Running docker network create kamal on 159.203.76.193
  INFO [b36fa775] Running /usr/bin/env mkdir -p .kamal/apps/sherldoc/env/accessories on 159.203.76.193
  INFO [b36fa775] Finished in 0.207 seconds with exit status 0 (successful).
  INFO Uploading .kamal/apps/sherldoc/env/accessories/tika.env 100.0%
  INFO [94a1e92e] Running docker run --name sherldoc-tika --detach --restart unless-stopped --network kamal --log-opt max-size="10m" --publish 9998:9998 --env-file .kamal/apps/sherldoc/env/accessories/tika.env --label service="sherldoc-tika" apache/tika:2.9.2.1-full on 159.203.76.193
  INFO [94a1e92e] Finished in 16.586 seconds with exit status 0 (successful).
Releasing the deploy lock...

So far everything looks like it’s working, or at least the parts are operational. I’ll dive into the application itself next and see is working under the hood.

“I have no idea what I’m doing. Please come again.”

One thought on “Building in Public: Deploy a PHP Application with Kamal, part 3

Leave a comment