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
Dockerfile
should reside in the project root directory instead of.devcontainer
with 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 theDockerfile
for building the image for devcontainer.context
: Build context directory (..
as our files are residing at the parent of.devcontainer
directory). Alternatively, one can placeDockerfile
inside.devcontainer
directory and change the context to.
, but it is always a good practice to keep yourDockerfile
at project’s root directory.- Other keys which can be used are
args
,options
andtarget
during building of docker image:args
are list of arguments that should be passed during the building stage.options
are list of options that should be passed to docker during the building stage.target
specifies 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.