diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..57a897c --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,31 @@ +name: Build and Release Workspace + +on: + push: + tags: + - 'v*' # Trigger automatically when you push a tag like "v1.0.0" + workflow_dispatch: # Allow manual triggers from the Gitea UI + +jobs: + release: + name: Create Release + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Package Workspace Files + run: | + echo "Zipping template files..." + zip workspace.zip main.tf README.md Dockerfile + + - name: Create Gitea Release and Upload Asset + uses: softprops/action-gh-release@v2 + with: + files: workspace.zip + fail_on_unmatched_files: true + generate_release_notes: true + env: + # Gitea Actions injects a compatible token automatically + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7d8a538 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM codercom/enterprise-base:ubuntu + +USER root + +# 1. Update system packages and install dependencies +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y curl wget git sudo zip unzip golang && \ + rm -rf /var/lib/apt/lists/* + +# 2. Install Docker CLI +RUN curl -fsSL https://get.docker.com | sh + +USER coder + +# 3. Install Bun +RUN curl -fsSL https://bun.sh/install | bash + +# 4. Install SDKMAN! and Maven +RUN curl -s "https://get.sdkman.io" | bash && \ + bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && sdk install maven" + +# Add tools to path +ENV PATH="/home/coder/.bun/bin:${PATH}" diff --git a/README.md b/README.md index e2d4ccd..355d041 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ tags: [docker, container, gpu, golang, bun, sdkman] # Feature-Rich Docker Workspaces -Provision powerful Docker containers as [Coder workspaces](https://coder.com/docs/workspaces) with this advanced template. It features GPU passthrough, Docker-out-of-Docker (DooD), and automatically installs essential development tools on startup. +Provision powerful Docker containers as [Coder workspaces](https://coder.com/docs/workspaces) with this advanced template. It features GPU passthrough, Docker-out-of-Docker (DooD), and pre-installs essential development tools via a custom Dockerfile. @@ -34,13 +34,12 @@ sudo -u coder docker ps This template provisions the following resources and features: -- **Base Image**: `codercom/enterprise-base:ubuntu` +- **Base Image**: Custom image built from `codercom/enterprise-base:ubuntu` - **GPU Support**: Passes all host GPUs to the workspace (`gpus = "all"`) for AI/ML and hardware acceleration. - **Docker-out-of-Docker (DooD)**: Mounts the host's `/var/run/docker.sock` so you can build and run containers seamlessly from inside your workspace. -- **Auto-Provisioned Tools**: The workspace startup script automatically handles: - - System package updates (`apt-get update` & `apt-get upgrade`) +- **Pre-baked Tools**: The custom Docker image comes pre-installed with: + - System package updates - Docker CLI - - Nixpacks - Bun - Golang - SDKMAN! & Maven @@ -49,4 +48,4 @@ This template provisions the following resources and features: - **IDE Support**: Native integration with code-server (Browser VS Code) and JetBrains IDEs. > **Note** -> While your `/home/coder` directory is persistent, the container's root filesystem is ephemeral. The startup script handles reinstalling your system-level tools (Go, Bun, SDKMAN!, etc.) on each start. To speed up boot times, you may want to bake these tools into a custom Docker image. +> While your `/home/coder` directory is persistent, the container's root filesystem is ephemeral. This template builds a custom Docker image to pre-bake tools (Go, Bun, SDKMAN!, etc.), ensuring your workspace starts instantly while keeping the tools available. diff --git a/main.tf b/main.tf index ea952f1..d0fe7f9 100644 --- a/main.tf +++ b/main.tf @@ -32,57 +32,14 @@ resource "coder_agent" "main" { os = "linux" startup_script = <<-EOT set -e - - # 1. Standard Permissions Fix - sudo chown -R $(whoami) /home/coder - # 2. Install Docker CLI (client only) to talk to the socket - if ! command -v docker >/dev/null 2>&1; then - echo "Installing Docker CLI..." - curl -fsSL https://get.docker.com | sh - fi - - # 3. Allow user to use the Docker socket (Docker-out-of-Docker) + # 1. Allow user to use the Docker socket (Docker-out-of-Docker) # We set strict permissions on the socket file to ensure access if [ -e /var/run/docker.sock ]; then sudo chmod 666 /var/run/docker.sock fi - # 4. Install Nixpacks - if ! command -v nixpacks >/dev/null 2>&1; then - echo "Installing Nixpacks..." - curl -sSL https://nixpacks.com/install.sh | bash - fi - - # 5. Install Bun - if ! command -v bun >/dev/null 2>&1; then - echo "Installing Bun..." - curl -fsSL https://bun.sh/install | bash - fi - - # 6. Update System Packages - echo "Updating system packages..." - sudo apt-get update - sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y - - # 7. Install Golang - if ! command -v go >/dev/null 2>&1; then - echo "Installing Golang..." - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y golang zip unzip - fi - - # 8. Install SDKMAN! & Maven - if [ ! -d "$HOME/.sdkman" ]; then - echo "Installing SDKMAN!..." - export SDKMAN_DIR="$HOME/.sdkman" - curl -s "https://get.sdkman.io" | bash - - echo "Installing Maven via SDKMAN!..." - source "$HOME/.sdkman/bin/sdkman-init.sh" - sdk install maven - fi - - # 9. Initialize Home Directory + # 2. Initialize Home Directory if [ ! -f ~/.init_done ]; then cp -rT /etc/skel ~ touch ~/.init_done @@ -183,13 +140,28 @@ module "jetbrains" { tooltip = "You need to [install JetBrains Toolbox](https://coder.com/docs/user-guides/workspace-access/jetbrains/toolbox) to use this app." } +resource "docker_image" "workspace" { + name = "coder-${data.coder_workspace.me.id}" + build { + context = "." + dockerfile = "Dockerfile" + } + keep_locally = true +} + resource "docker_container" "workspace" { count = data.coder_workspace.me.start_count - image = "codercom/enterprise-base:ubuntu" + image = docker_image.workspace.name name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" hostname = data.coder_workspace.me.name - entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] + entrypoint = [ + "sh", "-c", + <