# Self hosting ghost blog on your home server

[Ghost](https://ghost.org/?ref=nikhildev.com) has one of most beautiful interface for both writing and reading post. The only downside that I found was that to leverage the full benefit I had to pay up. Of course Wordpress is an option to self host but only recently did I become aware that [Ghost](https://ghost.org/?ref=nikhildev.com) can be self hosted as well and has docker images that I could use.

In this post I will try my best to explaining how I got mine up and working

**Prerequisites**

I will assume that you have the following already set up

1. A linux server
    
2. Docker installed within it
    
3. Cloudflare tunnel or some way of exposing your service to the outside world
    

Let's start with the `docker-compose.yaml`

```yaml
services:
  ghost:
    image: ghost:latest
    container_name: ghost-server
    environment:
      - url=https://blog.nikhildev.com
      - mail__transport=SMTP
      - mail__options__host=smtp.eu.mailgun.org
      - mail__options__port=587
      - mail__options__auth__user=<your_auth_user_email>
      - mail__options__auth__pass=<the_password_from_mailgun>
      - mail__from=blog@example.com #This probably will need verification
      - database__client=mysql
      - database__connection__host=db # Name of the service from below
      - database__connection__user=ghost
      - database__connection__password=ghost # You can choose a better password
      - database__connection__database=ghost
    volumes:
      - /docker_volumes/ghost/content:/var/lib/ghost/content # I prefer to map a different location for the safe keep of the data. The /docker_volumes is mirrored on zpool for redundancy
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "2368:2368"
  db:
    image: mysql:9
    container_name: ghost-db
    restart: always
    networks:
      - default
    volumes:
      - /docker_volumes/ghost/db/data:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=ghost
      - MYSQL_USER=ghost
      - MYSQL_PASSWORD=ghost
      - MYSQL_ROOT_PASSWORD=ghost
      - MYSQL_ROOT_HOST=172.*.*.* ## Ensures the Docker network has access
```

In the above docker compose files we are defining two service. `ghost-server` is the main application and `db` is a mysql instance that it would be using.

Now, if you want the newsletter part of ghost be available to you, I would highly recommend signing up with something like [Mailgun](https://www.mailgun.com/?ref=nikhildev.com) which has pretty generous free tier. Once you have signed up, use the generated credentials in ghost. Here is a great article on it [https://brightthemes.com/blog/ghost-mailgun-config](https://brightthemes.com/blog/ghost-mailgun-config?ref=nikhildev.com.com)

I'm sticking to exposing the default port of the service as in my entire stack there are no conflicting ones.

The `db` service is vanilla mysql without any bells and whistles. The official guide suggests using mysql 8 but I've tried this with mysql 9 and it works just fine. We simply are setting the credentials before hand to be made accessible to the ghost instance. Even here I prefer to mount a redundant local directory just for safe keeps.

And that's it. Go ahead and run the container with `docker compose up -d` and run through the setup process. If you run into any issues, please leave a comment and I can probably try and help you out.
