├── .devcontainer.json ├── .gitignore ├── LICENSE.txt ├── README.md ├── customizations └── plugins │ └── .devcontainer.json ├── demoApps ├── python-webserver │ ├── Dockerfile │ └── app.py └── static │ ├── Dockerfile │ ├── docker-compose.yml │ └── html │ ├── index.css │ ├── index.html │ └── index.js ├── enablingJavaAsyncProfiler └── devcontainer.json ├── gpu_amd64 ├── .devcontainer.json └── Dockerfile ├── minimalOS ├── almalinux │ └── .devcontainer.json ├── alpine │ └── .devcontainer.json ├── archlinux_amd64 │ └── .devcontainer.json ├── archlinux_arm64 │ └── .devcontainer.json ├── clearlinux_amd64 │ └── .devcontainer.json ├── debian │ └── .devcontainer.json ├── fedora │ └── .devcontainer.json ├── gentoo │ └── .devcontainer.json ├── kalilinux │ └── .devcontainer.json ├── manjaro │ └── .devcontainer.json ├── opensuse │ └── .devcontainer.json ├── oraclelinux │ └── .devcontainer.json ├── rockylinux │ └── .devcontainer.json └── ubuntu │ └── .devcontainer.json └── specification ├── 1-spec_forwardPorts └── .devcontainer.json ├── 1_1-spec_portsAttributes └── .devcontainer.json ├── 1_10-spec_shutdownAction └── .devcontainer.json ├── 1_11-spec_init └── .devcontainer.json ├── 1_12-spec_privileged └── .devcontainer.json ├── 1_13-spec_capAdd └── .devcontainer.json ├── 1_14-spec_securityOpt └── .devcontainer.json ├── 1_15-spec_mounts └── .devcontainer.json ├── 1_16-spec_features └── .devcontainer.json ├── 1_17-spec_overrideFeatureInstallOrder └── .devcontainer.json ├── 1_18-spec_customizations └── .devcontainer.json ├── 1_19-spec_workspaceFolder └── .devcontainer.json ├── 1_2-spec_otherPortsAttributes └── .devcontainer.json ├── 1_20-spec_workspaceMount └── .devcontainer.json ├── 1_21-spec_runArgs └── .devcontainer.json ├── 1_22-spec_hostRequirements └── .devcontainer.json ├── 1_3-spec_containerEnv └── .devcontainer.json ├── 1_4-spec_remoteEnv └── .devcontainer.json ├── 1_5-spec_remoteUser ├── .devcontainer.json └── Dockerfile ├── 1_6-spec_containerUser ├── .devcontainer.json └── Dockerfile ├── 1_7-spec_updateRemoteUserUID ├── .devcontainer.json └── Dockerfile ├── 1_8-spec_userEnvProbe └── .devcontainer.json ├── 1_9-spec_overrideCommand_false ├── .devcontainer.json └── Dockerfile ├── 1_9-spec_overrideCommand_true ├── .devcontainer.json └── Dockerfile ├── 2-compose └── .devcontainer.json ├── spec-lifecycle_initializeCommand └── .devcontainer.json ├── spec-lifecycle_onCreateCommand └── .devcontainer.json ├── spec-lifecycle_postStartCommand └── .devcontainer.json ├── spec-lifecycle_updateContentCommand └── .devcontainer.json ├── spec-lifecycle_waitFor └── .devcontainer.json ├── spec_lifecycle_postAttachCommand └── .devcontainer.json └── spec_lifecycle_postCreateCommand └── .devcontainer.json /.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_ubuntu", 3 | "image": "ubuntu:latest", 4 | "onCreateCommand": { 5 | "update": "apt update && apt -y upgrade", 6 | "installDependencies": "apt install -y git" 7 | }, 8 | "customizations": { 9 | "jetbrains" : { 10 | 11 | }, 12 | "settings": { 13 | },"backend": "IntelliJ"}, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | **/.idea/ 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020-2021 JetBrains s.r.o. and and respective authors and developers. 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![team project](http://jb.gg/badges/team.svg)](https://github.com/JetBrains#jetbrains-on-github) 2 | [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) 3 | 4 | # DevContainers Examples 5 | 6 | A comprehensive collection of examples demonstrating how to use DevContainers with JetBrains IDEs. 7 | 8 | ## Table of Contents 9 | 10 | - [Overview](#overview) 11 | - [What are DevContainers?](#what-are-devcontainers) 12 | - [Benefits of DevContainers](#benefits-of-devcontainers) 13 | - [Repository Structure](#repository-structure) 14 | - [Getting Started](#getting-started) 15 | - [Prerequisites](#prerequisites) 16 | - [Installation](#installation) 17 | - [Usage](#usage) 18 | - [Examples](#examples) 19 | - [Minimal OS Examples](#minimal-os-examples) 20 | - [Specification Examples](#specification-examples) 21 | - [Demo Applications](#demo-applications) 22 | - [Customizations](#customizations) 23 | - [GPU Support](#gpu-support) 24 | - [Troubleshooting](#troubleshooting) 25 | - [Contributing](#contributing) 26 | - [License](#license) 27 | 28 | ## Overview 29 | 30 | This repository provides a collection of examples and templates for using DevContainers with JetBrains IDEs. It demonstrates various configurations, features, and use cases to help developers quickly set up reproducible development environments. 31 | 32 | ## What are DevContainers? 33 | 34 | DevContainers (Development Containers) are a technology that allows developers to package a fully functional development environment inside containers. This approach ensures that all team members work with identical development environments, regardless of their local setup. 35 | 36 | The DevContainers approach enables: 37 | 38 | - Running applications in isolated environments 39 | - Using IDEs and development tools consistently across the team 40 | - Managing appropriate versions of libraries and dependencies 41 | - Configuring runtimes required by specific codebases and projects 42 | - Simplifying onboarding for new team members 43 | - Utilizing remote development capabilities on servers with Docker and necessary hardware 44 | 45 | ## Benefits of DevContainers 46 | 47 | - **Consistency**: Everyone on the team works with the same environment, eliminating "it works on my machine" problems 48 | - **Efficiency**: Significantly reduces time spent setting up development environments 49 | - **Onboarding**: New team members can start contributing quickly without extensive environment setup 50 | - **Isolation**: Projects with different dependencies can coexist without conflicts 51 | - **Portability**: Development environments can be easily moved between machines 52 | - **Reproducibility**: Environments can be recreated exactly as needed for debugging or testing 53 | 54 | JetBrains IDEs provide built-in support for DevContainers, allowing you to: 55 | - Use pre-configured environments with required dependencies 56 | - Create and customize your own DevContainers 57 | - Access source code without manual uploading (via source mounting or creating a DevContainer from a repository over SSH) 58 | - Enjoy the same developer experience as when working locally, thanks to Remote Development technology 59 | 60 | ## Repository Structure 61 | 62 | This repository is organized into several main directories: 63 | 64 | - **`minimalOS/`**: Contains minimal DevContainer configurations for various operating systems 65 | - **`specification/`**: Demonstrates different DevContainer specification options and features 66 | - **`demoApps/`**: Contains sample applications configured to run in DevContainers 67 | - **`customizations/`**: Shows how to customize DevContainers with plugins and extensions 68 | - **`gpu_amd64/`**: Provides examples for GPU support in DevContainers 69 | 70 | ## Getting Started 71 | 72 | ### Prerequisites 73 | 74 | - Docker installed on your local machine 75 | - A JetBrains IDE with DevContainers support (IntelliJ IDEA, PyCharm, WebStorm, etc.) 76 | - [JetBrains DevContainers Plugin](https://plugins.jetbrains.com/plugin/21962-dev-containers) 77 | 78 | ### Installation 79 | 80 | 1. Clone this repository: 81 | ```bash 82 | git clone https://github.com/JetBrains/devcontainers-examples.git 83 | cd devcontainers-examples 84 | ``` 85 | 86 | 2. Install the DevContainers plugin in your JetBrains IDE: 87 | - Go to Settings/Preferences > Plugins 88 | - Search for "Dev Containers" 89 | - Install the plugin and restart your IDE 90 | 91 | ### Usage 92 | 93 | The DevContainer configuration is defined in a `devcontainer.json` file, which can be located in one of the following paths: 94 | 95 | - `.devcontainer/devcontainer.json` 96 | - `.devcontainer.json` 97 | - `.devcontainer//devcontainer.json` (where `` is a sub-folder, one level deep) 98 | 99 | To build and run a DevContainer: 100 | 101 | 1. Open your project in a JetBrains IDE 102 | 2. The IDE will detect the DevContainer configuration and prompt you to reopen the project in a container 103 | 3. Click "Reopen in Container" to start the container build process 104 | 4. Once the container is built, your IDE will connect to it and you can start working 105 | 106 | For detailed instructions, refer to the [official JetBrains documentation](https://www.jetbrains.com/help/idea/connect-to-devcontainer.html#start_from_gateway). 107 | 108 | ## Examples 109 | 110 | ### Minimal OS Examples 111 | 112 | The `minimalOS/` directory contains examples for various Linux distributions: 113 | 114 | - Alpine 115 | - Ubuntu 116 | - Debian 117 | - Fedora 118 | - AlmaLinux 119 | - ArchLinux (AMD64 and ARM64) 120 | - ClearLinux 121 | - Gentoo 122 | - Kali Linux 123 | - Manjaro 124 | - openSUSE 125 | - Oracle Linux 126 | - Rocky Linux 127 | 128 | These examples provide a minimal setup for each operating system with the necessary dependencies for DevContainers. 129 | 130 | ### Specification Examples 131 | 132 | The `specification/` directory contains examples demonstrating various DevContainer specification options: 133 | 134 | - Port forwarding and attributes 135 | - Environment variables 136 | - User configuration 137 | - Command overrides 138 | - Security options 139 | - Mounts and volumes 140 | - Features and customizations 141 | - Workspace configuration 142 | - Lifecycle hooks 143 | - Docker Compose integration 144 | 145 | ### Demo Applications 146 | 147 | The `demoApps/` directory contains sample applications configured to run in DevContainers: 148 | 149 | - `python-webserver/`: A Python web server example 150 | - `static/`: A static website example 151 | 152 | ### Customizations 153 | 154 | The `customizations/` directory demonstrates how to customize DevContainers: 155 | 156 | - `plugins/`: Examples of configuring IDE plugins in DevContainers 157 | 158 | ### GPU Support 159 | 160 | The `gpu_amd64/` directory provides examples for using GPUs in DevContainers. 161 | 162 | ## Troubleshooting 163 | 164 | If you encounter any issues, please click "Help" → "Submit a bug report…" in the IDE and describe the problem—we’ll do our best to help. 165 | 166 | ## Contributing 167 | 168 | Contributions to this repository are welcome! If you have an example or improvement to share, please submit a pull request. 169 | 170 | ## License 171 | 172 | This project is licensed under the Apache License 2.0 - see the [LICENSE.txt](LICENSE.txt) file for details. 173 | 174 | Copyright 2025 JetBrains s.r.o. and respective authors and developers. 175 | -------------------------------------------------------------------------------- /customizations/plugins/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | // Example: install JetBrains IDE plugins in a dev-container with the 3 | // “customization” section. 4 | // 5 | // To find a plugin’s ID, open its JetBrains Marketplace page and look in 6 | // the “Additional Information” panel. 7 | // e.g. https://plugins.jetbrains.com/plugin/7808-terraform-and-hcl 8 | 9 | "name": "minimal_ubuntu", 10 | "image": "ubuntu:latest", 11 | "customizations": { 12 | "jetbrains": { 13 | "plugins": [ 14 | "org.intellij.plugins.hcl" 15 | ], 16 | }, 17 | } 18 | } -------------------------------------------------------------------------------- /demoApps/python-webserver/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.9-slim 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | git \ 5 | procps \ 6 | && rm -rf /var/lib/apt/lists/* 7 | 8 | RUN pip install flask 9 | 10 | COPY . /app 11 | WORKDIR /app 12 | 13 | CMD ["python", "app.py"] 14 | -------------------------------------------------------------------------------- /demoApps/python-webserver/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def hello_world(): 6 | return 'Hello, World!' 7 | 8 | if __name__ == '__main__': 9 | app.run(host='0.0.0.0', port=8080) 10 | -------------------------------------------------------------------------------- /demoApps/static/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | 3 | RUN apt-get update && apt-get install -y procps 4 | 5 | EXPOSE 80 6 | 7 | STOPSIGNAL SIGQUIT 8 | 9 | CMD ["nginx", "-g", "daemon off;"] 10 | -------------------------------------------------------------------------------- /demoApps/static/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | web: 3 | build: "." 4 | volumes: 5 | - ./html:/usr/share/nginx/html 6 | ports: 7 | - "80:80" 8 | -------------------------------------------------------------------------------- /demoApps/static/html/index.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | height: 100%; 3 | margin: 0; 4 | color: #33ff33; 5 | background-color: black; 6 | font-family: 'Courier New', Courier, monospace; 7 | } 8 | 9 | #console { 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | height: 100%; 14 | font-size: 24px; 15 | text-shadow: 0 0 5px rgba(51, 255, 51, 0.8); 16 | } 17 | -------------------------------------------------------------------------------- /demoApps/static/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello, DevContainers 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demoApps/static/html/index.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | const consoleElement = document.getElementById('console'); 3 | consoleElement.textContent = 'Hello, Devcontainers!'; 4 | }); 5 | -------------------------------------------------------------------------------- /enablingJavaAsyncProfiler/devcontainer.json: -------------------------------------------------------------------------------- 1 | //The example shows how to enable Java Async Profiler in a Dev Container 2 | { 3 | "name": "minimal_ubuntu", 4 | "image": "ubuntu:latest", 5 | "runArgs": [ 6 | "--privileged" 7 | ], 8 | "postCreateCommand": "apt-get update && apt-get install -y procps && sysctl -w kernel.perf_event_paranoid=1" 9 | } -------------------------------------------------------------------------------- /gpu_amd64/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GPU Dev Container", 3 | 4 | "build": { 5 | "dockerfile": "Dockerfile" 6 | }, 7 | 8 | "runArgs": ["--gpus=all"], 9 | } -------------------------------------------------------------------------------- /gpu_amd64/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 2 | 3 | ENV NVIDIA_VISIBLE_DEVICES=all 4 | ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility 5 | 6 | ENV DEBIAN_FRONTEND=noninteractive 7 | 8 | RUN apt-get update -y && \ 9 | apt-get install -y --no-install-recommends \ 10 | python3 python3-pip python3-dev build-essential && \ 11 | apt-get clean && rm -rf /var/lib/apt/lists/* 12 | 13 | RUN pip3 install --no-cache-dir --upgrade pip 14 | 15 | WORKDIR /workspace 16 | -------------------------------------------------------------------------------- /minimalOS/almalinux/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_almalinux", 3 | "image": "almalinux" 4 | } 5 | -------------------------------------------------------------------------------- /minimalOS/alpine/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_alpine", 3 | "image": "frolvlad/alpine-glibc:latest", 4 | "onCreateCommand": "apk add --no-cache unzip curl libxext libxrender libxtst libxi freetype procps" 5 | } -------------------------------------------------------------------------------- /minimalOS/archlinux_amd64/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_archlinux", 3 | "image": "menci/archlinux:latest" 4 | } 5 | -------------------------------------------------------------------------------- /minimalOS/archlinux_arm64/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_archlinux", 3 | "image": "menci/archlinuxarm:latest" 4 | } -------------------------------------------------------------------------------- /minimalOS/clearlinux_amd64/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_clearlinux", 3 | "image": "clearlinux:latest" 4 | } -------------------------------------------------------------------------------- /minimalOS/debian/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_debian", 3 | "image": "debian:latest" 4 | } 5 | -------------------------------------------------------------------------------- /minimalOS/fedora/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_fedora", 3 | "image": "fedora:latest" 4 | } 5 | -------------------------------------------------------------------------------- /minimalOS/gentoo/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_gentoo", 3 | "image": "gentoo/stage3:latest" 4 | } -------------------------------------------------------------------------------- /minimalOS/kalilinux/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_kalilinux", 3 | "image": "kalilinux/kali-rolling:latest" 4 | } -------------------------------------------------------------------------------- /minimalOS/manjaro/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_manjaro", 3 | "image": "manjarolinux/base:latest" 4 | } -------------------------------------------------------------------------------- /minimalOS/opensuse/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_opensuse", 3 | "image": "opensuse/leap:latest" 4 | } -------------------------------------------------------------------------------- /minimalOS/oraclelinux/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_oraclelinux", 3 | "image": "oraclelinux:8" 4 | } -------------------------------------------------------------------------------- /minimalOS/rockylinux/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_rockylinux", 3 | "image": "rockylinux/rockylinux:9" 4 | } 5 | -------------------------------------------------------------------------------- /minimalOS/ubuntu/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_ubuntu", 3 | "image": "ubuntu:latest", 4 | } 5 | -------------------------------------------------------------------------------- /specification/1-spec_forwardPorts/.devcontainer.json: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Ports that should always be forwarded from the primary container 4 | * to your local machine. 5 | * 6 | * Accepted formats: 7 | * • port number — `3000` 8 | * • host-and-port pair — `"db:5432"` 9 | * 10 | * Typical use cases: 11 | * • The process opens the port before the IDE can auto-forward it 12 | * • The port belongs to a service in **another** container (Docker Compose) 13 | * 14 | * Example 15 | * ```json 16 | * "forwardPorts": [3000, "db:5432"] 17 | * ``` 18 | * 19 | * Default: `[]` 20 | */ 21 | 22 | /* 23 | * In most cases you don’t need to set `forwardPorts` manually. 24 | * When an app inside the dev container starts listening on a port, 25 | * the IDE forwards it automatically. 26 | */ 27 | { 28 | "name": "1-spec_forwardPorts", 29 | "build": { 30 | "dockerfile": "../../demoApps/python-webserver/Dockerfile" 31 | }, 32 | "forwardPorts": [8080] 33 | } 34 | /*TODO: In the future support for hostname:port when used with compose are planned IDEA-335758 35 | */ 36 | 37 | -------------------------------------------------------------------------------- /specification/1_1-spec_portsAttributes/.devcontainer.json: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Maps a port—whether specified as a single number, a "host:port" pair, a range, or a regular expression— 4 | to its default options. 5 | See “Port attributes” for the list of available options. 6 | 7 | Example: 8 | "portsAttributes": { 9 | "3000": { "label": "Application port" } 10 | } 11 | */ 12 | 13 | /* 14 | The forwardPorts feature works only in automatic mode, so you don’t need to set any flag. 15 | When an application launched from the IDE inside the dev container starts listening on a port, 16 | that port is forwarded automatically. 17 | */ 18 | { 19 | "name": "1_1-spec_portsAttributes", 20 | "build": { 21 | "dockerfile": "../../demoApps/python-webserver/Dockerfile" 22 | }, 23 | "forwardPorts": [8080, 8090], 24 | "portsAttributes": { 25 | "8080": { 26 | "label": "Web Default", 27 | }, 28 | "8090": { 29 | "label": "API Server", 30 | } 31 | } 32 | } 33 | 34 | //TODO: In the future support for onAutoForward, requireLocalPort, elevateIfNeeded are planned. 35 | //IDEA-337384 36 | -------------------------------------------------------------------------------- /specification/1_10-spec_shutdownAction/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | shutdownAction 3 | -------------- 4 | 5 | Tells the IDE what to do with the container when its tool window closes or the 6 | backend shuts down. 7 | 8 | • none – Leave the container running. 9 | • stopContainer – Stop just this container (default for images/Dockerfiles). 10 | • stopCompose – Shut down the entire Docker Compose stack (default for 11 | Compose). 12 | 13 | Choose **none** if you want the container to stay alive after the IDE 14 | disconnects—for example: 15 | 16 | • **Long-running jobs** (model training, large data processing). 17 | • **Background services** (web servers, databases) you still need. 18 | • **Quicker return**—re-connecting is faster than a full restart. 19 | */ 20 | 21 | { 22 | "name": "1_10-spec_shutdownAction", 23 | "image": "ubuntu:latest", 24 | "shutdownAction": "none" 25 | } 26 | -------------------------------------------------------------------------------- /specification/1_11-spec_init/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | init 3 | ---- 4 | 5 | Adds the `--init` flag when the dev container is created, so **tini** runs as 6 | PID 1. 7 | 8 | Why use it? 9 | • Tini is a tiny init system that reaps orphaned child processes, preventing 10 | “zombie” PIDs. 11 | • It also forwards Unix signals, letting your app shut down cleanly. 12 | 13 | Default: **false**. 14 | The option works across orchestrators that support the `--init` flag. 15 | 16 | More details: https://github.com/krallin/tini 17 | */ 18 | 19 | { 20 | "name": "1_11-spec_init", 21 | "image": "ubuntu:latest", 22 | "init": true 23 | } 24 | -------------------------------------------------------------------------------- /specification/1_12-spec_privileged/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | privileged 3 | ---------- 4 | 5 | Runs the container with Docker’s `--privileged` flag, granting it full host 6 | capabilities—necessary for setups such as Docker-in-Docker. 7 | 8 | Default: **false**. 9 | 10 | ⚠️ Privileged mode weakens isolation and poses security risks, especially 11 | on native Linux hosts. Enable only when strictly required. 12 | */ 13 | { 14 | "name": "1_12-spec_privileged", 15 | "image": "ubuntu:latest", 16 | privileged: true 17 | } 18 | -------------------------------------------------------------------------------- /specification/1_13-spec_capAdd/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | capAdd 3 | ------ 4 | 5 | A list of extra Linux capabilities to grant the container. 6 | Example: 7 | 8 | "capAdd": ["SYS_PTRACE"] // needed to debug C++, Go, Rust, etc. 9 | 10 | Default: [] (no additional capabilities). 11 | 12 | Use **capAdd** when a task requires privileges that a standard container lacks, 13 | so you don’t have to run the entire environment in full **privileged** mode. 14 | This keeps the setup more secure. 15 | */ 16 | { 17 | "name": "1_13-spec_capAdd", 18 | "image": "ubuntu:latest", 19 | "capAdd": ["SYS_PTRACE"] 20 | } -------------------------------------------------------------------------------- /specification/1_14-spec_securityOpt/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | securityOpt 3 | ----------- 4 | 5 | Array of extra Docker security options to apply to the container. 6 | 7 | Default: [] 8 | 9 | Example: 10 | "securityOpt": ["seccomp=unconfined"] 11 | 12 | In this example the default seccomp profile is disabled, so the container 13 | is not limited by Docker’s standard system-call filters. 14 | */ 15 | { 16 | "name": "1_14-spec_securityOpt", 17 | "image": "ubuntu:latest", 18 | "securityOpt": [ "seccomp=unconfined" ] 19 | } 20 | -------------------------------------------------------------------------------- /specification/1_15-spec_mounts/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | mounts 3 | ------ 4 | 5 | Adds extra mounts to the container. 6 | Each entry follows the syntax of Docker’s `--mount` flag and can reference 7 | environment or predefined variables. 8 | 9 | Default: *unset*. 10 | 11 | Example: 12 | "mounts": [ 13 | { "type": "volume", 14 | "source": "dind-var-lib-docker", 15 | "target": "/var/lib/docker" } 16 | ] 17 | 18 | Choosing a mount type 19 | • **Bind mount** – Ideal when you need to edit files on the host and have 20 | changes appear instantly in the container. 21 | • **Volume** – Better for data that should persist across container runs but 22 | doesn’t need to live on the host filesystem. 23 | */ 24 | 25 | { 26 | "name": "1_15-spec_mounts", 27 | "image": "ubuntu:latest", 28 | 29 | "mounts": [{ 30 | "source": "${localEnv:HOME}", 31 | "target": "/hostHome", 32 | "type": "bind" 33 | }, { 34 | "source": "mount", 35 | "target": "/volume/mount", 36 | "type": "volume" 37 | }] 38 | } 39 | -------------------------------------------------------------------------------- /specification/1_16-spec_features/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | features 3 | -------- 4 | 5 | A map of Dev Container Feature IDs (see https://containers.dev/features) and 6 | their configuration options to be added to your main container. 7 | 8 | Each feature supports its own set of options—check the feature’s 9 | documentation for specifics. 10 | 11 | Example: 12 | "features": { 13 | "ghcr.io/devcontainers/features/docker-in-docker:2": {} 14 | } 15 | */ 16 | 17 | { 18 | "name": "1_16-spec_features", 19 | "image": "ubuntu:latest", 20 | "features": { 21 | "ghcr.io/devcontainers/features/docker-in-docker:2": {} 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /specification/1_17-spec_overrideFeatureInstallOrder/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | overrideFeatureInstallOrder 3 | --------------------------- 4 | 5 | Features normally install themselves in the order implied by their 6 | `installsAfter` field. 7 | Use this setting to override that order when necessary. 8 | 9 | Example: 10 | "overrideFeatureInstallOrder": [ 11 | "ghcr.io/devcontainers/features/common-utils", 12 | "ghcr.io/devcontainers/features/github-cli" 13 | ] 14 | */ 15 | 16 | { 17 | "name": "1_17-spec_overrideFeatureInstallOrder", 18 | "image": "ubuntu:latest", 19 | "features": { 20 | "ghcr.io/devcontainers/features/common-utils:2": { 21 | "configureZshAsDefaultShell": true 22 | }, 23 | "ghcr.io/devcontainers/features/git:1": {}, 24 | "ghcr.io/devcontainers/features/docker-in-docker:2": { 25 | "installDockerBuildx": true 26 | } 27 | } 28 | , 29 | "overrideFeatureInstallOrder": [ 30 | "ghcr.io/devcontainers/features/common-utils", 31 | "ghcr.io/devcontainers/features/git" 32 | ], 33 | } 34 | -------------------------------------------------------------------------------- /specification/1_18-spec_customizations/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | Product-specific properties provided by the supporting tools. 3 | */ 4 | { 5 | "name": "1_1_18-spec_customizations", 6 | "image": "ubuntu:latest", 7 | "customizations": { 8 | "jetbrains": { 9 | "backend": "GoLand" 10 | } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /specification/1_19-spec_workspaceFolder/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | workspaceFolder 3 | --------------- 4 | 5 | Absolute path in the container where the workspace is mounted. 6 | Change this if you need a different location. 7 | 8 | • Must be an absolute path (Linux or Windows style). 9 | • Supports variables such as ${localWorkspaceFolderBasename}. 10 | 11 | Default: "/workspaces/${localWorkspaceFolderBasename}" 12 | */ 13 | 14 | { 15 | "name": "1_19-spec_workspaceFolder", 16 | "image": "ubuntu:latest", 17 | "workspaceFolder": "/custom-workspace/${localWorkspaceFolderBasename}" 18 | } -------------------------------------------------------------------------------- /specification/1_2-spec_otherPortsAttributes/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | Default settings for any port, port range, or host **not** covered by portsAttributes. 3 | See “Port attributes” for all available options. 4 | 5 | Example: 6 | "otherPortsAttributes": { 7 | "onAutoForward": "silent" 8 | } 9 | */ 10 | 11 | { 12 | "name": "1_2-spec_otherPortsAttributes", 13 | "build": { 14 | "dockerfile": "../../demoApps/python-webserver/Dockerfile" 15 | }, 16 | "forwardPorts": [8080], 17 | "otherPortsAttributes": { 18 | label: "Application" 19 | } 20 | } 21 | 22 | //TODO: In the future support for onAutoForward, requireLocalPort, elevateIfNeeded are planned. 23 | //IDEA-337384 24 | -------------------------------------------------------------------------------- /specification/1_20-spec_workspaceMount/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | workspaceMount 3 | -------------- 4 | 5 | Defines how the workspace is mounted inside the container. 6 | 7 | • Customize the mount’s source, target, and options. 8 | • Useful when you need a different host path or specific mount flags. 9 | 10 | If omitted, the local workspace folder is mounted to `workspaceFolder` 11 | using the default settings. 12 | */ 13 | 14 | { 15 | "name": "1_20-spec_workspaceMount", 16 | "image": "ubuntu:latest", 17 | "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached" 18 | } -------------------------------------------------------------------------------- /specification/1_21-spec_runArgs/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | runArgs 3 | ------- 4 | 5 | Array of command-line flags passed straight to the container runtime 6 | (e.g. Docker) at launch time, letting you change behaviour without touching 7 | the Dockerfile. 8 | 9 | Typical examples: 10 | 11 | • ["--env", "NAME=VALUE"] // set an environment variable 12 | • ["--volume", "/host:/container:ro"] // bind or volume mount 13 | • ["--network=host"] // switch network mode 14 | • ["--gpus=all"] // expose GPUs 15 | • ["--cap-add=SYS_PTRACE"] // add a Linux capability 16 | */ 17 | 18 | { 19 | "name": "1_21-spec_runArgs", 20 | "image": "ubuntu:latest", 21 | "runArgs": [ 22 | "--env", "EXAMPLE_VAR=example_value", 23 | "--network=host", 24 | "--cap-add=SYS_PTRACE" 25 | ] 26 | } -------------------------------------------------------------------------------- /specification/1_22-spec_hostRequirements/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | hostRequirements 3 | ---------------- 4 | 5 | Define the minimum host resources the dev-container needs. 6 | 7 | You can set: 8 | 9 | • cpu – minimum number of CPU cores 10 | • memoryGB – minimum RAM (GB) 11 | • storageGB – minimum disk space (GB) 12 | • gpu – required GPU type, or `true` if any GPU is needed 13 | 14 | If the host falls short of these limits, the IDE will show a warning. 15 | */ 16 | 17 | { 18 | "name": "1_25-spec_hostRequirements", 19 | "image": "ubuntu:latest", 20 | "hostRequirements": { 21 | "cpus": 4, 22 | "memory": "8gb", 23 | "storage": "32gb", 24 | "gpu": "optional" 25 | } 26 | } 27 | //TODO: IJPL-66527 Devcontainers: support "Minimum host requirements" options -------------------------------------------------------------------------------- /specification/1_3-spec_containerEnv/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | Defines environment variables for the container as simple key–value pairs. 3 | 4 | You can reference host or predefined variables in the values, e.g.: 5 | 6 | "containerEnv": { "MY_VARIABLE": "${localEnv:MY_VARIABLE}" } 7 | 8 | Need to build on an existing container variable (for example, to extend PATH)? 9 | Use **remoteEnv** instead. 10 | 11 | `containerEnv` writes the variable directly into the Docker container, so every 12 | process inside can read it. The value is fixed for the life of the container— 13 | rebuild the container to change it. 14 | 15 | Whenever you can, prefer `containerEnv` over `remoteEnv`; it works for every 16 | process and isn’t tied to a particular client. 17 | 18 | --- 19 | 20 | **Verify the variables** 21 | 22 | Inside the container, run: 23 | 24 | echo $HOSTHOME $HOSTNAME 25 | */ 26 | { 27 | "name": "1_3-spec_containerEnv", 28 | "image": "ubuntu:latest", 29 | "containerEnv": { 30 | "HOSTHOME": "${localEnv:HOME}", 31 | "HOSTNAME": "jetbrains.com" 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /specification/1_4-spec_remoteEnv/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | remoteEnv 3 | --------- 4 | 5 | Key–value pairs that set or override environment variables **only** for the JetBrains IDE 6 | backend and its helper processes (such as integrated terminals), **not** for the entire 7 | Docker container. 8 | 9 | • Values can reference host-side or predefined variables. 10 | • Choose **remoteEnv** over **containerEnv** when the variable needs to change at runtime 11 | because remoteEnv can be updated without rebuilding the whole container (once 12 | rebuild/restart logic is fully in place). 13 | 14 | ------------------------------------------------- 15 | containerEnv vs. remoteEnv (at a glance) 16 | ------------------------------------------------- 17 | containerEnv – Baked into the image during `docker build`; visible to every process 18 | in the container; changes require a rebuild. 19 | 20 | remoteEnv – Injected when the JetBrains IDE backend starts; affects only the 21 | backend and its sub-processes; can be refreshed on restart. 22 | 23 | Default guideline: use **containerEnv** unless you specifically need the flexibility 24 | of runtime updates provided by **remoteEnv**. 25 | */ 26 | 27 | { 28 | "name": "1_4-spec_remoteEnv", 29 | "image": "ubuntu:latest", 30 | "remoteEnv": { 31 | "DYNAMIC_VAR": "initial" 32 | }, 33 | "containerEnv": { 34 | "STATIC_VAR": "initial" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /specification/1_5-spec_remoteUser/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | remoteUser 3 | ---------- 4 | 5 | Specifies the Linux user that the JetBrains IDE backend and its helper tools 6 | (terminals, tasks, debuggers, etc.) run as inside the container. 7 | 8 | • **Does not** affect the default user for the entire container—use `containerUser` 9 | for that. 10 | • If omitted, it inherits the container’s main user (typically `root`). 11 | • By default, the value comes from the base image used by the dev-container 12 | configuration unless you override it here. 13 | */ 14 | { 15 | "name": "1_5-spec_remoteUser", 16 | "build": { 17 | "dockerfile": "./Dockerfile" 18 | }, 19 | "remoteUser": "developer" 20 | } 21 | -------------------------------------------------------------------------------- /specification/1_5-spec_remoteUser/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | git \ 5 | procps \ 6 | && rm -rf /var/lib/apt/lists/* 7 | 8 | ARG USER=developer 9 | ARG USER_GID=1001 10 | ARG USER_UID=1001 11 | 12 | RUN groupadd --gid $USER_GID $USER \ 13 | && useradd --uid $USER_UID --gid $USER_GID -m $USER 14 | # sudo support 15 | RUN apt-get update \ 16 | && apt-get install -y sudo \ 17 | && echo $USER ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USER \ 18 | && chmod 0440 /etc/sudoers.d/$USER 19 | 20 | USER $USER 21 | 22 | CMD ["/bin/bash"] 23 | -------------------------------------------------------------------------------- /specification/1_6-spec_containerUser/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | containerUser 3 | ------------- 4 | 5 | Defines the Linux user that **all** processes inside the container run as. 6 | 7 | • If omitted, the container starts as `root` or as the last `USER` specified 8 | in your Dockerfile. 9 | • Need the IDE backend or its tools to run as a different user? 10 | Use **remoteUser** instead. 11 | 12 | ⚠️ The user must already exist in the image and have the right permissions. 13 | Add one in your Dockerfile, for example: 14 | 15 | RUN useradd -m devuser && \ 16 | chown -R devuser /workspace 17 | */ 18 | { 19 | "name": "1_6-spec_containerUser", 20 | "build": { 21 | "dockerfile": "./Dockerfile" 22 | }, 23 | "containerUser": "root" 24 | } 25 | 26 | -------------------------------------------------------------------------------- /specification/1_6-spec_containerUser/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | git \ 5 | procps \ 6 | && rm -rf /var/lib/apt/lists/* 7 | 8 | ARG USER=developer 9 | ARG USER_GID=1001 10 | ARG USER_UID=1001 11 | 12 | RUN groupadd --gid $USER_GID $USER \ 13 | && useradd --uid $USER_UID --gid $USER_GID -m $USER 14 | # sudo support 15 | RUN apt-get update \ 16 | && apt-get install -y sudo \ 17 | && echo $USER ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USER \ 18 | && chmod 0440 /etc/sudoers.d/$USER 19 | 20 | USER $USER 21 | 22 | CMD ["/bin/bash"] 23 | -------------------------------------------------------------------------------- /specification/1_7-spec_updateRemoteUserUID/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | updateUIDGID 3 | ------------ 4 | 5 | On Linux, when you specify `containerUser` or `remoteUser`, the container 6 | automatically updates that user’s UID and GID to match your local user. 7 | This prevents permission issues with bind-mounted files. 8 | Default: **true**. 9 | 10 | If you already have host files that rely on fixed UID/GID values and must be 11 | accessible from the container, consider turning this feature off to keep the 12 | container user’s IDs unchanged. 13 | 14 | Check the current IDs and file ownership inside the container with: 15 | 16 | id # shows your UID and GID 17 | ls -l # shows ownership of files 18 | */ 19 | { 20 | "name": "1_7-spec_updateRemoteUserUID", 21 | "build": { 22 | "dockerfile": "./Dockerfile" 23 | }, 24 | "containerUser": "root", 25 | "updateRemoteUserUID": false 26 | } 27 | -------------------------------------------------------------------------------- /specification/1_7-spec_updateRemoteUserUID/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | git \ 5 | procps \ 6 | && rm -rf /var/lib/apt/lists/* 7 | 8 | ARG USER=developer 9 | ARG USER_GID=1001 10 | ARG USER_UID=1001 11 | 12 | RUN groupadd --gid $USER_GID $USER \ 13 | && useradd --uid $USER_UID --gid $USER_GID -m $USER 14 | # sudo support 15 | RUN apt-get update \ 16 | && apt-get install -y sudo \ 17 | && echo $USER ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USER \ 18 | && chmod 0440 /etc/sudoers.d/$USER 19 | 20 | USER $USER 21 | 22 | CMD ["/bin/bash"] 23 | -------------------------------------------------------------------------------- /specification/1_8-spec_userEnvProbe/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | userEnvProbe 3 | ------------ 4 | 5 | Controls **how** the IDE backend collects your local environment variables and 6 | passes them into supporting tools and processes defined in `.devcontainer.json`. 7 | 8 | Valid options (default = `loginInteractiveShell`): 9 | 10 | • none 11 | No variables are pulled from the host; only those defined in the 12 | container image or in `.devcontainer.json` are available. 13 | 14 | • interactiveShell 15 | Runs a non-login interactive shell (e.g. Bash reads `/etc/bash.bashrc` 16 | and `~/.bashrc`). Login-only files such as `~/.profile` are **not** read. 17 | 18 | • loginShell 19 | Runs a login (non-interactive) shell, loading files like 20 | `/etc/profile`, `~/.bash_profile`, `~/.bash_login`, or `~/.profile`. 21 | 22 | • loginInteractiveShell 23 | Runs an interactive **login** shell, so it sources *all* of the above 24 | files. This gives the most complete set of variables. 25 | 26 | The actual shell is whatever the user’s default is (usually Bash). 27 | 28 | --- 29 | 30 | **Check what was imported** 31 | 32 | Inside the container, inspect a variable with: 33 | 34 | echo "$USERPATH" 35 | */ 36 | 37 | { 38 | "name": "1_8-spec_userEnvProbe", 39 | "image": "ubuntu:latest", 40 | "userEnvProbe": "loginInteractiveShell", 41 | "runArgs": ["--env", "USERPATH=${localEnv:PATH}"] 42 | } -------------------------------------------------------------------------------- /specification/1_9-spec_overrideCommand_false/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | overrideCommand 3 | --------------- 4 | 5 | Decides whether supporting services/tools defined in `.devcontainer.json` 6 | should replace the container’s default command with a simple 7 | keep-alive loop: 8 | 9 | /bin/sh -c "while sleep 1000; do :; done" 10 | 11 | This loop prevents the container from shutting down if its normal command 12 | exits immediately. 13 | 14 | • **true** – Run the keep-alive loop instead of the image’s default command 15 | (default for images built from a Dockerfile). 16 | • **false** – Run the image’s default command; choose this when the container 17 | must start its normal entrypoint to function. 18 | 19 | Default behaviour: 20 | • `true` when using an image or Dockerfile 21 | • `false` when using a Docker Compose file 22 | 23 | Test note: a file named **test** is created in the container’s root (`/`) 24 | directory. 25 | */ 26 | 27 | { 28 | "name": "1_9-spec_overrideCommand_false", 29 | "build": { 30 | "dockerfile": "./Dockerfile" 31 | }, 32 | "overrideCommand": false 33 | } -------------------------------------------------------------------------------- /specification/1_9-spec_overrideCommand_false/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | git \ 5 | procps \ 6 | && rm -rf /var/lib/apt/lists/* 7 | 8 | ENTRYPOINT ["/bin/bash", "-c", "touch /test && echo 'Hello from Dockerfile'; exec bash"] 9 | -------------------------------------------------------------------------------- /specification/1_9-spec_overrideCommand_true/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | overrideCommand 3 | --------------- 4 | 5 | Determines whether the supporting services/tools defined in `.devcontainer.json` 6 | replace the container’s default command with a simple keep-alive loop: 7 | 8 | /bin/sh -c "while sleep 1000; do :; done" 9 | 10 | This loop prevents the container from exiting immediately if its normal 11 | command ends. Set **false** when the container must run its default 12 | entrypoint to work correctly. 13 | 14 | Default behaviour: 15 | • **true** for containers built from a Dockerfile 16 | • **false** for containers started via Docker Compose 17 | 18 | Note: In this setup the file **test** was *not* created in the root (`/`) 19 | directory because the Dockerfile’s `ENTRYPOINT` was overridden. 20 | */ 21 | 22 | { 23 | "name": "1_9-spec_overrideCommand_true", 24 | "build": { 25 | "dockerfile": "./Dockerfile" 26 | }, 27 | "overrideCommand": true 28 | } 29 | -------------------------------------------------------------------------------- /specification/1_9-spec_overrideCommand_true/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | git \ 5 | procps \ 6 | && rm -rf /var/lib/apt/lists/* 7 | 8 | ENTRYPOINT ["/bin/bash", "-c", "touch /test && echo 'Hello from Dockerfile'; exec bash"] 9 | -------------------------------------------------------------------------------- /specification/2-compose/.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal_web", 3 | "forwardPorts": ["80"], 4 | "dockerComposeFile": "../../demoApps/static/docker-compose.yml", 5 | "service": "web" 6 | } 7 | -------------------------------------------------------------------------------- /specification/spec-lifecycle_initializeCommand/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | onCreateCommand 3 | --------------- 4 | 5 | Command (string) or argv-style array to run on the **host** *before* the 6 | container is created. 7 | 8 | ⚠️ Executes in the folder where the source lives—if your code is in the 9 | cloud, the command runs there. 10 | 11 | • Array form is invoked directly (no shell). 12 | */ 13 | 14 | { 15 | "name": "spec-lifecycle_initializeCommand", 16 | "image": "ubuntu:latest", 17 | // "initializeCommand": "echo 'Initializing Dev Container...'" 18 | // "initializeCommand": ["sh", "-c", "echo 'Initializing Dev Container...'"] 19 | "initializeCommand": { 20 | "1": "echo a", 21 | "2": "echo b", 22 | "3": "echo c" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /specification/spec-lifecycle_onCreateCommand/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | initCommand 3 | ----------- 4 | 5 | The first of three lifecycle hooks (`initCommand`, `updateContentCommand`, 6 | `postCreateCommand`) that finish setting up the dev-container. 7 | 8 | • Executes **inside** the container immediately after its very first start. 9 | • Cloud services may run it while pre-building or caching the image, so 10 | don’t expect user-specific files or secrets to be available. 11 | • Array form is invoked directly—no shell wrapper. 12 | */ 13 | 14 | { 15 | "name": "spec-lifecycle_onCreateCommand", 16 | "image": "ubuntu:latest", 17 | // "onCreateCommand": "echo 'Initializing Dev Container...'" 18 | // "onCreateCommand": ["sh", "-c", "echo 'Initializing Dev Container...'"] 19 | "onCreateCommand": { 20 | "1": "echo a", 21 | "2": "echo b", 22 | "3": "echo c" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /specification/spec-lifecycle_postStartCommand/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | postStartCommand 3 | ---------------- 4 | 5 | Command that runs every time the container starts successfully. 6 | 7 | • Accepts either a single string or an array of arguments. 8 | Array form is executed directly (no shell). 9 | 10 | --- 11 | 12 | **How to check the output** 13 | 14 | In the JetBrains client IDE, choose **Help ▸ Collect Host and Client Logs**. 15 | Unzip the archive, then open `Host/idea.log` to see the command’s terminal 16 | output. 17 | 18 | */ 19 | 20 | { 21 | "name": "spec-lifecycle_postStartCommand", 22 | "image": "ubuntu:latest", 23 | // "postCreateCommand": "echo 'Initializing Dev Container...'" 24 | // "postCreateCommand": ["sh", "-c", "echo 'Initializing Dev Container...'"] 25 | "postCreateCommand": { 26 | "1": "ls /", 27 | "2": "echo 'PostStartCommand...'", 28 | "3": "echo 'ok'" 29 | } 30 | } 31 | //TODO: IDEA-339416 32 | -------------------------------------------------------------------------------- /specification/spec-lifecycle_updateContentCommand/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | updateContentCommand 3 | -------------------- 4 | 5 | The second of three lifecycle hooks (`initCommand`, `updateContentCommand`, 6 | `postCreateCommand`) used to finish setting up a dev-container. 7 | 8 | • Runs **inside** the container **after** `onCreateCommand` whenever new files 9 | appear in the workspace during creation. 10 | • Executes at least once; cloud providers may run it again to refresh cached 11 | or pre-built containers. 12 | • Only repository- or organisation-scoped secrets are available—assume no 13 | user-scoped credentials. 14 | • Array form is executed directly (no shell). 15 | 16 | --- 17 | 18 | **Viewing the output** 19 | 20 | In the JetBrains client IDE choose **Help ▸ Collect Host and Client Logs**. 21 | Unzip the archive and open `Host/idea.log` to see the command’s terminal 22 | output. 23 | */ 24 | 25 | { 26 | "name": "spec-lifecycle_updateContentCommand", 27 | "image": "ubuntu:latest", 28 | // "updateContentCommand": "echo 'Initializing Dev Container...'" 29 | // "updateContentCommand": ["sh", "-c", "echo 'Initializing Dev Container...'"] 30 | "updateContentCommand": { 31 | "1": "ls /", 32 | "2": "echo 'UpdateContentCommand...'", 33 | "3": "echo 'ok'" 34 | } 35 | } 36 | //TODO: IDEA-339416 -------------------------------------------------------------------------------- /specification/spec-lifecycle_waitFor/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | waitFor 3 | ------- 4 | 5 | Specifies which lifecycle hook a supporting tool must wait for before it 6 | connects to the container. 7 | 8 | Possible values: `onCreateCommand`, `updateContentCommand`, `postCreateCommand` 9 | Default: `updateContentCommand`. 10 | 11 | Use `onCreateCommand` or `updateContentCommand` for tasks that have to finish 12 | before the tool attaches, and reserve `postCreateCommand` for work that can 13 | run later in the background. 14 | */ 15 | 16 | { 17 | "name": "Ubuntu", 18 | image: "ubuntu:latest", 19 | 20 | "onCreateCommand": "sleep 30 && echo onCreateCommand", 21 | "updateContentCommand": "sleep 30 && echo updateContentCommand", 22 | "postCreateCommand": "sleep 30 && echo postCreateCommand", 23 | "waitFor": "postCreateCommand" 24 | } 25 | -------------------------------------------------------------------------------- /specification/spec_lifecycle_postAttachCommand/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | Now the command is executed correctly. To verify this, in the Client IDE, select Help -> Collect Host and Client Logs. 3 | The resulting zip archive should be unzipped, and in the Host -> idea.log folder, you can find the terminal output of 4 | the command execution. 5 | */ 6 | { 7 | "name": "spec-lifecycle_postAttachCommand", 8 | "image": "ubuntu:latest", 9 | // "postAttachCommand": "echo 'Initializing Dev Container...'" 10 | // "postAttachCommand": ["sh", "-c", "echo 'Initializing Dev Container...'"] 11 | "postAttachCommand": { 12 | "1": "ls /", 13 | "2": "echo 'PostAttachCommand...'", 14 | "3": "echo 'ok'" 15 | } 16 | } 17 | //TODO: IDEA-339416 18 | -------------------------------------------------------------------------------- /specification/spec_lifecycle_postCreateCommand/.devcontainer.json: -------------------------------------------------------------------------------- 1 | /* 2 | postCreateCommand 3 | ----------------- 4 | 5 | The third and final setup hook (`initCommand`, `updateContentCommand`, 6 | `postCreateCommand`). 7 | 8 | • Runs **inside** the container **after** `updateContentCommand`, once the 9 | container is assigned to a user for the first time. 10 | • At this stage, you can access user-scoped secrets and permissions—cloud 11 | providers execute this hook only after the container becomes user-specific. 12 | • If you supply an array, it is run directly (no shell wrapper). 13 | 14 | --- 15 | 16 | **Viewing the output** 17 | 18 | In the JetBrains client IDE, choose **Help ▸ Collect Host and Client Logs**. 19 | Unzip the archive and open `Host/idea.log` to see the command’s terminal 20 | output. 21 | */ 22 | { 23 | "name": "spec-lifecycle_postCreateCommand", 24 | "image": "ubuntu:latest", 25 | // "postCreateCommand": "echo 'Initializing Dev Container...'" 26 | // "postCreateCommand": ["sh", "-c", "echo 'Initializing Dev Container...'"] 27 | "postCreateCommand": { 28 | "1": "ls /", 29 | "2": "echo 'PostCreateCommand...'", 30 | "3": "echo 'ok'" 31 | } 32 | } 33 | //TODO: IDEA-339416 34 | --------------------------------------------------------------------------------