Platform.sh User Documentation

Tethered local

Try for 30 days
Flexible, version-controlled infrastructure provisioning and development-to-production workflows
Activate your trial

To test changes locally, you can connect your locally running Django server to service containers on an active Platform.sh environment.

Before you begin Anchor to this heading

You need:

  • A local copy of the repository for a Django project running on Platform.sh.

    To get one, run platform get PROJECT_ID .

    Alternatively, you can clone an integrated source repository and set the remote branch. To do so, run platform project:set-remote PROJECT_ID .

  • The Platform.sh CLI

Assumptions Anchor to this heading

This example makes some assumptions, which you may need to adjust for your own circumstances.

It’s assumed you want to run a built-in lightweight development server with manage.py runserver. To match a production web server (such as Gunicorn or Daphne), modify those commands accordingly.

It’s generally assumed that Platform.sh is the primary remote for the project. If you use a source integration, the steps are identical in most cases. When they differ, the alternative is noted.

If you followed the Django deployment guide, you should have a Django configuration file with settings for decoding variables and also overrides for Platform.sh.

You can use these settings to set up a tethered connection to services running on a Platform.sh environment. The settings are used to mock the conditions of the environment locally.

Create the tethered connection Anchor to this heading

  1. Create a new environment based on production.

    platform branch new-feature PRODUCTION_ENVIRONMENT_NAME

    If you’re using a source integration, open a merge/pull request.

  2. To open an SSH tunnel to the new environment’s services, run the following command:

    platform tunnel:open

    This command returns the addresses for SSH tunnels to all of your services.

  3. Export the PLATFORMSH_RELATIONSHIPS environment variable with information from the open tunnel:

    export PLATFORM_RELATIONSHIPS="$(platform tunnel:info --encode)"
  4. To ensure your settings.py file acts as if in a Platform.sh environment, mock two variables present in active environments:

    export PLATFORM_APPLICATION_NAME=django && export PLATFORM_ENVIRONMENT=new-feature
  5. To install dependencies, run the command for your package manager:

    python pip install -r requirements.txt
    
    pipenv install
    
    poetry install
        
  6. Collect static assets.

    python manage.py collectstatic
    
    pipenv run python manage.py collectstatic
    
    poetry run python manage.py collectstatic 
        
  7. To start your local server, run the following command based on your package manager:

    python manage.py runserver
    
    pipenv run python manage.py runserver
    
    poetry run python manage.py runserver
        
  8. When you’ve finished your work, close the tunnels to your services by running the following command:

    platform tunnel:close --all -y

Next steps Anchor to this heading

You can now use your local environment to develop changes for review on Platform.sh environments. The following examples show how you can take advantage of that.

Onboard collaborators Anchor to this heading

It’s essential for every developer on your team to have a local development environment to work on. Place the local configuration into a script to ensure everyone has this. You can merge this change into production.

  1. Create a new environment called local-config.

  2. To set up a local environment for a new Platform.sh environment, create an executable script.

    touch init-local.sh && chmod +x init-local.sh
  3. Fill it with the following example, depending on your package manager:

    init-local.sh
    #!/usr/bin/env bash
    
    PROJECT=$1
    ENVIRONMENT=$2
    PARENT=$3
    
    # Create the new environment
    platform branch $ENVIRONMENT $PARENT
    
    # Configure DDEV
    ddev config --auto
    ddev config --web-environment-add PLATFORM_PROJECT=$PROJECT
    ddev config --web-environment-add PLATFORM_ENVIRONMENT=$ENVIRONMENT
    ddev config --webimage-extra-packages python-is-python3
    
    ddev get drud/ddev-platformsh
    
    # Update .ddev/config.platformsh.yaml
    #   1. hooks.post-start
    printf "  # Platform.sh start command\n  - exec: |\n      python manage.py runserver 0.0.0.0:8000" >> .ddev/config.platformsh.yaml
    #   2. php_version
    grep -v "php_version" .ddev/config.platformsh.yaml > tmpfile && mv tmpfile .ddev/config.platformsh.yaml
    printf "\nphp_version: 8.0" >> .ddev/config.platformsh.yaml
    
    # Create a docker-compose.django.yaml
    printf "
    version: \"3.6\"
    services:
        web:
            expose:
                - 8000
            environment:
                - HTTP_EXPOSE=80:8000
                - HTTPS_EXPOSE=443:8000
            healthcheck:
                test: \"true\"
    " > .ddev/docker-compose.django.yaml
    
    # Create Dockerfile.python
    printf "
    RUN apt-get install -y python3.10 python3-pip
    " > .ddev/web-build/Dockerfile.python
    
    ddev start
    ddev pull platform -y
    ddev restart
    init-local.sh
    #!/usr/bin/env bash
    
    PROJECT=$1
    ENVIRONMENT=$2
    PARENT=$3
    
    # Create the new environment
    platform branch $ENVIRONMENT $PARENT
    
    # Configure DDEV
    ddev config --auto
    ddev config --web-environment-add PLATFORM_PROJECT=$PROJECT
    ddev config --web-environment-add PLATFORM_ENVIRONMENT=$ENVIRONMENT
    ddev config --webimage-extra-packages python-is-python3
    
    ddev get drud/ddev-platformsh
    
    # Update .ddev/config.platformsh.yaml
    #   1. hooks.post-start
    printf "  # Platform.sh start command\n  - exec: |\n      pipenv run python manage.py runserver 0.0.0.0:8000" >> .ddev/config.platformsh.yaml
    #   2. php_version
    grep -v "php_version" .ddev/config.platformsh.yaml > tmpfile && mv tmpfile .ddev/config.platformsh.yaml
    printf "\nphp_version: 8.0" >> .ddev/config.platformsh.yaml
    
    # Create a docker-compose.django.yaml
    printf "
    version: \"3.6\"
    services:
        web:
            expose:
                - 8000
            environment:
                - HTTP_EXPOSE=80:8000
                - HTTPS_EXPOSE=443:8000
            healthcheck:
                test: \"true\"
    " > .ddev/docker-compose.django.yaml
    
    # Create Dockerfile.python
    printf "
    RUN apt-get install -y python3.10 python3-pip
    " > .ddev/web-build/Dockerfile.python
    
    ddev start
    ddev pull platform -y
    ddev restart
    init-local.sh
    #!/usr/bin/env bash
    
    PROJECT=$1
    ENVIRONMENT=$2
    PARENT=$3
    
    # Create the new environment
    platform branch $ENVIRONMENT $PARENT
    
    # Configure DDEV
    ddev config --auto
    ddev config --web-environment-add PLATFORM_PROJECT=$PROJECT
    ddev config --web-environment-add PLATFORM_ENVIRONMENT=$ENVIRONMENT
    ddev config --webimage-extra-packages python-is-python3
    
    ddev get drud/ddev-platformsh
    
    # Update .ddev/config.platformsh.yaml
    #   1. hooks.post-start
    printf "  # Platform.sh start command\n  - exec: |\n      poetry run python manage.py runserver 0.0.0.0:8000" >> .ddev/config.platformsh.yaml
    #   2. php_version
    grep -v "php_version" .ddev/config.platformsh.yaml > tmpfile && mv tmpfile .ddev/config.platformsh.yaml
    printf "\nphp_version: 8.0" >> .ddev/config.platformsh.yaml
    
    # Create a docker-compose.django.yaml
    printf "
    version: \"3.6\"
    services:
        web:
            expose:
                - 8000
            environment:
                - HTTP_EXPOSE=80:8000
                - HTTPS_EXPOSE=443:8000
            healthcheck:
                test: \"true\"
    " > .ddev/docker-compose.django.yaml
    
    # Create Dockerfile.python
    printf "
    RUN apt-get install -y python3.10 python3-pip
    " > .ddev/web-build/Dockerfile.python
    
    ddev start
    ddev pull platform -y
    ddev restart
  4. To commit and push the revisions, run the following command:

    git add . && git commit -m "Add local configuration" && git push platform local-config
  5. Merge the change into production.

Once the script is merged into production, any user can set up their local environment by running the following commands:

platform PROJECT_ID
cd PROJECT_NAME
./init-local.sh PROJECT_ID another-new-feature PRODUCTION_ENVIRONMENT_NAME

Sanitize data Anchor to this heading

It’s often a compliance requirement to ensure that only a minimal subset of developers within an organization have access to production data during their work. By default, your production data is automatically cloned into every child environment.

You can customize your deployments to include a script that sanitizes the data within every preview environment.

  1. Create a new environment called sanitize-non-prod.

  2. Follow the example on how to sanitize PostgreSQL with Django. This adds a sanitization script to your deploy hook that runs on all preview environments.

  3. Commit and push the revisions by running the following command:

    git add . && git commit -m "Add data sanitization" && git push platform sanitize-non-prod
  4. Merge the change into production.

    Once the script is merged into production, every preview environment created on Platform.sh and all local environments contain sanitized data free of your users’ personally identifiable information (PII).

Is this page helpful?