In this series, we have discussed about creating a basic Go based devcontainer and then we moved onto showcasing the life cycle events in devcontainers. Events like postCreateCommand and postStartCommand are good for smaller scripts execution during initialisation and running stage, but sometimes complex operations are needed to create an appropriate container such as installing major dependencies, initialisation of DB, etc. To facilitate this purpose, Dockerfile can be used create a devcontainer.
There is one more advantage of using Dockerfile as devcontainer which is portability. The Dockerfile used during the development can be directly used in deployment environments without worrying about breaking of code of missing or conflicting dependencies.
PHP devcontainer using Dockerfile
In this part of the series, we will extend our PHP devcontainer from the previous part to install some of the dependencies, run some Apache based settings and most importantly run our devcontainer as non-root user.
Dockerfile is used in this example, to achieve the same. The following is the Dockerfile used for the features mentioned above:
FROM php:8.2.20-apache
# Switching to root user for installation of dependencies
USER root
RUN a2enmod rewrite
RUN apt-get update && apt-get install -y git vim
WORKDIR /var/www/html
COPY . .
# Setting for running devcontainer as non-root user
RUN groupadd -g 1000 asura && useradd -r -u 1000 -g asura -m asura -c "Project Asuras" -s /bin/bash
RUN chown -R www-data:www-data /var/www/html
# Switching to apache2 default non-root user
USER www-data
EXPOSE 80
CMD [ "apache2-foreground" ]Note
The
Dockerfileshould reside in the project root directory instead of.devcontainerwith the current settings ofdevcontainer.json.
In the above Dockerfile we are switching to root user for installing the dependencies using apt repository and enabling rewrite plugin in apache.
Also, for our devcontainer we are creating a user and group named asura with UID of 1000 (as this is default uid used for devcontainer).
As Apache web server requires, owner of our /var/www/html directory to be www-data, we are executing chown command.
Once all the root operations are performed, we are switching to non-root www-data user. (such that during deployment, www-data is used instead of root user).
Our Dockerfile is ready, now let’s change our devcontainer.json file to:
{
"name": "Test Application Dev Container",
"build": {
"dockerfile": "../Dockerfile",
"context": ".."
},
"postStartCommand": "apache2ctl start",
"appPort": ["8080:80"],
"workspaceFolder": "/var/www/html",
"mounts": [
"source=${localWorkspaceFolder},target=/var/www/html,type=bind"
],
// Setting for running devcontainer as non-root user asura
"remoteUser": "asura",
"customizations": {
"vscode": {
"extensions": [
"bmewburn.vscode-intelephense-client",
"esbenp.prettier-vscode",
"xdebug.php-debug",
"ms-azuretools.vscode-docker"
],
"settings": {
"php.validate.executablePath": "/usr/local/bin/php",
"php.validate.run": "onType"
}
}
}
}The new parameters in the devcontainer.json which needs a bit of a understanding are as follows:
build: Build parameter is used for building a new container image (instead of pre-built container images) for devcontainer.dockerfile: Path of theDockerfilefor building the image for devcontainer.context: Build context directory (..as our files are residing at the parent of.devcontainerdirectory). Alternatively, one can placeDockerfileinside.devcontainerdirectory and change the context to., but it is always a good practice to keep yourDockerfileat project’s root directory.- Other keys which can be used are
args,optionsandtargetduring building of docker image:argsare list of arguments that should be passed during the building stage.optionsare list of options that should be passed to docker during the building stage.targetspecifies the build target.
remoteUser: Specify the user to be used while running the devcontainer, in our case, we have specially created a user namedasura.
After running the devcontainer using Rebuild command, you will be able to access the index.php page as previously.
Note
You can also check full specifications at containers.dev.
In the next part, we will be looking at running multiple containers in devcontainer.
