Blog Workshop
A workshop-style log of the Hermes prompts used to deploy, configure, troubleshoot, and document this Ghost blog.
This version of the workshop is focused less on the raw Linux commands and more on the Hermes instructions that drove the project. It shows the prompts given to Johnny/Hermes and what each instruction caused Hermes to do on the server.
1. “Deploy a ghost blog docker projectâ€
This was the main build instruction. Hermes interpreted it as a Docker Manager-style deployment and created a Compose project under /docker/ghost-blog instead of running a one-off container.
Hermes checked Docker, inspected existing containers and ports, reviewed the Traefik setup, generated database credentials, wrote docker-compose.yml and .env, pulled ghost:5-alpine and mysql:8.0, started the stack, and verified that Ghost and MySQL were running.
2. “What is the URL to the Ghost blog?â€
This instruction asked Hermes to identify the public and local access URLs. At that stage, the blog was reachable locally on port 2368 and was configured for a public Ghost hostname.
Hermes reported the public URL, the /ghost admin URL, and the local server probe URL so the site could be opened and checked from different angles.
3. “I just deleted the Ghost Docker container; can you clean up any remains?â€
After the container was removed, this instruction had Hermes inspect Docker for leftovers. Hermes checked containers, volumes, networks, images, and /docker project files to make sure old Ghost pieces were gone before redeploying.
This mattered because stale volumes or leftover project files could have caused confusing results during a new deployment.
4. “Deploy a ghost blog docker project†again
After cleanup, the deployment instruction was repeated. Hermes rebuilt the Ghost project from scratch, again using /docker/ghost-blog as the project directory.
The rebuilt stack included Ghost, MySQL, named volumes, restart policies, a database health check, Traefik labels, and a secure .env file.
5. “My server’s IP address is 2.25.72.108 — how can I navigate to the Ghost blog?â€
This instruction shifted the task from container deployment to access and routing. Hermes explained the difference between direct IP access, the local Ghost port, and domain-based HTTPS routing through Traefik.
The practical outcome was that the blog needed a DNS record pointing the chosen hostname at the server, while Ghost itself continued running behind Traefik.
6. “What’s the Ghost URL again?â€
This was a reminder/checkpoint instruction. Hermes restated the blog URL, admin URL, and local access path so testing could continue without guessing.
7. “Let’s configure Gmail emailâ€
This instruction moved the project from basic site hosting to functional email. Ghost member login, newsletters, invites, and passwordless magic links depend on outbound mail.
Hermes updated the Compose configuration to include Gmail SMTP environment variables and created a helper script at /docker/ghost-blog/configure-gmail-smtp.sh.
8. “You do it, you have rootâ€
This instruction clarified the boundary between server access and secret access. Hermes had root on the server, but it still could not create or know the Google App Password from the user’s Google account.
Hermes explained that the App Password had to be generated by the account owner and entered directly into the server-side setup script, not pasted into chat.
9. “When attempting to login to the blog: Failed to log in, please try againâ€
This was the troubleshooting instruction. Hermes checked the Ghost logs instead of assuming the account password was wrong.
The logs showed POST /members/api/send-magic-link/ returning 500. The root cause was Gmail SMTP authentication: Gmail required an application-specific password.
10. “OK, I did thatâ€
After the Google App Password was entered into the script, this instruction told Hermes to verify the result.
Hermes checked the containers, confirmed Ghost restarted, verified the SMTP values were present without revealing the secret, and saw the successful login flow. The key log signal was POST /members/api/send-magic-link/ returning 201.
11. “It works now, tyâ€
This confirmed the deployment was no longer just running, but usable. The blog could send login emails and complete the magic-link sign-in flow.
12. “Summarize everything we did and post the summary to the blogâ€
This instruction turned the deployment work into documentation. Hermes drafted a recap post, published it to Ghost, restarted Ghost so the route refreshed, and verified that the post URL returned HTTP 200 with the expected content.
13. “Create a blog post, call it Blog Workshopâ€
This instruction created the first Blog Workshop post. The first version focused on deployment steps such as Docker Compose, MySQL, Traefik, hostname mapping, SMTP, and verification.
14. “I’m more interested in the Hermes commands I instructed you to doâ€
This instruction refined the blog post into the version you are reading now. Instead of just listing infrastructure steps, the post now follows the actual Hermes prompts that guided the project from deployment through troubleshooting and documentation.
Final outcome
Through those Hermes instructions, we created a working Ghost blog at https://blog.johnnyv5ai.com, deployed it as a Docker Compose project under /docker/ghost-blog, connected it to MySQL, routed it through Traefik with HTTPS, configured Gmail SMTP, fixed magic-link login, and published documentation back onto the blog itself.