docker-library / ghost

Docker Official Image packaging for Ghost
https://hub.docker.com/_/ghost
MIT License
730 stars 312 forks source link

Setting mail settings thru env variables doesn't work #207

Closed colorfulsing closed 4 years ago

colorfulsing commented 4 years ago

Description: I have tested with several ghost versions, both alpine and non-alpine version, but I haven't been able to have ghost docker to set the mail settings thru environment variables into config.production.json. I don't understand why it is not working!

Linux kernel: 5.4.13
Docker version 19.03.5-ce, build 633a0ea838

Steps to reproduce: I have tested both using env file and inline env vars within the docker command, none worked.

Here is using the env file:

docker run -d -p 3001:2368 -v /srv/ghost/content:/var/lib/ghost/content --env-file=test.env --name ghost ghost:3.3.0-alpine

My test.env file is as follows:

url=https://www.example.com
mail__transport="SMTP"
mail__options__service="Gmail"
mail__options__auth__user="example@gmail.com"
mail__options__auth__pass="my-pass"

And here is using docker command only with inline env vars with same results:

docker run -d -p 3001:2368 -v /srv/ghost/content:/var/lib/ghost/content \
-e url=https://www.example.com \
-e mail__transport="SMTP" \
-e mail__options__service="Gmail" \
-e mail__options__auth__user="example@gmail.com" \
-e mail__options__auth__pass="my-pass" \
--name ghost ghost:3.3.0-alpine

Expected behavior: config.production.json contents:

{
  "url": "http://localhost:2368",
  "server": {
    "port": 2368,
    "host": "0.0.0.0"
  },
  "database": {
    "client": "sqlite3",
    "connection": {
      "filename": "/var/lib/ghost/content/data/ghost.db"
    }
  },
  "mail": {
    "transport": "SMTP",
    "options": {
        "service": "Gmail",
        "auth": {
            "user": "example@gmail.com",
            "pass": "my-pass"
        }
    }
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/lib/ghost/content"
  }
}

Actual behavior: config.production.json contents:

{
  "url": "http://localhost:2368",
  "server": {
    "port": 2368,
    "host": "0.0.0.0"
  },
  "database": {
    "client": "sqlite3",
    "connection": {
      "filename": "/var/lib/ghost/content/data/ghost.db"
    }
  },
  "mail": {
    "transport": "Direct"
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/lib/ghost/content"
  }
}
acburdine commented 4 years ago

@colorfulsing are you seeing errors from Ghost around the mail configuration not working, or is the confusion around why the config.production.json file isn't being updated?

As far as the config.production.json file goes, you won't see your environment variables added to it. Ghost itself knows how to pull configuration fields from both config.production.json and environment variables, so there's no need to modify the contents of the json file. You can take a look at the docs here for more information on how it works 😄

colorfulsing commented 4 years ago

@acburdine wait, so does that means that the env variables override the config.production.json config file contents without writing to the file? if so, could you guys update documentation to clarify that on detail?

It is extremely confusing how it really works as it does override config.production.json file when url env variable is set but it doesn't for mail so how would users know which settings would override config.production.json and which ones won't...

Don't take me wrong, ghost blog is amazing and being able to override config is awesome, but from a user point of view (or anyone trying to debug for that matter), ghost docker just doesn't work because it is not writing the file. Trying to send an email without being able to confirm configuration first doesn't make any sense, specially when implementing it into a existing running production website.

I will test to send an email ignoring config.production.json file contents, and report back.

acburdine commented 4 years ago

@colorfulsing all configuration settings, when supplied via environment variables, override what's in the file. I can make a note to get the docs updated to note that environment variables override what's in the config.production.json file.

colorfulsing commented 4 years ago

@acburdine success!!

You were totally right, the env vars are not reflected into config.production.json file but it does override the config. So many hours wasted because of this misunderstanding... but it is great to finally see it working.

Can you guys update it to specify to users that the env vars will take effect overriding config.production.json file in memory, but that it will NOT modify the config.production.json file contents?

Thanks for all the help and fast response! :smile:

noahsbwilliams commented 4 years ago

I'm curious what you did to get that to work...

I'm having an issue where mail actually doesn't send while using Sendgrid (sending a test email throws "Failed to send email. Reason: Authentication required, invalid details provided.")

My docker-compose environment looks like this:

environment:
      database__client: 'sqlite3'
      url: 'https://domain.com'
      mail__transport: 'SMTP'
      mail__options__service: 'Sendgrid'
      mail__options__port: '587'
      mail__options__secureConnection: 'true'
      mail__options__host: 'smtp.sendgrid.net'
      mail__options__auth__user: 'apikey'
      mail__options__auth__password: ${SMTP_PASSWORD}

I've verified the API key I put in the .env file works, and has permissions to send. When I docker exec into the ghost container and do a prinenv, I can see the API key correctly listed as an environment variable.

I also tried hardcoding it in, just in case, to no avail.

Running Ghost 3.7

dm17 commented 2 years ago

@colorfulsing are you seeing errors from Ghost around the mail configuration not working, or is the confusion around why the config.production.json file isn't being updated?

As far as the config.production.json file goes, you won't see your environment variables added to it. Ghost itself knows how to pull configuration fields from both config.production.json and environment variables, so there's no need to modify the contents of the json file. You can take a look at the docs here for more information on how it works smile

Is Ghost expected to function normally without config.development.json & config.production.json if all of the relevant variables are supplied via docker's --env-file? Thanks.

dm17 commented 2 years ago

@colorfulsing all configuration settings, when supplied via environment variables, override what's in the file. I can make a note to get the docs updated to note that environment variables override what's in the config.production.json file.

But these config files still needs to exist with some variables or else ghost will explode on start, it seems... Correct? I agree with @colorfulsing that this is confusing and opaque.

Ghost blows up without the config file existing + url & database variables in it... Would be cleaner if that wasn't the case - but for now the developer has to remember those are being used even though they must exist as a placeholder for environmental variables existing.