diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..f1c69b97 --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +S3_ACCESS_KEY_ID=XXXXXXXXXX +S3_SECRET_ACCESS_KEY=Xxxxxxxxxxxxxxxxxxxxxxxxxx +S3_BUCKET=code-server +S3_ENDPOINT=xxxxxx +S3_REGION=us-southeast-1 +GIT_USER_NAME=git +GIT_USER_EMAIL=git@localhost +TOKEN_NGROK=xxxxxxx +EXTENSIONS_RUNTIME=Vue.volar Vue.vscode-typescript-vue-plugin dbaeumer.vscode-eslint diff --git a/.gitignore b/.gitignore index 6e8ad977..5df90450 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ Network Trash Folder Temporary Items .apdisk .jenkins-external +.env diff --git a/Dockerfile b/Dockerfile index 50a3794b..b03abdc6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,48 +1,53 @@ FROM ghcr.io/linuxserver/baseimage-ubuntu:jammy -# set version label +# Set version label ARG BUILD_DATE ARG VERSION ARG CODE_RELEASE LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}" LABEL maintainer="aptalca" -# environment settings +# Environment settings ARG DEBIAN_FRONTEND="noninteractive" -ENV HOME="/config" +ENV HOME="/config" -RUN \ - echo "**** install runtime dependencies ****" && \ - apt-get update && \ - apt-get install -y \ - git \ - jq \ - libatomic1 \ - nano \ - net-tools \ - netcat \ - sudo && \ - echo "**** install code-server ****" && \ - if [ -z ${CODE_RELEASE+x} ]; then \ - CODE_RELEASE=$(curl -sX GET https://api.github.com/repos/coder/code-server/releases/latest \ - | awk '/tag_name/{print $4;exit}' FS='[""]' | sed 's|^v||'); \ - fi && \ - mkdir -p /app/code-server && \ - curl -o \ - /tmp/code-server.tar.gz -L \ - "https://github.com/coder/code-server/releases/download/v${CODE_RELEASE}/code-server-${CODE_RELEASE}-linux-amd64.tar.gz" && \ - tar xf /tmp/code-server.tar.gz -C \ - /app/code-server --strip-components=1 && \ - echo "**** clean up ****" && \ - apt-get clean && \ - rm -rf \ - /config/* \ - /tmp/* \ - /var/lib/apt/lists/* \ - /var/tmp/* +# Install dependencies and clean up in a single RUN command +RUN apt-get update && apt-get install -y \ + git openssh-client jq libatomic1 nano net-tools netcat sudo \ + ca-certificates curl gnupg s3fs \ + && mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \ + && chmod a+r /etc/apt/keyrings/docker.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \ + && apt-get update \ + && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin \ + && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y nodejs \ + && npm install -g yarn \ + && npx playwright install-deps \ + && npx playwright install webkit chromium \ + && if [ -z ${CODE_RELEASE+x} ]; then \ + CODE_RELEASE=$(curl -sX GET https://api.github.com/repos/coder/code-server/releases/latest | awk '/tag_name/{print $4;exit}' FS='[""]' | sed 's|^v||'); \ + fi \ + && mkdir -p /app/code-server \ + && curl -o /tmp/code-server.tar.gz -L "https://github.com/coder/code-server/releases/download/v${CODE_RELEASE}/code-server-${CODE_RELEASE}-linux-amd64.tar.gz" \ + && tar xf /tmp/code-server.tar.gz -C /app/code-server --strip-components=1 \ + && curl -o /tmp/ngrok.tgz -L "https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz" \ + && tar zxvf /tmp/ngrok.tgz -C /app \ + && curl -LO https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb \ + && dpkg -i cloudflared-linux-amd64.deb \ + && mkdir -p /temp/extensions \ + && /app/code-server/bin/code-server --extensions-dir /temp/extensions --install-extension ms-azuretools.vscode-docker \ + && /app/code-server/bin/code-server --extensions-dir /temp/extensions --install-extension IronGeek.vscode-env \ + && /app/code-server/bin/code-server --extensions-dir /temp/extensions --install-extension esbenp.prettier-vscode \ + && /app/code-server/bin/code-server --extensions-dir /temp/extensions --install-extension redhat.vscode-yaml \ + && /app/code-server/bin/code-server --extensions-dir /temp/extensions --install-extension nick-rudenko.back-n-forth \ + && /app/code-server/bin/code-server --extensions-dir /temp/extensions --install-extension humao.rest-client \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* "${HOME:?}"/* -# add local files +# Add local files COPY /root / -# ports and volumes +# Expose port EXPOSE 8443 diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 9502c20a..0baa06e8 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -36,7 +36,7 @@ RUN \ echo "**** clean up ****" && \ apt-get clean && \ rm -rf \ - /config/* \ + "${HOME:?}"/* \ /tmp/* \ /var/lib/apt/lists/* \ /var/tmp/* diff --git a/PUSH_DOCKER.md b/PUSH_DOCKER.md new file mode 100644 index 00000000..412eff3a --- /dev/null +++ b/PUSH_DOCKER.md @@ -0,0 +1,4 @@ +# Push image to the Docker registry +docker build -t erikvargas/code-server . +docker login -u erikvargas +docker push erikvargas/code-server diff --git a/README.md b/README.md index d4270a0d..e46a1557 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,8 @@ Containers are configured using parameters passed at runtime (such as those abov | `-e DEFAULT_WORKSPACE=/config/workspace` | If this optional variable is set, code-server will open this directory by default | | `-v /config` | Contains all relevant configuration files. | +The container uses `HOME=/config` by default for code-server data, extensions, workspace files, and shell configuration. If overriding `HOME` with `-e HOME=/some/path`, use an absolute path inside the container and mount persistent storage at that same path. + ## Environment variables from files (Docker secrets) You can set any environment variable from a file by using a special prepend `FILE__`. diff --git a/ai/project-overview.md b/ai/project-overview.md new file mode 100644 index 00000000..2d2b1b56 --- /dev/null +++ b/ai/project-overview.md @@ -0,0 +1,410 @@ +# Project Overview: code-server Docker Container + +## Quick Summary + +This repository builds a Docker container image for [code-server](https://coder.com) - Visual Studio Code running on a remote server accessible via web browser. + +**Status**: Active maintenance by LinuxServer.io team +**Base**: Ubuntu Jammy with s6-overlay process supervisor +**Application**: code-server (VS Code in browser) +**Port**: 8443 +**Architectures**: x86_64, ARM64 + +## What is code-server? + +code-server is VS Code running on a remote server, accessible through the browser. It allows developers to: +- Code on Chromebooks, tablets, and laptops with a consistent dev environment +- Develop for Linux more easily from Windows/Mac workstations +- Leverage large cloud servers for faster builds and tests +- Preserve battery life on laptops +- Run intensive computations on the server instead of local machine + +## Project Structure + +``` +./ +├── Dockerfile # Main build configuration (x86_64) +├── Dockerfile.aarch64 # ARM64 build configuration +├── docker-compose.yml # Development configuration +├── README.md # Official documentation +├── Jenkinsfile # CI/CD pipeline +├── .env.example # Environment variable examples +├── root/ # Files copied into container image +│ ├── etc/s6-overlay/ # Service definitions +│ │ └── s6-rc.d/ +│ │ ├── svc-code-server/run # Main service +│ │ └── init-code-server/run # Init service +│ └── usr/local/bin/install-extension # Extension installer +└── .github/workflows/ # GitHub Actions +``` + +## Key Components + +### 1. Docker Image Structure +- **Base Image**: `ghcr.io/linuxserver/baseimage-ubuntu:jammy` +- **Process Supervisor**: s6-overlay (for reliable service management) +- **Application**: code-server (VS Code in browser) +- **User**: Runs as user `abc` (UID 1000) by default +- **Home Directory**: `/config` + +### 2. Service Architecture (s6-overlay) + +Two main services: + +**init-code-server** (runs first): +- Sets up authentication +- Configures S3 workspace if enabled +- Prepares environment variables + +**svc-code-server** (main service): +- Binds to `0.0.0.0:8443` +- Uses `/config` for all persistent data +- Supports multiple authentication modes +- Disables telemetry by default + +### 3. Installed Components + +**Build Tools:** +- Node.js 22.x +- yarn +- npm +- Playwright (for browser automation) +- Docker CLI and Docker Compose plugin + +**Pre-installed Extensions:** +- ms-azuretools.vscode-docker +- IronGeek.vscode-env +- esbenp.prettier-vscode +- redhat.vscode-yaml +- nick-rudenko.back-n-forth +- humao.rest-client + +**Utilities:** +- git, openssh-client, jq +- nano, sudo, curl, wget +- s3fs (for S3 integration) +- ngrok (for tunneling) +- cloudflared (for Cloudflare Tunnel) + +## Environment Variables + +### Core Configuration +| Variable | Purpose | Example | +|----------|---------|---------| +| `PUID` | User ID for file permissions | `1000` | +| `PGID` | Group ID for file permissions | `1000` | +| `TZ` | Timezone | `Etc/UTC` | + +### Authentication +| Variable | Purpose | Example | +|----------|---------|---------| +| `PASSWORD` | Plain text password | `mypassword` | +| `HASHED_PASSWORD` | Hashed password (overrides PASSWORD) | `$2a$10$...` | +| `SUDO_PASSWORD` | Password for sudo in terminal | `mypassword` | +| `SUDO_PASSWORD_HASH` | Hashed sudo password | `$2a$10$...` | + +### Workspace & Networking +| Variable | Purpose | Example | +|----------|---------|---------| +| `DEFAULT_WORKSPACE` | Default workspace directory | `/config/workspace` | +| `PROXY_DOMAIN` | Domain for subdomain proxying | `code-server.my.domain` | + +### S3 Integration (Optional) +When these are set, code-server creates a default workspace that mounts S3: +| Variable | Purpose | Example | +|----------|---------|---------| +| `S3_ACCESS_KEY_ID` | AWS/S3 access key | `AKIA...` | +| `S3_SECRET_ACCESS_KEY` | AWS/S3 secret key | `secret...` | +| `S3_BUCKET` | S3 bucket name | `code-server` | +| `S3_ENDPOINT` | S3 endpoint URL | `s3.amazonaws.com` | +| `S3_REGION` | S3 region | `us-east-1` | + +### Git Configuration +| Variable | Purpose | Example | +|----------|---------|---------| +| `GIT_USER_NAME` | Git username | `John Doe` | +| `GIT_USER_EMAIL` | Git email | `john@example.com` | + +### Cloud Services +| Variable | Purpose | Example | +|----------|---------|---------| +| `TOKEN_NGROK` | ngrok authentication token | `12345abcde` | +| `EXTENSIONS_RUNTIME` | Extensions to install at runtime | `Vue.volar dbaeumer.vscode-eslint` | + +## Build & Deployment + +### Building the Image + +**Standard (x86_64):** +```bash +docker build --no-cache --pull -t lscr.io/linuxserver/code-server:latest . +``` + +**ARM64:** +```bash +# Register QEMU first +docker run --rm --privileged multiarch/qemu-user-static:register --reset + +# Then build +docker build --no-cache --pull -t lscr.io/linuxserver/code-server:latest -f Dockerfile.aarch64 . +``` + +**With specific version:** +```bash +docker build --build-arg CODE_RELEASE=4.24.0 -t lscr.io/linuxserver/code-server:4.24.0 . +``` + +### Running the Container + +**Basic:** +```bash +docker run -d \ + --name=code-server \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -p 8443:8443 \ + -v /path/to/config:/config \ + lscr.io/linuxserver/code-server:latest +``` + +**With authentication:** +```bash +docker run -d \ + --name=code-server \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e PASSWORD=mysecurepassword \ + -p 8443:8443 \ + -v /path/to/config:/config \ + lscr.io/linuxserver/code-server:latest +``` + +**With S3 workspace:** +```bash +docker run -d \ + --name=code-server \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e S3_ACCESS_KEY_ID=AKIA... \ + -e S3_SECRET_ACCESS_KEY=secret... \ + -e S3_BUCKET=my-bucket \ + -e S3_ENDPOINT=s3.amazonaws.com \ + -e S3_REGION=us-east-1 \ + -p 8443:8443 \ + -v /path/to/config:/config \ + lscr.io/linuxserver/code-server:latest +``` + +## Development Workflow + +### 1. Clone the Repository +```bash +git clone https://github.com/linuxserver/docker-code-server.git +cd docker-code-server +``` + +### 2. Make Changes +- Modify `Dockerfile` for new packages/extensions +- Update service definitions in `root/etc/s6-overlay/s6-rc.d/` +- Test locally with `docker-compose up --build` + +### 3. Test Your Changes +```bash +# Build and run +docker-compose up --build + +# Access at http://localhost:8443 + +# Shell into container +docker exec -it code-server /bin/bash + +# View logs +docker logs -f code-server +``` + +### 4. Install Extensions at Runtime +```bash +# Install via helper script +docker exec -it code-server install-extension ms-python.python + +# Or via code-server CLI +docker exec -it code-server /app/code-server/bin/code-server --extensions-dir /config/extensions --install-extension ms-python.python +``` + +## Key Files to Understand + +### Dockerfile (lines 1-47) +**What it does:** +- Sets up base Ubuntu Jammy image +- Installs all dependencies (apt packages, Node.js, Docker CLI) +- Downloads and configures code-server +- Installs extensions at build time +- Cleans up apt cache + +**Key sections:** +- Lines 15-28: Package installation +- Lines 29-34: code-server download and extraction +- Lines 40-45: Extension installation + +### svc-code-server/run (root/etc/s6-overlay/s6-rc.d/svc-code-server/run) +**What it does:** +- Defines the main code-server service +- Configures authentication +- Sets up workspace +- Starts code-server with proper arguments + +**Key settings:** +- `--bind-addr 0.0.0.0:8443` - Makes it accessible from outside container +- `--user-data-dir /config/data` - Persistent user data +- `--extensions-dir /config/extensions` - Persistent extensions +- `--auth` - Authentication mode (password/none) + +### install-extension (root/usr/local/bin/install-extension) +**What it does:** +- Helper script for installing extensions at runtime +- Runs as the correct user (abc) +- Usage: `install-extension extension-name@version` + +## CI/CD Pipeline + +**Platform**: Jenkins (managed by LinuxServer.io team) + +**Pipeline Stages:** +1. **Build**: Creates Docker images for x86_64 and ARM64 +2. **Test**: Validates the build works correctly +3. **Publish**: Pushes images to: + - Docker Hub: `lscr.io/linuxserver/code-server` + - GitHub Container Registry + - Quay.io +4. **Cleanup**: Removes old images + +**Build Frequency**: Weekly base OS updates, plus updates when code-server releases new versions + +## Common Use Cases + +### 1. Personal Development Environment +```bash +docker run -d \ + --name=code-server \ + -e PUID=$(id -u) \ + -e PGID=$(id -g) \ + -e TZ=America/New_York \ + -e PASSWORD=mysecurepassword \ + -e DEFAULT_WORKSPACE=/config/workspace \ + -p 8443:8443 \ + -v ~/code-server-config:/config \ + lscr.io/linuxserver/code-server:latest +``` + +### 2. Team Development Server +```bash +docker run -d \ + --name=code-server \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=UTC \ + -e HASHED_PASSWORD='$2a$10$...' \ + -e PROXY_DOMAIN=code.company.com \ + -p 8443:8443 \ + -v /mnt/shared/config:/config \ + --restart unless-stopped \ + lscr.io/linuxserver/code-server:latest +``` + +### 3. Cloud Development with S3 Storage +```bash +docker run -d \ + --name=code-server \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=UTC \ + -e S3_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ + -e S3_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ + -e S3_BUCKET=dev-bucket \ + -e S3_ENDPOINT=s3.us-east-1.amazonaws.com \ + -e S3_REGION=us-east-1 \ + -e GIT_USER_NAME="Dev Team" \ + -e GIT_USER_EMAIL="dev@company.com" \ + -p 8443:8443 \ + -v /mnt/code-server:/config \ + --restart unless-stopped \ + lscr.io/linuxserver/code-server:latest +``` + +## Troubleshooting + +### Can't access web UI +**Check:** +- Container is running: `docker ps` +- Port is mapped: `docker port code-server` should show `8443/tcp -> 0.0.0.0:8443` +- No firewall blocking port 8443 +- Try `http://localhost:8443` or `http://:8443` + +### Authentication not working +**Check:** +- If using password, ensure `PASSWORD` or `HASHED_PASSWORD` is set +- If using no auth, ensure neither is set +- Hashed passwords must be properly formatted (use code-server's hashing tool) + +### Extensions missing +**Check:** +- Extensions directory exists: `/config/extensions` +- Correct permissions: owned by user abc (UID 1000) +- Try installing via `install-extension` script + +### Slow startup with large workspace +**Note:** Workspace directory contents are NOT chowned during startup (performance optimization) + +### Permission issues +**Solution:** Use `PUID` and `PGID` environment variables to match your host user + +## Version Management + +**code-server versions** are tracked in the Dockerfile and can be updated by: +1. Setting `CODE_RELEASE` build arg +2. Or letting the Dockerfile auto-detect latest via GitHub API + +**Container image versions** follow the pattern: `YYYY.MM.DD` + +## Security Considerations + +- **Authentication**: Always set a password or hashed password for production +- **File Permissions**: Use `PUID`/`PGID` to match host user +- **Sensitive Data**: Use Docker secrets or environment files for credentials +- **SSH Keys**: Mount to `/config/.ssh` for GitHub integration +- **Network**: Bind to specific IP if not using 0.0.0.0 + +## Performance Tips + +- Use SSD storage for `/config` volume +- Allocate sufficient memory (code-server can use 1GB+) +- Consider CPU limits for shared environments +- Disable telemetry: `--disable-telemetry` flag in service definition + +## Resources & Links + +- **code-server**: https://coder.com / https://github.com/coder/code-server +- **s6-overlay**: https://github.com/just-containers/s6-overlay +- **LinuxServer.io**: https://linuxserver.io +- **Docker Multi-arch**: https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md +- **VS Code Extensions**: https://marketplace.visualstudio.com/vscode + +## Quick Reference + +| Task | Command | +|------|---------| +| Build image | `docker build -t my-code-server .` | +| Run container | `docker run -d -p 8443:8443 -v /config:/config my-code-server` | +| Shell access | `docker exec -it code-server /bin/bash` | +| View logs | `docker logs -f code-server` | +| Install extension | `docker exec -it code-server install-extension ms-python.python` | +| Update image | `docker pull lscr.io/linuxserver/code-server:latest` | + +--- + +**Last Updated**: May 2026 +**Maintainer**: LinuxServer.io team +**License**: OSS (see LICENSE file) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..2c39beab --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,56 @@ +version: "2.1" +services: + code-server: + privileged: true + build: + context: ./ + dockerfile: Dockerfile + # image: lscr.io/linuxserver/code-server:latest + container_name: code-server + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + - PASSWORD=password #optional + - HASHED_PASSWORD= #optional + - SUDO_PASSWORD=password #optional + - SUDO_PASSWORD_HASH= #optional + - PROXY_DOMAIN=code-server.my.domain #optional + - S3_ACCESS_KEY_ID=${S3_ACCESS_KEY_ID} + - S3_SECRET_ACCESS_KEY=${S3_SECRET_ACCESS_KEY} + - S3_BUCKET=code-server + - S3_ENDPOINT=${S3_ENDPOINT} + - S3_REGION=${S3_REGION} + - GIT_USER_NAME=${GIT_USER_NAME} + - GIT_USER_EMAIL=${GIT_USER_EMAIL} + - CODE_FOLDER_DIR=/mnt/s3 + - TOKEN_NGROK=${TOKEN_NGROK} + - DISPLAY=bdd-ui:0.0 + # - HTTPS_PORTS=3000,8000 + - EXTENSIONS_RUNTIME=${EXTENSIONS_RUNTIME} + devices: + - "/dev/fuse" + security_opt: + # - apparmor:unconfined + - "apparmor=unconfined" + volumes: + # - /path/to/appdata/config:/config + - ./root/etc/s6-overlay/s6-rc.d/init-code-server/run:/etc/s6-overlay/s6-rc.d/init-code-server/run + - ./root/usr/local/bin/install-extension:/usr/local/bin/install-extension + - ./root/etc/s6-overlay/s6-rc.d/svc-code-server/run:/etc/s6-overlay/s6-rc.d/svc-code-server/run + - /var/run/docker.sock:/var/run/docker.sock + ports: + - 8443:8443 + # - 8000:8000 + # depends_on: + # - bdd-ui + + # bdd-ui: + # image: theasp/novnc:latest + # environment: + # # Adjust to your screen size + # - DISPLAY_WIDTH=1920 + # - DISPLAY_HEIGHT=1200 + # - RUN_XTERM=no + # ports: + # - "8080:8080" diff --git a/root/etc/s6-overlay/s6-rc.d/init-code-server/run b/root/etc/s6-overlay/s6-rc.d/init-code-server/run index d93a4d26..d01f2e90 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-code-server/run +++ b/root/etc/s6-overlay/s6-rc.d/init-code-server/run @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -mkdir -p /config/{extensions,data,workspace,.ssh} +mkdir -p "${HOME}"/{extensions,data,workspace,.ssh} if [ -n "${SUDO_PASSWORD}" ] || [ -n "${SUDO_PASSWORD_HASH}" ]; then echo "setting up sudo access" @@ -17,15 +17,127 @@ if [ -n "${SUDO_PASSWORD}" ] || [ -n "${SUDO_PASSWORD_HASH}" ]; then fi fi -[[ ! -f /config/.bashrc ]] && \ - cp /root/.bashrc /config/.bashrc -[[ ! -f /config/.profile ]] && \ - cp /root/.profile /config/.profile - -# fix permissions (ignore contents of /config/workspace) -find /config -path /config/workspace -prune -o -exec chown abc:abc {} + -chown abc:abc /config/workspace -chmod 700 /config/.ssh -if [ -n "$(ls -A /config/.ssh)" ]; then - chmod 600 /config/.ssh/* +[[ ! -f "${HOME}/.bashrc" ]] && \ + cp /root/.bashrc "${HOME}/.bashrc" +[[ ! -f "${HOME}/.profile" ]] && \ + cp /root/.profile "${HOME}/.profile" + +# fix permissions (ignore contents of ${HOME}/workspace) +find "${HOME}" -path "${HOME}/workspace" -prune -o -exec chown abc:abc {} + +chown abc:abc "${HOME}/workspace" +chmod 700 "${HOME}/.ssh" +if [ -n "$(ls -A "${HOME}/.ssh")" ]; then + chmod 600 "${HOME}"/.ssh/* +fi + +if [ -n "${GIT_USER_NAME}" ]; then + git config --global user.name "${GIT_USER_NAME}" + git config --global user.email "${GIT_USER_EMAIL}" +fi + +# echo $S3_ACCESS_KEY_ID:$S3_SECRET_ACCESS_KEY > /etc/passwd-s3fs +# chmod 600 /etc/passwd-s3fs +if [ -n "${S3_ACCESS_KEY_ID}" ]; then + echo $S3_ACCESS_KEY_ID:$S3_SECRET_ACCESS_KEY > "${HOME}/.passwd-s3fs" + chmod 600 "${HOME}/.passwd-s3fs" + mkdir /mnt/s3 + mkdir -p /tmp/s3cache + chmod 777 /tmp/s3cache + s3_region_opt=() + if [ -n "${S3_REGION}" ]; then + s3_region_opt=(-o endpoint=${S3_REGION}) + fi + s3fs ${S3_BUCKET} /mnt/s3 -o passwd_file="${HOME}/.passwd-s3fs" -o url=${S3_ENDPOINT} "${s3_region_opt[@]}" -o use_path_request_style -o uid=1000 -o gid=1000 -o umask=0002 -o allow_other -o mp_umask=0002 -o multireq_max=5 -o use_cache=/tmp/s3cache -o nonempty -o use_xattr -o enable_noobj_cache -o parallel_count=15 -o multipart_size=64 -o max_stat_cache_size=100000 -o enable_noobj_cache #-o dbglevel=info -o curldbg + + # add SSH file + + read_count=3 + interval_time=5 + ssh_file="/mnt/s3/.ssh/id_ed25519" + for((i=1;i<=$read_count;i++)) + do + if [ -f "$ssh_file" ]; then + echo "ssh file exist ***" + # eval "$(ssh-agent -s)" + cp "$ssh_file" "${HOME}/.ssh/" + chown abc:abc "${HOME}/.ssh" + chmod 600 "${HOME}/.ssh/id_ed25519" + # ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts + # ssh-add "${HOME}/.ssh/id_ed25519" + # ssh -T git@github.com + + echo 'eval "$(ssh-agent -s)"' >> "${HOME}/.bashrc" + echo "ssh-add ${HOME}/.ssh/id_ed25519" >> "${HOME}/.bashrc" + echo 'export SSH_PRIVATE_KEY="$(cat /mnt/s3/.ssh/id_ed25519)"' >> "${HOME}/.bashrc" + + # cat "${HOME}/.ssh/id_ed25519" | tr -d '\r' | ssh-add - > /dev/null + # ssh-keyscan github.com >> "${HOME}/.ssh/known_hosts" + # ssh-add "${HOME}/.ssh/id_ed25519" + # ssh-keyscan -t rsa github.com >> "${HOME}/.ssh/known_hosts" + # ssh -T git@github.com + if [ -f "/mnt/s3/init-code-server.sh" ]; then + echo "init-code-server.sh exist ***" + chmod +x /mnt/s3/init-code-server.sh + /mnt/s3/init-code-server.sh + fi + break + else + echo "ssh file not exist, wait $interval_time seconds" + sleep $interval_time + fi + done +fi + +# echo "installing extensions***" +# /app/code-server/bin/code-server --extensions-dir "${HOME}/extensions" --install-extension IronGeek.vscode-env +mv -v /temp/extensions/* "${HOME}/extensions/" + +CODE_BIN=/app/code-server/bin/code-server +EXT_DIR="${HOME}/extensions" +echo "[init-extensions] Starting runtime extension installation..." >&2 +install_one() { + i=0; until [ $i -ge 3 ]; do + if "$CODE_BIN" --extensions-dir "$EXT_DIR" --install-extension "$1"; then + echo "[init-extensions] Installed $1" >&2 + return 0 + fi + i=$((i+1)); sleep $((2**i)) + done + echo "[init-extensions] Failed to install $1" >&2 +} +echo "[init-extensions] Extensions to install: $EXTENSIONS_RUNTIME" >&2 +for ext in $EXTENSIONS_RUNTIME; do + [ -n "$ext" ] && install_one "$ext" +done +echo "[init-extensions] Finished runtime extension installation." >&2 + + +if [ -n "${TOKEN_NGROK}" ]; then + echo "starting ngrok" + /app/ngrok config add-authtoken ${TOKEN_NGROK} + mkdir -p /app/logs + /app/ngrok http --log=stdout 3000 > /app/logs/ngrok.log & + sleep 7 + grep "started tunnel" /app/logs/ngrok.log | awk '{print $NF}' > "${HOME}/workspace/https_url.txt" +fi + +# expose PORTS with cloudflare +IFS=',' read -ra PORTS <<< "${HTTPS_PORTS:-8443}" +for port in "${PORTS[@]}"; do + cloudflared tunnel --url http://localhost:$port --logfile /app/logs/cloudflared_$port.log & +done + +# Wait for the tunnels to be established and extract the URLs +sleep 7 +for port in "${PORTS[@]}"; do + cf_url=$(grep -oE 'https://[a-zA-Z0-9.-]+\.trycloudflare\.com' /app/logs/cloudflared_$port.log | head -n 1) + if [ -n "$cf_url" ]; then + echo "# PORT $port" >> "${HOME}/workspace/https_url.txt" + echo "$cf_url" >> "${HOME}/workspace/https_url.txt" + fi +done + +welcome_message='echo "Welcome to code-server terminal! power by Erik Vargas"' +if ! grep -Fxq "$welcome_message" "${HOME}/.bashrc"; then + echo "$welcome_message" >> "${HOME}/.bashrc" fi diff --git a/root/etc/s6-overlay/s6-rc.d/svc-code-server/run b/root/etc/s6-overlay/s6-rc.d/svc-code-server/run index 373dc0af..a86d5641 100755 --- a/root/etc/s6-overlay/s6-rc.d/svc-code-server/run +++ b/root/etc/s6-overlay/s6-rc.d/svc-code-server/run @@ -13,14 +13,22 @@ else PROXY_DOMAIN_ARG="--proxy-domain=${PROXY_DOMAIN}" fi +if [ -n "${S3_ACCESS_KEY_ID}" ]; then + printf '{"folders": [ {"path": "%s/workspace"}, {"path": "/mnt/s3"} ]}\n' "${HOME}" > "${HOME}/default.code-workspace" + chmod 600 "${HOME}/default.code-workspace" + DEFAULT_WORKSPACE2="${HOME}/default.code-workspace" +else + DEFAULT_WORKSPACE2=${DEFAULT_WORKSPACE} +fi + exec \ s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z 127.0.0.1 8443" \ - s6-setuidgid abc \ + s6-setuidgid root \ /app/code-server/bin/code-server \ --bind-addr 0.0.0.0:8443 \ - --user-data-dir /config/data \ - --extensions-dir /config/extensions \ + --user-data-dir "${HOME}/data" \ + --extensions-dir "${HOME}/extensions" \ --disable-telemetry \ --auth "${AUTH}" \ "${PROXY_DOMAIN_ARG}" \ - "${DEFAULT_WORKSPACE:-/config/workspace}" + "${DEFAULT_WORKSPACE2:-${HOME}/workspace}" diff --git a/root/usr/local/bin/install-extension b/root/usr/local/bin/install-extension index 79c922a6..6a6e6eeb 100755 --- a/root/usr/local/bin/install-extension +++ b/root/usr/local/bin/install-extension @@ -1,7 +1,7 @@ #!/usr/bin/with-contenv bash # shellcheck shell=bash -_install=(/app/code-server/bin/code-server "--extensions-dir" "/config/extensions" "--install-extension") +_install=(/app/code-server/bin/code-server "--extensions-dir" "${HOME}/extensions" "--install-extension") if [ "$(whoami)" == "abc" ]; then "${_install[@]}" "$@"