Skip to content
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

As a developer, I can easily access service ports #691

Closed
mglaman opened this issue Feb 28, 2018 · 11 comments
Closed

As a developer, I can easily access service ports #691

mglaman opened this issue Feb 28, 2018 · 11 comments
Labels
Prioritized We expect to do this in an upcoming release

Comments

@mglaman
Copy link
Contributor

mglaman commented Feb 28, 2018

Feature request:

As a developer, I wish to easily access the ports for my app services.

What you expected to happen:

Currently, we have to type ddev describe to see ports for our connected services and database information. As a developer, I would like my tooling to easily know these ports for custom commands or a custom bootstrap process of my CMS on the host.

  • When I run ddev start, my service ports are mapped to .ddev/ports.json
  • When I run ddev stop my service port maps are removed
  • When I run a CLI tool on my host, the CMS can be bootstrapped by services using port defined in .ddev/ports.json

This would allow Solr, MySQL/Maria, Elastic, Redis support on host command line. I picked JSON because it's most easy thing to serialize/unserialize across languages.

So regardless if WP-CLI, Drush, Console, whatever. Each CMS can support a host settings.

I would like to have a generated ports.json in the .ddev folder. This would resemble the following:

{
  mysql: 32768
  mailhog: 8025
}

Each time the command is run and containers are brought up, this is updated.

This would allow me to easily customize settings to read the port from my host and allow execution of tooling on my host, instead of ddev exec.

This is beneficial so that I can run Blackfire.io profiling and Xdebug on my commands.

Why ports.json? Because my current workflow involves something like this

    $cmd = "docker inspect --format='{{(index (index .NetworkSettings.Ports \"3306/tcp\") 0).HostPort}}' {{ container_name }}";
    $port = trim(shell_exec($cmd));
    $host = '{{ project_domain }}';
    define('DB_HOST', "$host:$port");

That means each time the settings are loaded it executes a docker inspect which isn't performant and requires specific container naming. But since ddev controls the containers we can trust the file will be built properly

I picked JSON because it is the most common format that can be serialized/unserialized across languages (without external libraries.)

Anything else do we need to know:

Related source links or issues:

This was inspired by / relates to #454

My WordPress setup: https://github.com/mglaman/platform-docker/tree/develop/resources/stacks/wordpress
My Drupal setup: https://github.com/mglaman/platform-docker/tree/develop/resources/stacks/drupal8

Please use a complexity rating of 1-5 (5 is high) for a feature request. (High complexity implies more PR planning)

3

@mglaman
Copy link
Contributor Author

mglaman commented Feb 28, 2018

The Drupal configuration currently has

// This is super ugly but it determines whether or not drush should include a custom settings file which allows
// it to work both within a docker container and natively on the host system.
if (!empty($_SERVER["argv"]) && strpos($_SERVER["argv"][0], "drush") && empty($_ENV['DEPLOY_NAME'])) {
  include __DIR__ . '../../../drush.settings.php';
}

This should be renamed to host.settings.php and loaded whenever DEPLOY_NAME is missing or any DDEV* environment variable.

@mglaman
Copy link
Contributor Author

mglaman commented Feb 28, 2018

However CreateSettingsFile is only called on import db... not when ddev config runs.

@rickmanelius
Copy link
Contributor

I had a discussion with @mglaman at Midcamp. There are two segments to this feature.

  1. Simply the exposing of this information, which I don't see as a problem and could be helpful as a flat file way of accessing that information.
  2. By default including, this in the DB configurations as variables so that they can be used.

The first should be an easy lift. The second has some implications across CMSes. Let me know if that would hit your use case. I'm assuming it's likely that end-users will need to modify DB settings file per project to make this work. However, I'm open to discuss in more detail to see how viable the second part is.

@rfay
Copy link
Member

rfay commented Jul 16, 2018

ddev describe -j already has output that shows published_port for mysql, is that adequate for this?:

    "raw": {
        "approot": "/Users/rfay/workspace/d7git",
        "dbinfo": {
            "dbname": "db",
            "host": "db",
            "password": "db",
            "port": "3306",
            "published_port": "32848",
            "username": "db"
        },

@mglaman
Copy link
Contributor Author

mglaman commented Jul 18, 2018

It does. Currently I have

if (!getenv('DDEV_PROJECT_TYPE')) {
  $result = json_decode(shell_exec('ddev describe -j'));
  $databases['default']['default']['host'] = '127.0.0.1';
  $databases['default']['default']['port'] = $result->raw->dbinfo->published_port;
}

But the idea would be to not run shell_exec each time.

I guess via hooks I could echo that to a JSON file and just load that instead.

@rfay
Copy link
Member

rfay commented Jul 18, 2018

Your hook would have to clean up the file when you did an 'rm', because it would then be the wrong port (likely) on start.

@mglaman
Copy link
Contributor Author

mglaman commented Jul 20, 2018

Well each start would reset the file.

@rickmanelius
Copy link
Contributor

I’m long overdue to drive this one to AC. I’ll commit to COB Monday.

@rickmanelius
Copy link
Contributor

I believe this is a related request by @tmotyl asking for stable ports for mysqlworkbench. The same could be achievable if the ports were accessible. See #941

@rickmanelius
Copy link
Contributor

So this is an initial set of thoughts that may sane or not. But I see a few different ways this could be achieved in order to meet the goals during various use cases.

Problem Statement:

  • While each projects ports are easily found using ddev describe -j, there is frustration in having to search and replace these values out while on the 1) host command line, 2) container command line or 3) CMS/application. The concept of always generating a .ddev/ports.json file allows access by all three.
  1. Host Command Line: This could be achievable by either relying on a 3rd party library (jq to parse json on Linux) or a new command like ddev ports, which would take the current project and generate environment variables for each. This could be akin to PROJECTNAME_PORT_MYSQL. A user would run ddev port && mysql -u username -ppassword -hlocalhost --port=$PROJECTNAME_PORT_MYSQL
  2. Container Command Line. If we include the jq library, a user could then more .ddev/ports.json and then pipe through jq '.key'
  3. CMS application. Since we are already generating a settings.ddev.php for Drupal, we could then attempt to read the .ddev/ports.json file during bootstrap and then run json_decode and store in $settings.php['ddev']['ports'].

Please ignore any syntax errors. The point is more of trying to determine a way to make this programmable and fixed from a usage perpsective while allowing ports to change to avoid collisions.

@rfay rfay added the Prioritized We expect to do this in an upcoming release label Jun 4, 2019
@rfay
Copy link
Member

rfay commented Apr 8, 2020

ddev describe and ddev describe -j as of v1.14 also report the ports (http and https) of 3rd party services. Closing as I think this does the job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Prioritized We expect to do this in an upcoming release
Projects
None yet
Development

No branches or pull requests

3 participants