Skip to content
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
27 changes: 27 additions & 0 deletions src/ttyd/.devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "ttyd",
"dockerComposeFile": "docker-compose.yaml",
"service": "app",
"runServices": ["app"],
"shutdownAction": "none",
"workspaceFolder": "/workspace",
"postCreateCommand":
"./startupscript/post-startup.sh abc /config \"${templateOption:cloud}\" \"${templateOption:login}\"; ./sudo-passwordless.sh abc",
"postStartCommand": [
"./startupscript/remount-on-restart.sh",
"abc",
"/config",
"${templateOption:cloud}",
"${templateOption:login}"
],
"features": {
"ghcr.io/anthropics/devcontainer-features/claude-code@sha256:cfc2e7d3e9fd3b9b01f8d5cb158508a884c8c0ede2e23ed10f32dea5d4ffe69a": {},
"ghcr.io/ar90n/devcontainer-features/ttyd:1": {},
"./.devcontainer/features/workbench-tools": {
"cloud": "${templateOption:cloud}",
"username": "abc",
"userHomeDir": "/config"
}
},
"remoteUser": "root"
}
3 changes: 3 additions & 0 deletions src/ttyd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ttyd

Custom Workbench application based on ttyd
23 changes: 23 additions & 0 deletions src/ttyd/devcontainer-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"id": "ttyd",
"description": "ttyd is a simple command-line tool for sharing terminal over the web",
"version": "0.9.1",
"name": "Workbench minimal ttyd",
"documentationURL": "https://github.com/verily-src/workbench-app-devcontainers/tree/add-ttyd-devcontainer/src/ttyd",
"licenseURL": "https://github.com/verily-src/workbench-app-devcontainers/blob/master/LICENSE",
"options": {
"cloud": {
"type": "string",
"description": "VM cloud environment",
"proposals": ["gcp", "aws"],
"default": "gcp"
},
"login": {
"type": "string",
"description": "Whether to log in to workbench CLI",
"proposals": ["true", "false"],
"default": "false"
}
},
"platforms": ["Any"]
}
32 changes: 32 additions & 0 deletions src/ttyd/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
services:
app:
# The container name must be "application-server"
container_name: "application-server"
# This can be either a pre-existing image or built from a Dockerfile
image: "ubuntu:24.04"
restart: always
volumes:
- .:/workspace:cached
command: ["ttyd", "-W", "-p", "8888", "bash"]
# The port specified here will be forwarded and accessible from the
# Workbench UI.
ports:
- 8888:8888
environment:
USER: "abc"
DEFAULT_WORKSPACE: "/config"
SUDO_PASSWORD: "pwd"
# The service must be connected to the "app-network" Docker network
networks:
- app-network
security_opt:
- apparmor:unconfined

volumes:
work:

networks:
# The Docker network must be named "app-network". This is an external network
# that is created outside of this docker-compose file.
app-network:
external: true
34 changes: 34 additions & 0 deletions src/ttyd/sudo-passwordless.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

# This script is used to set up passwordless sudo for the core user on the VM.
# It requires to be run with root priviledges and USER_NAME to be set in the environment.
# It is typically called from post-startup.sh.

USER_NAME="${1}"

if [[ -z "${USER_NAME}" ]]; then
echo "Usage: $0 <username>"
exit 1
fi

sudoers_file="/etc/sudoers"
sudoers_d_file="/etc/sudoers.d/${USER_NAME}"

# Make sure user exists
if ! id "${USER_NAME}" &>/dev/null; then
echo "User ${USER_NAME} does not exist."
exit 1
fi

# Check if there's an old rule in the main sudoers file that requires a password
if grep -q "^${USER_NAME} ALL=(ALL:ALL) ALL" "${sudoers_file}"; then
echo "Found password-requiring rule for ${USER_NAME} in /etc/sudoers. Commenting it out."

# Comment out the old rule in /etc/sudoers
sed -i "s/^${USER_NAME} ALL=(ALL:ALL) ALL/# ${USER_NAME} ALL=(ALL:ALL) ALL/" "${sudoers_file}"
fi

echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" > "${sudoers_d_file}"
chmod 440 "${sudoers_d_file}"

echo "User ${USER_NAME} has been given passwordless sudo access."
Loading