I'll be demonstrating how to accomplish this using Debian Buster as the host with docker and docker-compose already installed. 

The source code for this project is available on GitHub


I use a directory structure on my host that allows me to store all of my PHP, Javascript, Python, etc. in separate folders organized by the project language. This allows me to have one workspace container per language. I.e.

- ~/develop/php
    - /symfony-app-1
    - /symfony-app-2
- ~/develop/python
    - /python-app

Creating our container


First we can go ahead and create our directory structure as follows:

cd ~/develop/php
mkdir workspace
touch .bash_aliases Dockerfile Makefile

- ~/php
    - .bash_aliases
    - Dockerfile
    - Makefile

Next, we'll define our docker image in the Dockerfile as follow's:

// Dockerfile

FROM php:7.4-cli-buster

RUN apt-get update && apt-get install -yqq \
    libzip-dev \
    zip \
    gnupg \
    git

# Install node and Yarn in workspace container
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash && \
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add && \
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update && apt-get install -yqq \
    nodejs \
    yarn

# Install composer & make compose global
RUN curl -s https://getcomposer.org/installer | php && \
    mv composer.phar /usr/local/bin/composer

# Create a regular user account to work from
RUN set -xe; \
    groupadd -g 1000 developer && \
    useradd -u 1000 -g developer -m developer && \
    usermod -p "*" developer -s /bin/bash

# Copy bash aliases defined on host to container
COPY .bash_aliases /home/developer/.bash_aliases

# Cleanup
RUN apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Set which account to use
USER developer

# Set working dir for container
WORKDIR /var/develop

Next, add any bash aliases that you want present within the workspace to .bash_aliases such as:

// .bash_aliases
alias la="ls -lah"

The above can be omitted if you prefer not to use any aliases, just remember to remove the COPY .bash_aliases /home/developer/.bash_aliases from the Dockerfile.

Create make targets


We could go ahead and fire up our container now without any issues using:

$> cd php/workspace
php/workspace:$> docker build . -t workspace:latest

....
Successfully built f6f89d2035c7
Successfully tagged workspace:latest

php/workspace:$> docker run -ti --rm --mount type=bind,src=/php,dst=/var/develop workspace:latest /bin/bash

developer@f6f89d2035c7:/var/develop$> 

But that's a lot of typing every time we need to enter the workspace container. We could use bash aliases to make this easier, but that can get unwieldy if you manage a lot of docker containers. I have chosen to use make to simplify my docker life. 

Edit your Makefile as follows:

// Makefile

.PHONY: build
build: ## Build docker workspace image
   docker build . -t workspace:latest

.PHONY: workspace
workspace: ## Launch workspace container bash shell
   docker run -ti --rm --mount type=bind,src=/path/to/develop/php,dst=/var/develop workspace:latest /bin/bash

Now all I have to do is call the make target's to build and launch the container like so:

php/workspace:$> make build
docker build . -t workspace:latest
Successfully built f6f89d2035c7
Successfully tagged workspace:latest

php/workspace:$> make workspace
docker run -ti --rm --mount type=bind,src=/path/to/develop/php,dst=/var/develop workspace:latest /bin/bash

developer@f6f89d2035c7:/var/develop$> WOOHOOO!

The best part about using make targets is portability. If you are managing several project's that each have their own docker images / containers, you can reuse the same makefile, with a little tweaking, across all of your projects. And best of all, it can be committed to your Git repo for others to use as well.

There are differences in how make works on linux based systems compared to Windows environments, but the principles are all the same.


Stay tuned for future video's in this series...