The
preconfigured base images
provided by Cloud Workstations contain only a minimal environment with IDE,
basic Linux terminal and language tools and a sshd server. To expedite the
environment setup of specific development use cases, you can create custom
container images that extend these base images to pre-install tools and
dependencies and that run automation scripts.
For custom container images, we recommend setting up a pipeline to automatically rebuild these images when the Cloud Workstations base image is updated, in addition to running a container scanning tool such as Artifact Analysis to inspect any additional dependencies you added. You're responsible for maintaining and updating custom packages and dependencies added to custom images.
Before you begin
You need a machine with tooling for building container images such as Docker, and for pushing images to Artifact Registry using the Google Cloud CLI. You can use Cloud Workstations or Cloud Shell Editor for performing these steps, which have this tooling pre-installed.
Select which base image you want to use from our list of supported base images, such as
us-central1-docker.pkg.dev/cloud-workstations-images/predefined/code-oss:latest.Alternatively, you can use your own container image or use external container images by following the instructions to Use your own container image.
Create a folder such as
CUSTOM_IMAGE_FOLDERand a Dockerfile inside this folder extending the base image selected, as shown in the examples that follow.
Cloud Workstations base image structure
Cloud Workstations base images share the following defined structure:
- The base image entrypoint file is set to
/google/scripts/entrypoint.sh. On startup, base images run files under
/etc/workstation-startup.d/*in lexicographical order to initialize the workstation environment.The files and their behavior are as follows:
000_configure-docker.sh: Configures and runs Docker inside the workstation.010_add-user.sh: Creates the default user in Cloud Workstations.Because the persistent disk is dynamically attached to the container, users must be added on workstation startup, not in the Dockerfile.
020_start-sshd.sh: Starts thesshdservice in the container.030_customize-environment.sh: Executes/home/user/.workstation/customize_environmentasuser.110_start-$IDE.sh: Starts the IDE for the image.
Cloud Workstations stores Docker images in the home directory at
/home/.docker_dataso that the images are preserved between sessions.
To add additional functionality during workstation startup, add your scripts in
the /etc/workstation-startup.d/ directory:
Scripts in this directory run as root by default. To execute the scripts as a different user, use the
runusercommand.Because scripts execute in lexicographical order, we recommended that you prefix the scripts with a three digit number that is greater than 200.
Alternatively, if you don't want to extend a workstations image, you can create a customize_environment script in your home directory.
Home directory modifications
When the workstation configuration specifies a persistent home directory
(which is the default behavior), a persistent disk backing the home directory
is dynamically attached to the container at runtime. This process overwrites
modifications made to the /home directory at container image build time.
To preserve updates, modify the /home directory at container runtime
by adding a script in the in the /etc/workstation-startup.d directory,
or by adding per-user configuration in the /etc/profile.d directory.
To speed up the process, consider running the setup script as a background
process (add an ampersand, &, to the end of the command) to avoid
blocking container startup.
Some examples of build time configuration that should be moved to container runtime:
- Per-user
gitconfiguration gitrepositories cloned in the home directory- Direct user configuration, such as placing files in a
$HOME/.configdirectory - User creation
User creation and modification
Because the persistent disk dynamically attaches to the container at runtime,
users must be added on workstation startup, not in the Dockerfile. To modify
or create additional users, we recommended that you update
/etc/workstation-startup.d/010_add-user.sh, or
create your own script that executes on startup.
Additionally, you can modify the default bash profile for the users by updating
the files in /etc/profile.d.
Update preconfigured Secure APT keys
Cloud Workstations base images come preinstalled with a number of tools obtained
from various third-party repositories using Secure APT. As part of the install
process, public keys provided by the repository owners are imported using gpg
and placed into individual files under /usr/share/keyrings/. These files are
referenced from corresponding list files under /etc/apt/sources.list.d/.
This enables apt to verify the integrity of the a given repository when
interacting with it.
On occasion, third-party repository owners may decide to change the public key
used to validate the integrity of their repository, which causes apt to
display an error when interacting with it. To resolve this potential problem,
you can use /google/scripts/refresh-preinstalled-apt-keys.sh, which
obtains the latest versions of preinstalled public keys and re-imports them.
You can also run this script directly in your custom Dockerfile before you
run apt-get update:
# Refresh the preinstalled APT keys
RUN /google/scripts/refresh-preinstalled-apt-keys.sh
RUN apt-get update
List installed IDE versions
Several Cloud Workstations base images come preinstalled with an IDE. For
convenience, see the included /google/scripts/preinstalled-ide-versions.sh
script, which lists the name and version information of IDEs installed in
the image.
Turn off sudo root privileges
The default workstation user has sudo root access privileges in these
containers. To turn off root access to the Docker container, set the
CLOUD_WORKSTATIONS_CONFIG_DISABLE_SUDO environment variable
to true when creating the workstation configuration.
To set this environment variable through the Google Cloud console when creating your workstation configuration, follow these steps:
- When creating your workstation configuration, complete the configuration for Basic information and the Machine configuration.
- On the Environment customization dialog, expand the Advanced container options section and select Environment variables.
- Click addAdd variable.
- Enter
CLOUD_WORKSTATIONS_CONFIG_DISABLE_SUDOandtrueas the value.
Customize without extending an image
For convenience all Cloud Workstations base images check for the presence of
an executable file located at /home/user/.workstation/customize_environment
and, if it exists, run it in the background as user. This lets you
run any script or binary at startup. Unlike .profile or .bashrc the script
only runs once when the workstation starts, rather than once for each shell
login.
Because the customize_environment script runs as user, be sure to update
permissions as necessary when writing your script. For example, if you want to
install Emacs everytime your workstation starts, the content of
customize_environment might be similar to the following:
#!/bin/bash
sudo apt-get update
sudo apt-get install -y emacs
Execution logs for customize_environment can be found in the container at
/var/log/customize_environment and are also written to the
container output logs.
On successful execution of customize_environment, a file is created in
/var/run/customize_environment_done. Because customize_environment runs in
parallel with Workstation startup, packages installed by the script can be
available as early as a few moments after your workstation has started.
Preventing idle timeouts
For convenience, all Cloud Workstations base images include a preinstalled script
at /google/scripts/keep_alive.sh. This script sends regular keep-alive
messages, which can prevent the workstation from shutting down due to idle
timeouts when you are running background processes without direct interaction.
Use your own container image
You can also use your own container image or use external container images, as long as they are Linux-based and run a blocking process when the container starts up.
When setting up the Dockerfile, the ENTRYPOINT instruction must run a
blocking process such as sleep infinity so that the container continues
to run, rather than immediately exit. Alternatively, in the workstation
configuration you can set the config.container.args field to specify a
blocking process.
When using your own container image, note the following:
Cloud Workstations does not require additional scripts from the Cloud Workstations base image.
You can, however, look at the scripts in the
/etc/workstation-startup.d/directory within a container running the Cloud Workstations base image. The filenames indicate what each script does.We recommend that you run an SSH server in the container. Refer to
/etc/workstation-startup.d/020_start-sshd.shin the default base image to learn how Cloud Workstations sets this up by default.We recommend that you run your default IDE or web server on port
80.
Google Cloud provides standard base images that you can use to build a fully custom container image.
Extend Cloud Workstations base images
When extending a Cloud Workstations base image to create a custom image for your workstation environment, you can take three approaches:
- Update your
Dockerfileto include any additional static assets that you want to add. - Add additional executable files under
/etc/workstation-startup.d/to customize the running container. Files under this directory automatically run in lexicographical order at container startup, so you can prefix your filename to run it at the appropriate time during workstation startup. - Override the
ENTRYPOINTin your Dockerfile to fully customize your container startup.
Sample custom Dockerfiles
This section provides example scenarios and instructions for creating your own Dockerfiles.
Container image with emacs pre-installed
To create a container image with emacs pre-installed, run the following
commands:
FROM us-central1-docker.pkg.dev/cloud-workstations-images/predefined/code-oss:latest
RUN sudo apt update
RUN sudo apt install -y emacs
Container image with user customization
Follow these steps to customize a container image:
Create a script in
/etc/workstation-startup.d/*that runs after010_add-user.sh—for example,011_customize-user.sh:#!/bin/bash # Create new group groupadd $GROUP # Add the user to a new group usermod -a -G $GROUP $USERNAMEReplace
$GROUPwith the new group name and$USERNAMEwith the user's username.Assuming that you named your script,
011_customize-user.sh, add the following to your image in your Dockerfile and make it executable:FROM us-central1-docker.pkg.dev/cloud-workstations-images/predefined/code-oss:latest COPY 011_customize-user.sh /etc/workstation-startup.d/ RUN chmod +x /etc/workstation-startup.d/011_customize-user.sh
Container image that sets container environment variables in SSH sessions
Environment variables set at the workstation configuration or workstation level are passed to direct subprocesses using the entrypoint command. This includes the IDE in the preconfigured base images. However, SSH sessions are not child processes of the entrypoint, and don't have these custom environment variables set.
To set those environment variables in the SSH sessions, setup a custom
container image that relays these environment variables from the container's
entrypoint command to the /etc/environment file.
To accomplish that, follow these steps:
Create a script in
/etc/workstation-startup.d/*that runs after010_add-user.sh—for example,011_add-ssh-env-variables.sh:#!/bin/bash # echo "CUSTOM_ENV_VAR=$CUSTOM_ENV_VAR" >> /etc/environmentReplace
CUSTOM_ENV_VARwith the intended environment variable name.Assuming that you named your script,
011_add-ssh-env-variables.sh, add the following to your image in your Dockerfile and make it executable:FROM us-central1-docker.pkg.dev/cloud-workstations-images/predefined/code-oss:latest COPY 011_add-ssh-env-variables.sh /etc/workstation-startup.d/ RUN chmod +x /etc/workstation-startup.d/011_add-ssh-env-variables.sh
Container image that enables X11 forwarding for SSH sessions
X11 forwarding lets you start remote applications and forward the application display to a local machine.
To create a container image that enables X11 forwarding, modify the OpenSSH daemon
configuration file (/etc/ssh/sshd_config) provided by the Cloud Workstations base images by
appending X11Forwarding yes (to permit X11 forwarding) and AddressFamily inet
(to ensure that only IPv4 is used). For more information about these keywords, see the OpenBSD web
pages about AddressFamily and
X11Forwarding.
Here's a sample Dockerfile, which makes the necessary modifications: