PHP Workspace Container Part 1
Tags: php, docker
Published: 2019-12-31 00:14:03

---
title: PHP Workspace Container Part 1
published: true
date: 2019-12-30 23:58:10 UTC
tags: php, docker
canonical_url: https://rushlow.dev/blog/php-workspace-container-part-1
---

{% youtube zyHWYpVP6Gs %}

###TL;DR;

Create a docker container to provide PHP's CLI, Composer, Git, Node & Yarn that is not project specific and without the need to have any of the aforementioned tools installed on the host.

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](https://github.com/jrushlow/docker-php-workspace)

* * *

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...