这是indexloc提供的服务,不要输入任何密码
Skip to content

Move app and global ENV files to consolidated config path #6716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/appendices/0.35.0-migration-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 0.35.0 Migration Guide

## Changes

- The path on disk to both the global `ENV` file and the `ENV` file for a given app has been moved. Users should reference environment variables via the provided plugin triggers rather than directly sourcing the ENV files. Existing ENV files are left untouched and will be removed on the subsequent Dokku install.
10 changes: 5 additions & 5 deletions docs/configuration/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ Environment variables are available both at run time and during the application
For buildpack deploys, Dokku will create a `/app/.env` file that can be used for legacy buildpacks. Note that this is _not_ updated when `config:set` or `config:unset` is called, and is only written during a `deploy` or `ps:rebuild`. Developers are encouraged to instead read from the application environment directly, as the proper values will be available then.

> [!NOTE]
> Global `ENV` files are sourced before app-specific `ENV` files. This means that app-specific variables will take precedence over global variables. Configuring your global `ENV` file is manual, and should be considered potentially dangerous as configuration applies to all applications.
> Global environment variables are sourced before app-specific environment variables. This means that app-specific variables will take precedence over global variables. Configuring global environment variables should be considered potentially dangerous as configuration applies to all applications.

You can set multiple environment variables at once:

```shell
dokku config:set node-js-app ENV=prod COMPILE_ASSETS=1
dokku config:set node-js-app APP_ENV=prod COMPILE_ASSETS=1
```

Whitespace and special characters get tricky. If you are using dokku locally you don't need to do any special escaping. If you are using dokku over ssh you will need to backslash-escape spaces:
Expand All @@ -45,7 +45,7 @@ dokku config:set --encoded node-js-app KEY="$(base64 ~/.ssh/id_rsa)"
When setting or unsetting environment variables, you may wish to avoid an application restart. This is useful when developing plugins or when setting multiple environment variables in a scripted manner. To do so, use the `--no-restart` flag:

```shell
dokku config:set --no-restart node-js-app ENV=prod
dokku config:set --no-restart node-js-app APP_ENV=prod
```

If you wish to have the variables output in an `eval`-compatible form, you can use the `config:export` command
Expand All @@ -54,7 +54,7 @@ If you wish to have the variables output in an `eval`-compatible form, you can u
dokku config:export node-js-app
# outputs variables in the form:
#
# export ENV='prod'
# export APP_ENV='prod'
# export COMPILE_ASSETS='1'

# source in all the node-js-app app environment variables
Expand All @@ -68,7 +68,7 @@ dokku config:export --format shell node-js-app

# outputs variables in the form:
#
# ENV='prod' COMPILE_ASSETS='1'
# APP_ENV='prod' COMPILE_ASSETS='1'
```

## Special Config Variables
Expand Down
1 change: 1 addition & 0 deletions docs/getting-started/upgrading/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Docker releases updates periodically to their engine. We recommend reading their

Before upgrading, check the migration guides to get comfortable with new features and prepare your deployment to be upgraded.

- [Upgrading to 0.35](/docs/appendices/0.35.0-migration-guide.md)
- [Upgrading to 0.34](/docs/appendices/0.34.0-migration-guide.md)
- [Upgrading to 0.33](/docs/appendices/0.33.0-migration-guide.md)
- [Upgrading to 0.32](/docs/appendices/0.32.0-migration-guide.md)
Expand Down
4 changes: 2 additions & 2 deletions plugins/common/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (

var (
testAppName = "test-app-1"
testAppDir = strings.Join([]string{"/home/dokku/", testAppName}, "")
testAppDir = strings.Join([]string{"/var/lib/dokku/config/config/", testAppName}, "")
testEnvFile = strings.Join([]string{testAppDir, "/ENV"}, "")
testEnvLine = "export testKey=TESTING"
testAppName2 = "01-test-app-1"
testAppDir2 = strings.Join([]string{"/home/dokku/", testAppName2}, "")
testAppDir2 = strings.Join([]string{"/var/lib/dokku/config/config/", testAppName2}, "")
testEnvFile2 = strings.Join([]string{testAppDir2, "/ENV"}, "")
testEnvLine2 = "export testKey=TESTING"
)
Expand Down
9 changes: 9 additions & 0 deletions plugins/common/properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,15 @@ func PropertySetup(pluginName string) error {
})
}

// PropertySetupApp creates the plugin config root for a given app
func PropertySetupApp(pluginName string, appName string) error {
if err := PropertySetup(pluginName); err != nil {
return err
}

return makePluginAppPropertyPath(pluginName, appName)
}

func getPropertyPath(pluginName string, appName string, property string) string {
pluginAppConfigRoot := getPluginAppPropertyPath(pluginName, appName)
return filepath.Join(pluginAppConfigRoot, property)
Expand Down
1 change: 1 addition & 0 deletions plugins/config/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/config-*
/config_sub
/post-*
/install
2 changes: 1 addition & 1 deletion plugins/config/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GOARCH ?= amd64
SUBCOMMANDS = subcommands/bundle subcommands/clear subcommands/export subcommands/get subcommands/keys subcommands/show subcommands/set subcommands/unset
TRIGGERS = triggers/config-export triggers/config-get triggers/config-get-global triggers/post-app-clone-setup triggers/post-app-rename-setup
TRIGGERS = triggers/config-export triggers/config-get triggers/config-get-global triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-create triggers/post-delete
BUILD = commands config_sub subcommands triggers
PLUGIN_NAME = config

Expand Down
7 changes: 4 additions & 3 deletions plugins/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"os"
"path/filepath"
"strings"
"testing"

Expand All @@ -12,9 +13,9 @@ import (

var (
testAppName = "test-app-1"
dokkuRoot = common.MustGetEnv("DOKKU_ROOT")
testAppDir = strings.Join([]string{dokkuRoot, testAppName}, "/")
globalConfigFile = strings.Join([]string{dokkuRoot, "ENV"}, "/")
dokkuLibRoot = common.MustGetEnv("DOKKU_LIB_ROOT")
testAppDir = filepath.Join(dokkuLibRoot, "config", testAppName)
globalConfigFile = filepath.Join(dokkuLibRoot, "config", "--global", "ENV")
)

func setupTests() (err error) {
Expand Down
4 changes: 2 additions & 2 deletions plugins/config/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,9 @@ func loadFromFile(name string, filename string) (env *Env, err error) {
}

func getAppFile(appName string) (string, error) {
return filepath.Join(common.MustGetEnv("DOKKU_ROOT"), appName, "ENV"), nil
return filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "config", appName, "ENV"), nil
}

func getGlobalFile() string {
return filepath.Join(common.MustGetEnv("DOKKU_ROOT"), "ENV")
return filepath.Join(common.MustGetEnv("DOKKU_ROOT"), "config", "--global", "ENV")
}
8 changes: 8 additions & 0 deletions plugins/config/src/triggers/triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ func main() {
case "config-get-global":
key := flag.Arg(0)
err = config.TriggerConfigGetGlobal(key)
case "install":
err = config.TriggerInstall()
case "post-app-clone-setup":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
Expand All @@ -44,6 +46,12 @@ func main() {
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
err = config.TriggerPostAppRenameSetup(oldAppName, newAppName)
case "post-create":
appName := flag.Arg(0)
err = config.TriggerPostCreate(appName)
case "post-delete":
appName := flag.Arg(0)
err = config.TriggerPostDelete(appName)
default:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
}
Expand Down
73 changes: 73 additions & 0 deletions plugins/config/triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package config

import (
"fmt"
"os"
"path/filepath"
"strconv"

"github.com/dokku/dokku/plugins/common"
)

// TriggerConfigExport returns a global config value by key
Expand Down Expand Up @@ -45,6 +49,65 @@ func TriggerConfigGetGlobal(key string) error {
return nil
}

// TriggerInstall runs the install step for the config plugin
func TriggerInstall() error {
if err := common.PropertySetup("config"); err != nil {
return fmt.Errorf("Unable to install the config plugin: %s", err.Error())
}

apps, err := common.UnfilteredDokkuApps()
if err != nil {
return nil
}

// migrate all created-at values from app mod-time to property
for _, appName := range apps {
oldEnvFile := filepath.Join(common.AppRoot(appName) + "ENV")
isMigrated := common.PropertyGetDefault("config", appName, "env-migrated", "")
// delete the old file on the next install
if isMigrated == "true" {
if err := os.RemoveAll(oldEnvFile); err != nil {
return fmt.Errorf("Unable to remove old ENV file: %s", err.Error())
}
continue
}

// skip if the file doesn't exist
if _, err := os.Stat(oldEnvFile); err != nil {
if err := common.PropertyWrite("config", appName, "env-migrated", "true"); err != nil {
return fmt.Errorf("Unable to set env-migrated property: %s", err.Error())
}
continue
}

if err := common.PropertySetupApp("config", appName); err != nil {
return fmt.Errorf("Unable to setup app environment: %s", err.Error())
}

// merge in the old env into the new env
oldEnv, err := loadFromFile(appName, oldEnvFile)
if err != nil {
return fmt.Errorf("Unable to load old environment: %s", err.Error())
}

env, err := LoadAppEnv(appName)
if err != nil {
return fmt.Errorf("Unable to load app environment: %s", err.Error())
}

env.Merge(oldEnv)
if err := env.Write(); err != nil {
return fmt.Errorf("Unable to write app environment: %s", err.Error())
}

if err := common.PropertyWrite("config", appName, "env-migrated", "true"); err != nil {
return fmt.Errorf("Unable to set env-migrated property: %s", err.Error())
}
}

return nil
}

// TriggerPostAppCloneSetup creates new buildpacks files
func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error {
oldEnv, err := LoadAppEnv(oldAppName)
Expand Down Expand Up @@ -84,3 +147,13 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {

return nil
}

// TriggerPostCreate ensures apps have the correct config structure
func TriggerPostCreate(appName string) error {
return common.PropertySetupApp("config", appName)
}

// TriggerPostDelete destroys the config data for a given app container
func TriggerPostDelete(appName string) error {
return common.PropertyDestroy("config", appName)
}
10 changes: 5 additions & 5 deletions tests/unit/config-oddities.bats
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ load test_helper

setup() {
global_setup
[[ -f ${DOKKU_ROOT}/ENV ]] && mv -f ${DOKKU_ROOT}/ENV ${DOKKU_ROOT}/ENV.bak
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_ROOT}/ENV"
mkdir -p "${DOKKU_LIB_ROOT}/config/--global"
[[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV ]] && mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV ${DOKKU_LIB_ROOT}/config/--global/ENV.bak
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_LIB_ROOT}/config/--global/ENV"
create_app
}

teardown() {
destroy_app
ls -la ${DOKKU_ROOT}
if [[ -f ${DOKKU_ROOT}/ENV.bak ]]; then
mv -f ${DOKKU_ROOT}/ENV.bak ${DOKKU_ROOT}/ENV
if [[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ]]; then
mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ${DOKKU_LIB_ROOT}/config/--global/ENV
fi
global_teardown
}
Expand Down
10 changes: 5 additions & 5 deletions tests/unit/config.bats
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ load test_helper

setup() {
global_setup
[[ -f ${DOKKU_ROOT}/ENV ]] && mv -f ${DOKKU_ROOT}/ENV ${DOKKU_ROOT}/ENV.bak
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_ROOT}/ENV"
mkdir -p "${DOKKU_LIB_ROOT}/config/--global"
[[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV ]] && mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV ${DOKKU_LIB_ROOT}/config/--global/ENV.bak
sudo -H -u dokku /bin/bash -c "echo 'export global_test=true' > ${DOKKU_LIB_ROOT}/config/--global/ENV"
create_app
}

teardown() {
destroy_app
ls -la ${DOKKU_ROOT}
if [[ -f ${DOKKU_ROOT}/ENV.bak ]]; then
mv -f ${DOKKU_ROOT}/ENV.bak ${DOKKU_ROOT}/ENV
if [[ -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ]]; then
mv -f ${DOKKU_LIB_ROOT}/config/--global/ENV.bak ${DOKKU_LIB_ROOT}/config/--global/ENV
fi
global_teardown
}
Expand Down
Loading