Skip to content

Commit 5c43911

Browse files
committed
Use docker multi-stage build for the base image
1 parent 6c1b904 commit 5c43911

File tree

4 files changed

+90
-65
lines changed

4 files changed

+90
-65
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
build/vendor/
21
config/local.php
32
config/console-local.php
43
/docker-compose.yml

README.md

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,38 @@ A template for docker based Yii 2 applications.
1717
## 1.1 Base Image
1818

1919
The core idea of this template is that you build a bespoke docker base image
20-
for your application wich exactly meets your project's requirements. We
21-
therefore use a dedicated configuration in `./build/Dockerfile`. This image
22-
will never change unless
20+
for your application that meets your project's exact requirements. This image
21+
contains:
2322

24-
* you want to upgrade to a newer Yii version or
23+
* PHP runtime environment (e.g. Apache + PHP module)
24+
* PHP extensions
25+
* Composer packages
26+
27+
This image will hardly ever change unless
28+
29+
* you want to upgrade to a newer PHP or Yii version or
2530
* you want to add a missing PHP extension or composer package.
2631

27-
The actual application image will extend from this base and use the Dockerfile
28-
in `./Dockerfile`.
32+
Its configuration can be found in the `./build` directory:
33+
34+
* `Dockerfile` adds PHP extensions and required system packages
35+
* `composer.json` and `composer.lock` list composer packages
36+
37+
The actual production image extends from this base image and uses `./Dockerfile`.
38+
It only adds your your app sources on top.
2939

30-
In the recommended scenario you would build the base image, upload it to your
31-
own container registry and, reference it in the app's main `./Dockerfile`. This
32-
way all your coworkers will always share the same base image.
40+
In the recommended scenario you would build the base image once then upload
41+
it to your container registry and share it with your co-developers.
3342

34-
If you don't have a container registry you can still use the template. But then
43+
If you don't have a container registry you can still use our template. But then
3544
each developer in your team will have to build the same base image locally.
3645

37-
## 1.2 Configuration with Environment Variables
46+
## 1.2 Runtime Configuration via Environment Variables
3847

3948
We follow docker's principle that containers are configured via environment
40-
variables. This does not include each and every part of the application
41-
configuration of course: Most settings will be hardcoded in `./config/web.php`,
42-
for example URL rules. But the variable runtime parameters like DB credentials
43-
or whether to enable debug mode will be configurable via environment variables.
49+
variables. This only includes runtime configuration, of course: Things like
50+
whether to run in debug mode or DB credentials. Most other settings like for
51+
example URL rules will be hardcoded in `./config/web.php`.
4452

4553
You should continue to follow this principle when developing your app. For
4654
more details also see our
@@ -50,6 +58,8 @@ in this template.
5058

5159
# 2 Initial Project Setup
5260

61+
## 2.1 Download Application Template
62+
5363
First fetch a copy of our application template, for example with composer:
5464

5565
```sh
@@ -58,50 +68,54 @@ composer create-project --no-install codemix/yii2-dockerized myproject
5868

5969
You could also just download the files as ZIP from GitHub.
6070

71+
## 2.2 Update/Add Composer Packages
6172

62-
## 2.1 Preparing Composer Directory
63-
64-
When we later build the application base image the contents of `./build/vendor`
65-
will be copied there. So we first need to install all required composer
66-
packages there.
67-
68-
To do so you can use the [composer](https://hub.docker.com/r/library/composer/)
69-
container:
73+
Go the `./build` directory of the app:
7074

7175
```sh
7276
cd myproject/base
73-
docker-compose run --rm composer install
7477
```
7578

76-
If you want to upgrade all packages to latest versions you could also run `...
77-
composer update` instead. You can now also add more packages that your
78-
application depends on:
79+
Your app may need some additional composer packages besides yii2. We use a
80+
composer container that is based on the official
81+
[composer](https://hub.docker.com/r/library/composer/) image to add them:
82+
7983

8084
```sh
81-
docker-compose run --rm composer require some/package
85+
docker-compose run --rm composer require some/library
8286
```
8387

84-
> **Note:** As docker's composer image may not meet the PHP requirements of
85-
> all your packages you may have to add `--ignore-platform-reqs` to be able to
88+
> **Note:** As docker's composer image may not meet the PHP requirements of all
89+
> your packages you may have to add `--ignore-platform-reqs` to be able to
8690
> install some packages.
8791
88-
## 2.2 Building the Base Image
92+
This will update `composer.json` and `composer.lock` respectively.
93+
94+
You can also run other composer commands, of course. For example if you want to
95+
update all packages listed in `composer.json` to the latest (constrained)
96+
versions, run:
97+
98+
```sh
99+
docker-compose run --rm composer update
100+
```
101+
102+
## 2.3 Build the Base Image
89103

90104
Before you continue with building the base image you should:
91105

92-
* Set a name for the base image in `./build/docker-compose.yml`
93-
* Optionally add more PHP extensions in `./build/Dockerfile`
106+
* Set a tag name for the base image in `./build/docker-compose.yml`
107+
* Use the same tag name in `./docker-compose.yml`
108+
* Optionally add more PHP extensions or system packages in `./build/Dockerfile`
94109

95-
Building the image is straightforward:
110+
Building the image is straightforward. Again from the `./build` directory run:
96111

97112
```sh
98-
cd myproject/base
99113
docker-compose build
100114
```
101115

102-
Now you could upload that image to your container registry.
116+
Now you can upload that image to your container registry.
103117

104-
## 2.3 Cleanup and Initial Commit
118+
## 2.4 Cleanup and Initial Commit
105119

106120
At this point you may want to modify our application template, add some default
107121
configuration and remove those parts that you don't need. Afterwards you are
@@ -110,13 +124,13 @@ ready for the initial commit to your project repository.
110124

111125
# 3 Local Development
112126

113-
During development we map the local app directory into the app container so
114-
that we always run the code that we currently work on. The app container will
115-
use the base image we built before.
127+
During development we map the local app directory into an container that uses
128+
our base image. This way we always run the code that we currently work on.
116129

117-
As local environments may differ (e.g. use different docker network settings)
118-
we usually keep `docker-compose.yml` out of version control. Instead we provide
119-
a `docker-compose-example.yml` with a reasonable example setup.
130+
As your local docker setup may differ from production (e.g. use different
131+
docker network settings) we usually keep `docker-compose.yml` out of version
132+
control. Instead we provide a `docker-compose-example.yml` with a reasonable
133+
example setup.
120134

121135
Since the runtime configuration should happen with environment variables, we
122136
use a `.env` file. We also keep this out of version control and only include a
@@ -132,17 +146,17 @@ cp docker-compose-example.yml docker-compose.yml
132146
cp .env-example .env
133147
```
134148

135-
You should modify those two files e.g. to enable debug mode or configure a
149+
You should modify these two files e.g. to enable debug mode or configure a
136150
database. Then you should be ready to start your container and initialize
137151
your database (if your project has one):
138152

139153
```sh
140154
docker-compose up -d
155+
# Wait some seconds to let the DB container fire up ...
141156
docker-compose exec web ./yii migrate
142157
```
143158

144-
It may take some minutes to download the required docker images before you can
145-
issue the second command. When done, you can access the new app from
159+
When done, you can access the new app from
146160
[http://localhost:8080](http://localhost:8080).
147161

148162
If you see an error about write permissions to `web/assets/`, `runtime/` or
@@ -152,20 +166,18 @@ which is the `www-data` user inside the container.
152166
To fix this, run:
153167

154168
```
155-
docker-compose exec chown www-data web/assets runtime var/sessions
169+
docker-compose exec web chown www-data web/assets runtime var/sessions
156170
```
157171

158172
## 3.2 Development Session
159173

160174
A development session will then usually go like this:
161175

162176
```sh
163-
git pull --ff-only
164177
docker-compose up -d
165178
# edit files, check, tests, ...
166179
git add .
167180
git commit -m 'Implemented stuff'
168-
git push origin my-branch
169181
docker-compose stop
170182
```
171183

@@ -179,12 +191,15 @@ docker-compose exec web ./yiic migrate/create add_column_name
179191
```
180192

181193
> **Note:** You may have to change ownership for files that where created from
182-
> inside the container if you want to write to them on the host system.
194+
> inside the container if you want to write to them on the host system:
195+
>
196+
> chown -R mike migrations/*
197+
>
183198
184199
### 3.2.2 Adding or Updating Composer Packages
185200

186201
Whenever you add new composer packages this requires a rebuild of the base
187-
image. The procedure for this is the same as described in 2.1 and 2.2.
202+
image. The procedure for this is the same as described in 2.2 and 2.3.
188203

189204
### 3.2.3 Working with Complex Local Configuration
190205

build/Dockerfile

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1-
# The base image that provides the PHP runtime and composer packages
2-
# which are requried by the application. You should use docker-compose
3-
# to build/update the image
1+
# Application base image
2+
#
3+
# This image contains:
4+
#
5+
# - PHP runtime
6+
# - PHP extensions
7+
# - Composer packages
48

5-
# Specific version constraint is recommended
9+
10+
# Build stage to install composer packages
11+
FROM composer AS vendor
12+
COPY composer.json /app
13+
COPY composer.lock /app
14+
RUN ["composer", "install"]
15+
16+
17+
# Build stage of the final image
618
FROM php:7.1.11-apache
719

820
# Set up PHP environment
@@ -17,7 +29,6 @@ RUN apt-get update \
1729

1830
# Extensions required by yii2
1931
&& docker-php-ext-install intl \
20-
&& docker-php-ext-install mbstring \
2132

2233
# Optional extensions (modify as needed)
2334
&& docker-php-ext-install pdo_mysql \
@@ -30,6 +41,6 @@ RUN apt-get update \
3041
&& apt-get autoremove -y \
3142
&& rm -r /var/lib/apt/lists/*
3243

33-
COPY vendor /var/www/vendor
44+
COPY --from=vendor /var/www/vendor /var/www/vendor
3445

3546
WORKDIR /var/www/html

build/docker-compose.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
version: '3'
22
services:
33

4-
# The base image that provides the PHP runtime and composer packages
5-
# which are requried by the application. To (re-)build the image use:
4+
# Application base image
65
#
7-
# docker-compose run --rm composer install
8-
# docker-compose build
6+
# This image contains:
7+
#
8+
# - PHP runtime
9+
# - PHP extensions
10+
# - Composer packages
911
#
1012
base:
1113
# Specify a tag name for your base image here:
1214
image: yii2-base-myapp:1.0
1315
build: ./
1416

15-
# The composer container to manage composer packages for the build process
16-
# in ./vendor.
17+
# Composer utilty to manage composer packages
1718
#
1819
# You will usually only ever run one of these commands:
1920
#
@@ -26,5 +27,4 @@ services:
2627
image: composer
2728
volumes:
2829
- ./:/app
29-
- ./:/var/www
3030
entrypoint: composer

0 commit comments

Comments
 (0)