Skip to content

Commit

Permalink
Allow setting web environment in config.yaml, fixes ddev#871
Browse files Browse the repository at this point in the history
  • Loading branch information
rfay committed Jan 11, 2021
1 parent d374ae9 commit 420245b
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 13 deletions.
14 changes: 14 additions & 0 deletions cmd/ddev/cmd/config-global.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ var (
instrumentationOptIn bool
// omitContainers allows user to set value of omit_containers
omitContainers string
// webEnvironmentGlobal allows user to set value of environment in web container
webEnvironmentGlobal string
)

// configGlobalCommand is the the `ddev config global` command
Expand Down Expand Up @@ -46,6 +48,16 @@ func handleGlobalConfig(cmd *cobra.Command, args []string) {
}
dirty = true
}
if cmd.Flag("web-environment").Changed {
env := strings.Replace(webEnvironmentGlobal, " ", "", -1)
if env == "" {
globalconfig.DdevGlobalConfig.WebEnvironment = []string{}
} else {
globalconfig.DdevGlobalConfig.WebEnvironment = strings.Split(env, ",")
}
dirty = true
}

if cmd.Flag("nfs-mount-enabled").Changed {
globalconfig.DdevGlobalConfig.NFSMountEnabledGlobal, _ = cmd.Flags().GetBool("nfs-mount-enabled")
dirty = true
Expand Down Expand Up @@ -105,6 +117,7 @@ func handleGlobalConfig(cmd *cobra.Command, args []string) {
util.Success("Global configuration:")
output.UserOut.Printf("instrumentation-opt-in=%v", globalconfig.DdevGlobalConfig.InstrumentationOptIn)
output.UserOut.Printf("omit-containers=[%s]", strings.Join(globalconfig.DdevGlobalConfig.OmitContainersGlobal, ","))
output.UserOut.Printf("web-environment=[%s]", strings.Join(globalconfig.DdevGlobalConfig.WebEnvironment, ","))
output.UserOut.Printf("nfs-mount-enabled=%v", globalconfig.DdevGlobalConfig.NFSMountEnabledGlobal)

output.UserOut.Printf("router-bind-all-interfaces=%v", globalconfig.DdevGlobalConfig.RouterBindAllInterfaces)
Expand All @@ -119,6 +132,7 @@ func handleGlobalConfig(cmd *cobra.Command, args []string) {

func init() {
configGlobalCommand.Flags().StringVarP(&omitContainers, "omit-containers", "", "", "For example, --omit-containers=dba,ddev-ssh-agent")
configGlobalCommand.Flags().StringVarP(&webEnvironmentGlobal, "web-environment", "", "", `Add environment variables to web container: --web-environment="TYPO3_CONTEXT=Development,SOMEENV=someval"`)
configGlobalCommand.Flags().Bool("nfs-mount-enabled", false, "Enable NFS mounting on all projects globally")
configGlobalCommand.Flags().BoolVarP(&instrumentationOptIn, "instrumentation-opt-in", "", false, "instrmentation-opt-in=true")
configGlobalCommand.Flags().Bool("router-bind-all-interfaces", false, "router-bind-all-interfaces=true")
Expand Down
12 changes: 12 additions & 0 deletions cmd/ddev/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ var (

// ngrokArgs provides additional args to the ngrok command in `ddev share`
ngrokArgs string

webEnvironmentLocal string
)

var providerName = nodeps.ProviderDefault
Expand Down Expand Up @@ -248,6 +250,7 @@ func init() {
ConfigCommand.Flags().StringVar(&additionalHostnamesArg, "additional-hostnames", "", "A comma-delimited list of hostnames for the project")
ConfigCommand.Flags().StringVar(&additionalFQDNsArg, "additional-fqdns", "", "A comma-delimited list of FQDNs for the project")
ConfigCommand.Flags().StringVar(&omitContainersArg, "omit-containers", "", "A comma-delimited list of container types that should not be started when the project is started")
ConfigCommand.Flags().StringVar(&webEnvironmentLocal, "web-environment", "", `Add environment variables to web container: --web-environment="TYPO3_CONTEXT=Development,SOMEENV=someval"`)
ConfigCommand.Flags().BoolVar(&createDocroot, "create-docroot", false, "Prompts ddev to create the docroot if it doesn't exist")
ConfigCommand.Flags().BoolVar(&showConfigLocation, "show-config-location", false, "Output the location of the config.yaml file if it exists, or error that it doesn't exist.")
ConfigCommand.Flags().StringVar(&uploadDirArg, "upload-dir", "", "Sets the project's upload directory, the destination directory of the import-files command.")
Expand Down Expand Up @@ -523,6 +526,15 @@ func handleMainConfigArgs(cmd *cobra.Command, args []string, app *ddevapp.DdevAp
app.OmitContainers = strings.Split(omitContainersArg, ",")
}

if cmd.Flag("web-environment").Changed {
env := strings.Replace(webEnvironmentLocal, " ", "", -1)
if env == "" {
app.WebEnvironment = []string{}
} else {
app.WebEnvironment = strings.Split(env, ",")
}
}

if cmd.Flag("webimage-extra-packages").Changed {
if cmd.Flag("webimage-extra-packages").Value.String() == "" {
app.WebImageExtraPackages = nil
Expand Down
2 changes: 2 additions & 0 deletions docs/users/extend/config_yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ the .ddev/config.yaml is the primary configuration for the project.
| upload_dir | Relative path to upload directory used by `ddev import-files` | |
| working_dir | explicitly specify the working directory used by `ddev exec` and `ddev ssh` | `working_dir: { web: "/var/www", db: "/etc" }` would set the working directories for the web and db containers. |
| omit_containers | Allows the project to not load specified containers | For example, `omit_containers: [db, dba, ddev-ssh-agent]`. Currently only these containers are supported. Some containers can also be omitted globally in the ~/.ddev/global_config.yaml and the result is additive; all containers named in both places will be omitted. Note that if you omit the "db" container, several standard features of ddev that access the database container will be unusable. |
| web_environment | Inject environment variables into web container | For example, `web_environment: ["SOMEENV=someval", "SOMEOTHERENV=someotherval"]`. |
| nfs_mount_enabled | Allows using NFS to mount the project into the container for performance reasons | See [nfs_mount_enabled documentation](../performance.md). This requires configuration on the host before it can be used. Note that project-level configuration of nfs_mount_enabled is unusual, and that if it's true in the global config, that overrides the project-specific nfs_mount_enabled|
| fail_on_hook_fail | Decide whether `ddev start` should be interrupted by a failing hook |
| host_https_port | Specify a specific and persistent https port for direct binding to the localhost interface | This is not commonly used, but a specific port can be provided here and the https URL will always remain the same. For example, if you put "59001", the project will always use "<https://127.0.0.1:59001".> for the localhost URL. (Note that the named URL is more commonly used and for most purposes is better.) If this is not set the port will change from `ddev start` to `ddev start` |
Expand Down Expand Up @@ -57,6 +58,7 @@ The $HOME/.ddev/global_config.yaml has a few key global config options.
| nfs_mount_enabled | Enables NFS mounting globally for all projects | Only a "true" value has any effect. If true, NFS will be used on all projects, regardless of any settings in the individual projects. |
| fail_on_hook_fail | Enables `ddev start` interruption globally for all projects when a hook fails | Decide whether `ddev start` should be interrupted by a failing hook |
| omit_containers | Allows the project to not load specified containers | For example, `omit_containers: [ "dba", "ddev-ssh-agent"]`. Currently only these containers are supported. Note that you cannot omit the "db" container in the global configuration, but you can in the per-project .ddev/config.yaml. |
| web_environment | Inject environment variables into web container | For example, `web_environment: ["SOMEENV=someval", "SOMEOTHERENV=someotherval"]`. |
| instrumentation_opt_in | Opt in or out of instrumentation reporting | If true, anonymous usage information is sent to ddev via [segment](https://segment.com) |
| router_bind_all_interfaces | Bind on all network interfaces | If true, ddev-router will bind on all network interfaces instead of just localhost, exposing ddev projects to your local network. If you set this to true, you may consider `omit_containers: ["dba"]` so that the phpMyAdmin port is not available. |
| internet_detection_timeout_ms | Internet detection timeout | ddev must detect whether the internet is working to determine whether to add hostnames to /etc/hosts. It uses a DNS query and times it out by default at 750ms. In rare cases you may need to increase this value if you have slow but working internet. See [FAQ](../faq.md) and [issue link](https://github.com/drud/ddev/issues/2409#issuecomment-662448025).|
Expand Down
18 changes: 6 additions & 12 deletions docs/users/extend/customization-extendibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,16 @@ If you need to create a service configuration for your project, see [Defining an

## Providing custom environment variables to a container

Each project can have an unlimited number of .ddev/docker-compose.\*.yaml files as described in [Custom Compose Files](./custom-compose-files.md), so it's easy to maintain custom environment variables in a .ddev/docker-compose.environment.yaml file (the exact name doesn't matter, if it just matches docker-compose.\*.yaml).

For example, a `.ddev/docker-compose.environment.yaml` with these contents would add a $TYPO3_CONTEXT environment variable to the web container, and a $SOMETHING environment variable to the db container:
Custom environment variables may be set in the project config.yaml or the ~/.ddev/global_config.yaml with the `web_environment` key, for example

```yaml
version: '3.6'

services:
web:
environment:
- TYPO3_CONTEXT=Development
db:
environment:
- SOMETHING=something special
web_environment:
- SOMEENV=someval
- SOMEOTHERENV=someotherval
```

You can also use `ddev config global --web-environment="SOMEENV=someval"` or `ddev config --web-environment="SOMEENV=someval"` for the same purpose. The command just sets the values in the configuration files.

### Providing custom nginx configuration

When you `ddev start` using the `nginx-fpm` webserver_type, ddev creates a configuration customized to your project type in `.ddev/nginx_full/nginx-site.conf`. You can edit and override the configuration by removing the `#ddev-generated` line and doing whatever you need with it. After each change, `ddev start`.
Expand Down
12 changes: 11 additions & 1 deletion pkg/ddevapp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ type composeYAMLVars struct {
GID string
AutoRestartContainers bool
FailOnHookFail bool
WebEnvironment []string
}

// RenderComposeYAML renders the contents of .ddev/.ddev-docker-compose*.
Expand All @@ -706,10 +707,18 @@ func (app *DdevApp) RenderComposeYAML() (string, error) {
if err != nil {
util.Warning("Could not determine host.docker.internal IP address: %v", err)
}

// The fallthrough default for hostDockerInternalIdentifier is the
// hostDockerInternalHostname == host.docker.internal

webEnvironment := globalconfig.DdevGlobalConfig.WebEnvironment
localWebEnvironment := app.WebEnvironment
for _, v := range localWebEnvironment {
// docker-compose won't accept a duplicate environment value
if !nodeps.ArrayContainsString(webEnvironment, v) {
webEnvironment = append(webEnvironment, v)
}
}

uid, gid, username := util.GetContainerUIDGid()

templateVars := composeYAMLVars{
Expand Down Expand Up @@ -744,6 +753,7 @@ func (app *DdevApp) RenderComposeYAML() (string, error) {
DBBuildDockerfile: app.GetConfigPath(".dbimageBuild/Dockerfile"),
AutoRestartContainers: globalconfig.DdevGlobalConfig.AutoRestartContainers,
FailOnHookFail: app.FailOnHookFail || app.FailOnHookFailGlobal,
WebEnvironment: webEnvironment,
}
if app.NFSMountEnabled || app.NFSMountEnabledGlobal {
templateVars.MountType = "volume"
Expand Down
1 change: 1 addition & 0 deletions pkg/ddevapp/ddevapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ type DdevApp struct {
Timezone string `yaml:"timezone,omitempty"`
ComposerVersion string `yaml:"composer_version"`
DisableSettingsManagement bool `yaml:"disable_settings_management,omitempty"`
WebEnvironment []string `yaml:"web_environment"`
ComposeYaml map[string]interface{} `yaml:"-"`
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/ddevapp/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ services:
- SSH_AUTH_SOCK=/home/.ssh-agent/socket
- TZ={{ .Timezone }}
- VIRTUAL_HOST=${DDEV_HOSTNAME}
{{ range $env := .WebEnvironment }}- "{{ $env }}"
{{ end }}
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.platform: {{ .Plugin }}
Expand Down Expand Up @@ -347,6 +349,11 @@ const ConfigInstructions = `
# Drupal's settings.php/settings.ddev.php or TYPO3's AdditionalSettings.php
# In this case the user must provide all such settings.
# You can inject environment variables into the web container with:
# web_environment:
# - SOMEENV=somevalue
# - SOMEOTHERENV=someothervalue
# no_project_mount: false
# (Experimental) If true, ddev will not mount the project into the web container;
# the user is responsible for mounting it manually or via a script.
Expand Down
6 changes: 6 additions & 0 deletions pkg/globalconfig/global_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type GlobalConfig struct {
FailOnHookFailGlobal bool `yaml:"fail_on_hook_fail"`
ProjectList map[string]*ProjectInfo `yaml:"project_info"`
HostDockerInternal string `yaml:"host_docker_internal"`
WebEnvironment []string `yaml:"web_environment"`
}

// GetGlobalConfigPath() gets the path to global config file
Expand Down Expand Up @@ -155,6 +156,11 @@ func WriteGlobalConfig(config GlobalConfig) error {
# You can enable nfs mounting for all projects with
# nfs_mount_enabled: true
#
# You can inject environment variables into the web container with:
# web_environment:
# - SOMEENV=somevalue
# - SOMEOTHERENV=someothervalue
# In unusual cases the default value to wait to detect internet availability is too short.
# You can adjust this value higher to make it less likely that ddev will declare internet
# unavailable, but ddev may wait longer on some commands. This should not be set below the default 750
Expand Down

0 comments on commit 420245b

Please sign in to comment.