Skip to content

Commit

Permalink
Merge pull request #10 from semaphoreci/tf/update
Browse files Browse the repository at this point in the history
Second Edition
  • Loading branch information
TomFern committed Aug 13, 2021
2 parents b43a01c + 8e9d839 commit 08aab70
Show file tree
Hide file tree
Showing 42 changed files with 331 additions and 224 deletions.
16 changes: 16 additions & 0 deletions .semaphore/pipeline_2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: v1.0
name: Publish to WordPress
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
blocks:
- name: SFTP Upload
task:
jobs:
- name: Upload PDF
commands:
- artifact pull workflow CICD_with_Docker_Kubernetes_Semaphore.pdf
- 'echo "put CICD_with_Docker_Kubernetes_Semaphore.pdf" | sshpass -p "$FTP_PASSWORD" sftp -P $FTP_PORT -o StrictHostKeyChecking=no $FTP_USER@$FTP_HOST:/wp-content/uploads/2020/05/'
secrets:
- name: wordpress-sftp
7 changes: 6 additions & 1 deletion .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ blocks:
- sed -i -e "s/\$REVISION/$(git rev-parse --short HEAD)/g" chapters/01-introduction.md
- make pdf
- ./deps/cpdf cover/cover.pdf build/pdf/CICD_with_Docker_Kubernetes_Semaphore.pdf -o CICD_with_Docker_Kubernetes_Semaphore.pdf
- artifact push workflow build/pdf/CICD_with_Docker_Kubernetes_Semaphore.pdf
- artifact push workflow CICD_with_Docker_Kubernetes_Semaphore.pdf
- name: Make ebook
commands:
- checkout
Expand All @@ -33,3 +33,8 @@ blocks:
- 'curl -L https://github.com/w3c/epubcheck/releases/download/v4.2.4/epubcheck-4.2.4.zip -o epubcheck.zip'
- unzip epubcheck.zip
- java -jar epubcheck-4.2.4/epubcheck.jar CICD_with_Docker_Kubernetes_Semaphore.epub
promotions:
- name: Publish
pipeline_file: pipeline_2.yml
auto_promote:
when: branch = 'master' AND result = 'passed'
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ CHAPTERS_EBOOK = chapters/01-introduction-ebook.md chapters/02-using-docker.md \
chapters/07-tutorial-clouds.md chapters/08-tutorial-deployment.md \
chapters/09-final-words-ebook.md

# handle non-intel archs (eg. Apple M1)
EXTRA_OPTS =
ARCH = $(shell arch)
ifeq ($(ARCH),arm64)
EXTRA_OPTS += --platform linux/amd64
endif

all: book

book: pdf ebook
ebook: epub mobi
docx: $(BUILD)/docx/$(BOOKNAME).docx
pdf: $(BUILD)/pdf/$(BOOKNAME).pdf
epub: $(BUILD)/epub/$(BOOKNAME).epub
mobi: $(BUILD)/mobi/$(BOOKNAME).mobi
Expand All @@ -26,22 +34,26 @@ html: $(BUILD)/html/$(BOOKNAME).html
clean:
rm -r $(BUILD)

$(BUILD)/docx/$(BOOKNAME).docx: $(TITLE) $(CHAPTERS)
mkdir -p $(BUILD)/docx
docker run --rm $(EXTRA_OPTS) --volume `pwd`:/data pandoc/latex:2.6 -f markdown-implicit_figures -H make-code-small.tex -V geometry:margin=1.5in -o /data/$@ $^

$(BUILD)/pdf/$(BOOKNAME).pdf: $(TITLE) $(CHAPTERS)
mkdir -p $(BUILD)/pdf
docker run --rm --volume `pwd`:/data pandoc/latex:2.6 -f markdown-implicit_figures -H make-code-small.tex -V geometry:margin=1.5in -o /data/$@ $^
docker run --rm $(EXTRA_OPTS) --volume `pwd`:/data pandoc/latex:2.6 -f markdown-implicit_figures -H make-code-small.tex -V geometry:margin=1.5in -o /data/$@ $^

# intermediate format for epub, uses small figures
$(BUILD)/html/$(BOOKNAME).html: title.txt $(CHAPTERS_EBOOK)
mkdir -p $(BUILD)/html $(BUILD)/html/figures
cp figures/* $(BUILD)/html/figures
cp figures-ebook/* $(BUILD)/html/figures
docker run --rm --volume `pwd`:/data pandoc/crossref:2.10 -o /data/$@ $^
docker run --rm $(EXTRA_OPTS) --volume `pwd`:/data pandoc/crossref:2.10 -o /data/$@ $^

# kindle-optimized epub
# note: output-profile=tablet converts best to kindle
$(BUILD)/epub/$(BOOKNAME).epub: $(BUILD)/html/$(BOOKNAME).html
mkdir -p $(BUILD)/epub
docker run --rm --volume `pwd`:/data --entrypoint ebook-convert -w /data linuxserver/calibre $^ /data/$@ \
docker run --rm $(EXTRA_OPTS) --volume `pwd`:/data --entrypoint ebook-convert -w /data linuxserver/calibre $^ /data/$@ \
--output-profile tablet \
--chapter "//*[name()='h1' or name()='h2']" \
--publisher "Semaphore" \
Expand Down
17 changes: 15 additions & 2 deletions chapters/01-introduction-ebook.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
\newpage

© 2020 Rendered Text. All rights reserved.
© 2021 Rendered Text. All rights reserved.

This book is open source:
<https://github.com/semaphoreci/book-cicd-docker-kubernetes>

$MONTHYEAR: First edition v1.1 (revision $REVISION)
$MONTHYEAR: Second edition v2.0 (revision $REVISION)

\newpage

Expand Down Expand Up @@ -53,6 +53,19 @@ Chapter 3, "Best Practices for Cloud Native Applications", describes how both ou

Chapter 4, "A Complete CI/CD Pipeline", is a step-by-step guide to implementing a CI/CD pipeline with Semaphore that builds, tests, and deploys a Dockerized microservice to Kubernetes.

## Changes in the Second Edition

A few changes were introduced in this second edition:

- Moved to Kubernetes version v1.20. All commands and actions were tested with this version.
- Added comments about accessing services in local development Kubernetes clusters.
- Added mention of new CI/CD features in Semaphore: parameterized pipelines, test results, code change detection.
- DigitalOcean deployment now uses their Private Container Registry service instead of Docker Hub.
- Updated setup steps for DigitalOcean, Google Cloud, and AWS.
- Updated UI screenshots using higher resolution.
- Modified deployment tutorial to use parametrized promotions.
- Other minor fixes.

## How to Contact Us

We would very much love to hear your feedback after reading this book. What did you like and learn? What could be improved? Is there something we could explain further?
Expand Down
26 changes: 21 additions & 5 deletions chapters/01-introduction.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
\newpage

© 2020 Rendered Text. All rights reserved.
© 2021 Rendered Text. All rights reserved.

This work is licensed under Creative Commmons
This work is licensed under Creative Commons
Attribution-NonCommercial-NoDerivatives 4.0 International.
To view a copy of this license, visit
<https://creativecommons.org/licenses/by-nc-nd/4.0>
Expand All @@ -13,7 +13,7 @@ This book is open source:
Published on the Semaphore website:
[https://semaphoreci.com](https://semaphoreci.com/?utm_source=ebook&utm_medium=pdf&utm_campaign=cicd-docker-kubernetes-semaphore)

$MONTHYEAR: First edition v1.0 (revision $REVISION)
$MONTHYEAR: Second edition v2.0 (revision $REVISION)

\newpage

Expand All @@ -29,16 +29,19 @@ To maximize the rate of learning, we must minimize the time to try things.

In software development, the cloud has been a critical factor in increasing the speed of building innovative products.

Today there's a massive change going on in the way we're using the cloud. To borrow the metaphor from Adrian Cockroft, who led cloud architecture at Netflix, we need to think of cloud resources not as long-lived and stable pets, but as transitory and disposable cattle.
Today there's a massive change going on in the way we're using the cloud. To borrow the metaphor from Adrian Cockroft[^cockroft], who led cloud architecture at Netflix, we need to think of cloud resources not as long-lived and stable pets, but as transitory and disposable cattle.

Doing so successfully, however, requires our applications to adapt. They need to be disposable and horizontally scalable. They should have a minimal divergence between development and production so that we can continuously deploy them multiple times per day.

A new generation of tools has democratized the way of building such *cloud native* software. Docker container is now the standard way of packaging software in a way that can be deployed, scaled, and dynamically distributed on any cloud. And Kubernetes is the leading platform to run containers in production. Over time new platforms with higher-order interfaces will emerge, but it's almost certain that they will be based on Kubernetes.
A new generation of tools has democratized the way of building such *cloud native* software. Docker containers are now the standard way of packaging software in a way that can be deployed, scaled, and dynamically distributed on any cloud. And Kubernetes is the leading platform to run containers in production. Over time new platforms with higher-order interfaces will emerge, but it's almost certain that they will be based on Kubernetes.

The great opportunity comes potentially at a high cost. Countless organizations have spent many engineering months learning how to deliver their apps with this new stack, making sense of disparate information from the web. Delaying new features by months is not exactly the outcome any business wants when engineers announce that they're moving to new tools that are supposed to make them more productive.

This is where this book comes into play, dear reader. Our goal is to help you transition to delivering cloud native apps quickly. The fundamentals don't change: we still need a rock-solid delivery pipeline, which automatically configures, builds, tests, and deploys code. This book shows you how to do that in a cloud native way — so you can focus on building great products and solutions.

[^cockroft]: Currently VP Amazon Sustainability Architecture at Amazon
_https://twitter.com/adrianco_

\newpage

## Who Is This Book For, and What Does It Cover?
Expand Down Expand Up @@ -67,6 +70,19 @@ Chapter 3, "Best Practices for Cloud Native Applications", describes how both ou

Chapter 4, "A Complete CI/CD Pipeline", is a step-by-step guide to implementing a CI/CD pipeline with Semaphore that builds, tests, and deploys a Dockerized microservice to Kubernetes.

## Changes in the Second Edition

A few changes were introduced in this second edition:

- Moved to Kubernetes version v1.20. All commands and actions were tested with this version.
- Added comments about accessing services in local development Kubernetes clusters.
- Added mention of new CI/CD features in Semaphore: parameterized pipelines, test results, code change detection.
- DigitalOcean deployment now uses their Private Container Registry service instead of Docker Hub.
- Updated setup steps for DigitalOcean, Google Cloud, and AWS.
- Updated UI screenshots using higher resolution.
- Modified deployment tutorial to use parametrized promotions.
- Other minor fixes.

## How to Contact Us

We would very much love to hear your feedback after reading this book. What did you like and learn? What could be improved? Is there something we could explain further?
Expand Down
10 changes: 5 additions & 5 deletions chapters/02-using-docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ We will see how to get there.

After we build container images, we can run them consistently on any server environment. Automating server installation would usually require steps (and domain knowledge) specific to our infrastructure. For instance, if we are using AWS EC2, we may use AMI (Amazon Machine Images), but these images are different (and built differently) from the ones used on Azure, Google Cloud, or a private OpenStack cluster.

Configuration management systems (like Ansible, Chef, Puppet, or Salt) help us by describing our servers and their configuration as manifests that live in version-controlled source repositories. This helps, but writing these manifests is no easy task, and they don’t guarantee reproducible execution. These manifests have to be adapted when switching distributions, distribution versions, and sometimes even from a cloud provider to another, because they would use different network interface or disk naming, for instance.
Configuration management systems (like Ansible, Chef, Puppet, or Salt) help us by describing our servers and their configuration as manifests that live in version-controlled source repositories. This helps, but writing these manifests is no easy task, and they don’t guarantee reproducible execution. These manifests have to be adapted when switching distributions, distribution versions, and sometimes even from a cloud provider to another, because they would use different network interfaces or disk naming, for instance.

Once we have installed the Docker Engine (the most popular option), it can run any container image and effectively abstract these environment discrepancies.

The ability to stage up new environments easily and reliably gives us exactly what we need to set up CI/CD (continuous integration and continuous delivery). We will see how to get there. Ultimately, it means that advanced techniques, such as blue/green deployments, or immutable infrastructure, become accessible to us, instead of being a privilege of larger organizations able to spend a lot of time to build their perfect custom tooling.
The ability to stage new environments easily and reliably gives us exactly what we need to set up CI/CD (continuous integration and continuous delivery). We will see how to get there. Ultimately, it means that advanced techniques, such as blue/green deployments, or immutable infrastructure, become accessible to us, instead of being a privilege of larger organizations able to spend a lot of time to build their perfect custom tooling.

### 1.1.3 Less Risky Releases

Expand All @@ -63,7 +63,7 @@ As a result, we can deploy with more confidence, because we know that if somethi

## 1.2 A Roadmap to Adopting Docker

The following roadmap works for organizations and teams of all size, regardless of their existing knowledge of containers. Even better, this roadmap will give you tangible benefits at each step, so that the gains realized give you more confidence into the whole process.
The following roadmap works for organizations and teams of all sizes, regardless of their existing knowledge of containers. Even better, this roadmap will give you tangible benefits at each step, so that the gains realized give you more confidence in the whole process.

Sounds too good to be true?

Expand All @@ -89,7 +89,7 @@ If we have a component that is tricky enough to require a tool like Vagrant to r

### 1.2.2 Writing the First Dockerfile

There are various ways to write your first Dockerfile, and none of them is inherently right or wrong. Some people prefer to follow the existing environment as close as possible. For example, if you're currently using PHP 7.2 with Apache 2.4, and have some very specific Apache configuration and `.htaccess` files? Sure, makes sense to put that in containers. But if you prefer to start anew from your `.php` files, serve them with PHP FPM, and host the static assets from a separate NGINX container, that’s fine too. Either way, the [official PHP images](https://hub.docker.com/r/_/php/) got us covered.
There are various ways to write your first Dockerfile, and none of them is inherently right or wrong. Some people prefer to follow the existing environment as closely as possible. For example, if you're currently using PHP 7.2 with Apache 2.4, and have some very specific Apache configuration and `.htaccess` files? Sure, it makes sense to put that in containers. But if you prefer to start anew from your `.php` files, serve them with PHP FPM, and host the static assets from a separate NGINX container, that’s fine too. Either way, the [official PHP images](https://hub.docker.com/r/_/php/) got us covered.

During this phase, we’ll want to make sure that the team working on that service has Docker installed on their machine, but only a few people will have to meddle with Docker at this point. They will be leveling the field for everyone else.

Expand All @@ -104,7 +104,7 @@ CMD ["ruby", "hasher.rb"]
EXPOSE 80
```

Once we have a working Dockerfile for an app, we can start using this container image as the official development environment for this specific service or component. If we picked a fast-moving one, we will see the benefits very quickly, since Docker makes library and other dependency upgrades completely seamless. Rebuilding the entire environment with a different language version now becomes effortless. And if we realize after a difficult upgrade that the new version doesn’t work as well, rolling back is just as easy and instantaneous, because Docker keeps a cache of previous image builds around.
Once we have a working Dockerfile for an app, we can start using this container image as the official development environment for this specific service or component. If we pick a fast-moving one, we will see the benefits very quickly, since Docker makes library and other dependency upgrades completely seamless. Rebuilding the entire environment with a different language version now becomes effortless. And if we realize after a difficult upgrade that the new version doesn’t work as well, rolling back is just as easy and instantaneous, because Docker keeps a cache of previous image builds around.

### 1.2.3 Writing More Dockerfiles

Expand Down

0 comments on commit 08aab70

Please sign in to comment.