After over 3 hours of me banging my head against the wall, I've finally figured out how to get all this junk working and now I have a blog!
Unfortunately, I'm still learning a lot so parts of these instructions may be extraneous and I welcome everyone smarter than me to help me learn!
Here's how I got it from ground zero:
Step 1: Get a VPS and a domain
I used Vultr as my VPS but you could use DigitalOcean, etc. I personally have grown to like Debian as my Linux distro of choice so I'll be using that.
Blogs use very little resources so if you're only doing this, you could get away with the lowest amount of stuff.
I used Namecheap but you can use Google Domains, etc.
Step 2: Point your domain at your VPS
Namecheap makes it pretty easy to add DNS records so you just have to add 2 A records:
- One with a
hostof*to pick up all the subdomains - another with a
hostof@to pick up thewwwanddomain.tldversions of your URL.
They'll both use your VPS's IP address in the value section.
Step 3: Installing Docker
I just used this set of instructions from Docker to install it. The gist is:
apt update- Add their repo
- Install Docker and its dependencies
Most likely, you'll be root in your VPS but if you made a user, feel free to add yourself to the docker group so you don't have to sudo every time.
The command would be /usr/sbin/usermod -aG docker <username>.
Step 4: Installing Portainer
I personally really enjoy using Portainer since it simplifies doing a lot actions in Docker. To install it is pretty straightforward.
Following these instructions, just creating a volume and the container is enough. Once it's ready, we'll be doing stuff in Portainer.
Go to https://<your-ip>:9443 and finish the initial setup.
To be safe, we should be setting up the VPS with a VPN and connecting through there but for speed just have a good username/password.
Step 5: Installing Caddy
Once we have Portainer installed, the rest is pretty straightforward! I was pleasantly surprised about how fluid setting up environments and such are these days.
First, make sure that you have the configs/caddy folder set up. Then we can create a Caddyfile there already or else it will be angry and say you're trying to map a file to a directory.
Here's a sample one that I used:
<REDACTED>.orewa.pw {
reverse_proxy http://172.17.0.2:9000
}
blog.orewa.pw {
reverse_proxy ghost:2368
header {
header_up Strict-Transport-Security max-age=31536000; includeSubDomains; preload
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-For {remote}
header_up X-Real-IP {remote}
}
}Caddyfile
The first entry is for the Portainer instance. I think (?) I could probably use the container name instead of the Docker IP but it works... This way I don't have to go to a port, just a nice ole subdomain.
The second entry has some settings that I saw help with reverse proxying for this Ghost blog.
I love docker compose (especially coming from typing hundreds of docker commands), it simplifies and speeds up the process for me.
In Portainer, they're called stacks. Here's the one I used:
version: "3.9"
services:
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- /root/configs/caddy/Caddyfile:/etc/caddy/Caddyfile
- /root/configs/caddy/site:/srv
- caddy_data:/data
- caddy_config:/config
network_mode: bridge
volumes:
caddy_data:
caddy_config:Portainer Caddy stack
Once you run the stack, Caddy should be up and running!
Step 6: Setting up Ghost
Now that we're more acclimated with Portainer stacks, here's the one for Ghost! It sets up the Ghost and the MySQL containers. You just have to set the root password as the same thing for both and your URL.
version: '3.1'
services:
ghost:
container_name: ghost
image: ghost:5-alpine
restart: always
ports:
- 2368:2368
environment:
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: <PASSWORD>
database__connection__database: ghost
url: https://<your-url>
NODE_ENV: development
volumes:
- ghost:/var/lib/ghost/content
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: <PASSWORD>
volumes:
- db:/var/lib/mysql
volumes:
ghost:
db:Portainer Ghost stack
Badabing badaboom, your Ghost stack is up.
Once it's up, you can go to https://<YOUR-URL>/ghost and set up your blog! You don't have to use a real email if you don't want.
Conclusion
Now you have Portainer and a blog running! The cool part is you can extrapolate from the Caddyfile and Portainer stacks to spin up as many containers you want! Very exciting stuff.
Good luck hacking!