Day 97 of #100DaysOfLearning
Dev Containers on Windows 11

Day 97 of #100DaysOfLearning

Today is the fourth day of setting up a Windows environment.

Today I finally get to set up my long-awaited development environment. First, today I decided to build a Java development environment, although I may be the only one who thinks it is the most basic of the basics.

The following is a summary of today's development environment settings.


Development Environment on Dev containers

Java

This Dev Container consists of the following three files:

  • Dockerfile
  • compose.yaml
  • devcontainer.json

Dockerfile

This file is used to build the container image that will contain your development environment. It specifies the base image, installs necessary dependencies, sets up the environment, and copies any project-specific files into the container. The Dockerfile is essential for defining the environment's infrastructure and dependencies.
FROM mcr.microsoft.com/devcontainers/java:1-21-bullseye
USER vscode
WORKDIR /workspace        

  • USER: Non-root user.In mcr.microsoft.com/devcontainers/java, the vscode user is already defined and can be used by simply specifying it
  • WORKDIR: To separate the workspace from the location of the dev container definition files

If you want a base image which Microsoft pre-built, you can find it at the following:

compose.yaml

Docker Compose is a tool for defining and running multi-container Docker applications. The compose.yaml file defines services, networks, and volumes for your application's containers. While not strictly required for every Dev Container setup, it can be useful for defining more complex development environments with multiple services or containers that need to interact with each other.
services:
  playground-java:
    container_name: 'playground'
    hostname: 'java'
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    working_dir: '/workspace'
    tty: true
    volumes:
      - type: bind
        source: ../workspace
        target: /workspace        

Explanation

services:
  playground-java:
    container_name: 'playground'
    hostname: 'java'        

  • services: This is the top-level key in a Docker Compose file, and it defines the services that make up your application.
  • playground-java: This is the name of the service, which in this case is named playground-java.

    build:
      context: .
      dockerfile: Dockerfile        

  • build: This specifies how to build the Docker image for the service.
  • context: .: This specifies the build context, which is the directory where the Dockerfile and any other files needed for building the image are located. In this case, it's set to the current directory (.).
  • dockerfile: Dockerfile: This specifies the name of the Dockerfile to use for building the image. In this case, it's named Dockerfile.

    restart: always        

  • restart: always: This instructs Docker to always restart the container if it stops for any reason.

    working_dir: '/workspace'        

  • working_dir: '/workspace': This sets the working directory inside the container to /workspace. When the container starts, commands executed within the container will run relative to this directory.

    tty: true        

  • tty: true: This allocates a pseudo-TTY for the service container, which enables interactive shell sessions.

    volumes:
      - type: bind
        source: ../workspace
        target: /workspace        

  • volumes: This specifies any volumes to mount into the container.
  • - type: bind: This indicates that you're using a bind mount, which mounts a directory from the host machine into the container.
  • source: ../workspace: This specifies the source directory on the host machine to bind mount into the container. It's relative to the location of the compose.yaml file and points to a directory named workspace in the parent directory (..).
  • target: /workspace: This specifies the target directory inside the container where the source directory will be mounted.

devcontainer.json

The devcontainer.json file configures how VS Code connects to and interacts with the Dev Container, including settings for extensions, environment variables, mount points, and more.
{
	"name": "Playground - Java",
  "dockerComposeFile": "compose.yaml",
	"service": "playground-java",
	"workspaceFolder": "/workspace",
	"remoteUser": "vscode",

	"features": {
		"ghcr.io/devcontainers/features/java:1": {
			"version": "none",
			"installMaven": "false",
			"installGradle": "true"
		}
	},
	"customizations": {
		"vscode": {
			"extensions": [
				"ms-azuretools.vscode-docker"
			],
			"settings": {
				"editor.formatOnSave": true,
				"workbench.colorCustomizations": {
					"titleBar.activeBackground": "#19549C",
					"titleBar.activeForeground": "#ffffff",
					"activityBar.background": "#02A7E3",
					"activityBar.foreground": "#ffffff"
				}
			}
		}
	}

	// "forwardPorts": [],

	// "postCreateCommand": "java -version"
}        

Explanation

{
	"name": "Playground - Java",
  "dockerComposeFile": "compose.yaml",
	"service": "playground-java",
	"workspaceFolder": "/workspace",
	"remoteUser": "vscode",        

  • name: This is the name of the Dev Container configuration, which appears in the VS Code UI.
  • dockerComposeFile: This specifies the Docker Compose file to use for creating the Dev Container. In this case, it's set to compose.yaml.
  • service: This specifies the service within the Docker Compose file that represents the Dev Container. Here, it's set to playground-java.
  • workspaceFolder: This specifies the workspace folder within the Dev Container. It's set to /workspace.
  • remoteUser: This specifies the user to use within the Dev Container. Here, it's set to vscode, which is a common choice for development within containers.

	"features": {
		"ghcr.io/devcontainers/features/java:1": {
			"version": "none",
			"installMaven": "false",
			"installGradle": "true"
		}
	},        

  • features: This section allows you to specify additional features or tools to include in the Dev Container. In this case, it's specifying a Java feature from a predefined set of Dev Container features. It specifies that Maven should not be installed (installMaven: "false") but Gradle should be installed (installGradle: "true").

	"customizations": {
		"vscode": {
			"extensions": [
				"ms-azuretools.vscode-docker"
			],
			"settings": {
				"editor.formatOnSave": true,
				"workbench.colorCustomizations": {
					"titleBar.activeBackground": "#19549C",
					"titleBar.activeForeground": "#ffffff",
					"activityBar.background": "#02A7E3",
					"activityBar.foreground": "#ffffff"
				}
			}
		}
	}        

  • customizations: This section allows you to customize the VS Code environment within the Dev Container. It specifies extensions to install (ms-azuretools.vscode-docker) and VS Code settings to apply. In this case, it enables automatic formatting on save ("editor.formatOnSave": true) and customizes the colors of the title bar and activity bar.

forwardPorts

The forwardPorts setting in the devcontainer.json file is used to specify port forwarding rules from the Dev Container to the local machine, allowing you to access services running inside the container from your local environment. This can be useful when you're running services or applications inside the Dev Container that need to be accessed from outside the container, such as web servers, APIs, or databases.

Here's example of the forwardPorts setting:

"forwardPorts": [3000, 8080]        

This example would forward ports 3000 and 8080 from the Dev Container to the local machine. So if there's a web server running inside the Dev Container on port 3000, you could access it from your local browser at https://localhost:3000.

You would typically set the forwardPorts setting when you're developing applications or services that need to be accessible from your local environment but are running inside a container. It's especially useful for web development, where you might have a web server running inside the container serving your application, and you want to test it locally in your browser.

postCreateCommand

The postCreateCommand setting in the devcontainer.json file is used to specify a command that should be executed after the Dev Container is created. This command runs once, immediately after the container is created but before it is started.

You might use the postCreateCommand setting for various purposes, such as:

  1. Setting up the development environment: You could use this command to perform additional setup steps required for your development environment after the container is created. For example, you might install additional tools or dependencies, initialize databases, or set up configuration files.
  2. Running initialization scripts: If your project requires specific initialization scripts to be executed before development can begin, you can specify these scripts as the postCreateCommand. This could include running database migrations, setting up test data, or performing any other necessary setup tasks.
  3. Customizing the container environment: You could use the postCreateCommand to customize the container environment based on specific project requirements. This might involve configuring system settings, setting environment variables, or performing any other customizations needed for your project.

Here's an example of how you might set the postCreateCommand in the devcontainer.json file:

"postCreateCommand": "git fetch origin && git diff origin/main"        

In this example, this command sequence would execute git fetch origin to fetch the latest changes from the remote repository and then run git diff origin/main to compare the local branch with the main branch on the remote repository.

Overall, the postCreateCommand setting allows you to automate additional setup steps or customization tasks that need to be performed after the Dev Container is created, helping to streamline the development environment setup process for your project.

Recommended VS Code Extensions

I recommend the following Visual Studio Code Extensions for Java Development:



The setup I have done today is a very basic Java development environment. You can use this as a template for various customizations, so if you use the contents of this template as a reference, please customize the environment to your own liking.


要查看或添加评论,请登录

社区洞察

其他会员也浏览了