Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Try This At HomeTry This At Home
Building a Personal Docker SwarmBuilding a Personal Docker Swarm
Matthew Clemente
@mjclem...
A Familiar StoryA Familiar Story
» Adobe ColdFusion 10 /11
» Windows Server 2008
» Microsoft IIS
» Rackspace
» FTP Deploym...
Nyan Whale originally by Andrew Kennedy
Every ConferenceEvery Conference
Looking for DirectionLooking for Direction
Legacy
Infrastructure
Scriptable
Scalable
Containerized
12-Factor App
CI/CD
Mic...
Bret Fisher ResourcesBret Fisher Resources
»
»
»
»
»
»
»
»
»
BretFisher.com
Github AMA
Github Sample Swarm tools
Podcast
D...
Learned a LotLearned a Lot
Still don't know how to do this.
¯_(ツ)_/¯
You'll learn more onYou'll learn more on
the first day ofthe first day of
production than theproduction than the
previous ...
DoingDoing
isis
LearningLearning
All genuine learningAll genuine learning
comes throughcomes through
experience.experience.
John Dewey, Experience & Educat...
How do IHow do I
actuallyactually do do
this?this?
Don't tell me that it's possible without
showing me how!
GoalGoal
Learning By Doing
Concrete Examples
What This Talk Is Not:What This Talk Is Not:
» Intro to Docker
» Intro to Swarm
» Comprehensive
» "The Best Way"*
» Starting point
» Practical and concrete
» Code Samples!
» Necessarily limited
What This Talk Is:What This Talk Is:
Tooling and ServicesTooling and Services
» Structure my project?
» Minimize divergence between Dev and Prod?
» Use environment variables?
» Manage sensitive inform...
It can be doneIt can be done
_ಠ_ಠ
Begin with the endBegin with the end
in mind.in mind.
Stephen Covey, The 7 Habits of Highly Effective People, 1989
https://gitlab.com/mjclemente/api­mashup­cfml­swarm/ 
https://gitlab.com/mjclemente/starter­swarm­cfml 
Project StructureProject Structure
.
├── .env
├── .gitlab-ci.yml
├── .secrets
│   ├── cfml.admin.password.dev
│   └── cfml...
Sharing ConfigurationSharing Configuration
.
├── docker-compose.override.yml
├── docker-compose.prod.yml
└── docker-compos...
Sharing ConfigurationSharing Configuration
$ docker-compose 
-f docker-compose.yml 
-f docker-compose.prod.yml 
up
# Works...
version: "3.7"
services:
cfml:
image: "registry.gitlab.com/${CI_PROJE
build:
context: .
dockerfile: ./build/cfml/Dockerfil...
the last slidethe last slide
was awas a lielie
The real worldThe real world
doesn't look likedoesn't look like
demos.demos.
┻━┻︵(°□°)/ ︵┻━┻
Swarm CreationSwarm Creation
https://github.com/mjclemente/do­swarm­create
Swarm CreationSwarm Creation
doctl
# Create Docker Droplet
doctl compute droplet create test
--size 1gb
--image docker-18-...
Swarm CreationSwarm Creation
Swarm Creation Script for DigitalOcean
Swarm InitializedSwarm Initialized
https://12factor.net/config
https://github.com/Ortus­Solutions/docker­commandbox#environment­variables
https://docs.docker...
.env
CI_PROJECT_NAMESPACE=mjclemente
OTHER_SETTING=
FOO=bar
1
2
3
https://direnv.net/
${Env} in Compose${Env} in Compose
image:
"registry.gitlab.com/${CI_PROJECT_NAMESPACE}/starter-swarm-
cfml/cfml:${BUILD_TA...
${Env} in CFConfig.json${Env} in CFConfig.json
"adminPassword":"${CF_ADMINPASSWORD}",
{1
2
"applicationListener":"modern",...
Env variables prone to leakEnv variables prone to leak
Docker Swarm SecretsDocker Swarm Secrets
» Immutable by design
» Account for rotation
» Account for Dev and Production
» T...
secrets:
cfml.admin.password:
external: true
name: cfml.admin.password.v1
secrets:
cfml.admin.password:
external: false
fi...
( ••)( ••)
( ••)>⌐■-■( ••)>⌐■-■
(⌐■_■) #Secrets!(⌐■_■) #Secrets!
https://gitlab.com/mjclemente/starter­swarm­cfml/blob/mas...
CI/CD with Gitlab RunnersCI/CD with Gitlab Runners
» Configured via .gitlab-ci.yml
» Run automagically
» Multiple types of ...
https://gitlab.com/mjclemente/starter­swarm­cfml/blob/master/.gitlab­ci.yml
₍₍ ᕕ( ಠ‿ಠ)ᕗ
.gitlab­ci.yml
» File containing all definitions of how
your project should be built
https://docs.gitlab.com/ee/ci/yaml/
before_script:
before_script:
## We're gonna log into the gitlab registry, as that's where
these images are stored
- docke...
Tagging Custom ImagesTagging Custom Images
» Don't just use "latest"
» Combination of date and commit
before_script:
- exp...
Control Pipeline StagesControl Pipeline Stages
deploy:
stage: deploy
only:
- deploy
except:
variables:
- $CI_COMMIT_MESSAG...
Building Custom ImagesBuilding Custom Images
build:
stage: build
only:
- deploy
script:
## Build the image, with the build...
Stack DeploymentStack Deployment
Stack DeploymentStack Deployment
deploy:
stage: deploy
script:
- [a lot of SSH related config]
## Enable SSH functionality...
» Swarm's missing UI
» Configuration and management
» Separate from application stack
PortainerPortainer
»
»
»
Hybrid license
Easy installation (ForgeBox)
Some manual configuration
FusionReactor (Cloud)FusionReactor (Cloud)
» Required in multi-node Swarms
» Free options
» Provided via (beta) Lucee Extensions
» Paid options are superior
Sessions...
SSLSSL
https://blog.filippo.io/mkcert­valid­https­certificates­for­localhost/
https://letsencrypt.org/docs/certificates­fo...
All things areAll things are
difficult before theydifficult before they
are easy.are easy.
Dr. Thomas Fuller, Gnomologia, ...
Try This At HomeTry This At Home
Building a Personal Docker SwarmBuilding a Personal Docker Swarm
Matthew Clemente
@mjclem...
ITB2019 Try This At Home: Building a Personal Docker Swarm - Matt Clemente
ITB2019 Try This At Home: Building a Personal Docker Swarm - Matt Clemente
ITB2019 Try This At Home: Building a Personal Docker Swarm - Matt Clemente
Upcoming SlideShare
Loading in …5
×

ITB2019 Try This At Home: Building a Personal Docker Swarm - Matt Clemente

89 views

Published on

There’s no shortage of excitement surrounding Docker. But while many developers are familiar with containers in the abstract (they’ve installed Docker on their machines, watched online courses, and played with images locally), they’re unsure of the concrete steps needed to deploy CFML apps to Swarm.

Since it’s said that you learn more on your first day of production than all the time beforehand, why wait? In this session, we’ll take a API Mashup project from local development to replicated cloud deployment on a multi-node Swarm. Containerizing a small, fun application provides a great opportunity for acquiring real-world knowledge and hands-on experience. At each step in the process, I’ll share the practical approaches I’ve learned, with the goal of removing obstacles, both real and imagined, that prevent ColdFusion developers from using Swarm.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

ITB2019 Try This At Home: Building a Personal Docker Swarm - Matt Clemente

  1. 1. Try This At HomeTry This At Home Building a Personal Docker SwarmBuilding a Personal Docker Swarm Matthew Clemente @mjclemente @mjclemente84 blog.mattclemente.com @mjclemente
  2. 2. A Familiar StoryA Familiar Story » Adobe ColdFusion 10 /11 » Windows Server 2008 » Microsoft IIS » Rackspace » FTP Deployments » Dev Server (in basement)
  3. 3. Nyan Whale originally by Andrew Kennedy Every ConferenceEvery Conference
  4. 4. Looking for DirectionLooking for Direction Legacy Infrastructure Scriptable Scalable Containerized 12-Factor App CI/CD Microservices
  5. 5. Bret Fisher ResourcesBret Fisher Resources » » » » » » » » » BretFisher.com Github AMA Github Sample Swarm tools Podcast Docker Mastery Docker Swarm Mastery Docker Mastery for Node.js Taking Docker to Production Building Your Swarm Production Stack
  6. 6. Learned a LotLearned a Lot Still don't know how to do this. ¯_(ツ)_/¯
  7. 7. You'll learn more onYou'll learn more on the first day ofthe first day of production than theproduction than the previous two months.previous two months. Bret Fisher, , DockerCon Europe 2017Taking Docker to Production
  8. 8. DoingDoing isis LearningLearning
  9. 9. All genuine learningAll genuine learning comes throughcomes through experience.experience. John Dewey, Experience & Education, 1938
  10. 10. How do IHow do I actuallyactually do do this?this? Don't tell me that it's possible without showing me how!
  11. 11. GoalGoal Learning By Doing Concrete Examples
  12. 12. What This Talk Is Not:What This Talk Is Not: » Intro to Docker » Intro to Swarm » Comprehensive » "The Best Way"*
  13. 13. » Starting point » Practical and concrete » Code Samples! » Necessarily limited What This Talk Is:What This Talk Is:
  14. 14. Tooling and ServicesTooling and Services
  15. 15. » Structure my project? » Minimize divergence between Dev and Prod? » Use environment variables? » Manage sensitive information? » Use a private image registry? » Tag images properly? » Add Lucee extensions? » Configure CI/CD for deployment? » Monitor with FusionReactor? » Handle sessions? » File a tax extension? How Do I...How Do I...
  16. 16. It can be doneIt can be done _ಠ_ಠ
  17. 17. Begin with the endBegin with the end in mind.in mind. Stephen Covey, The 7 Habits of Highly Effective People, 1989
  18. 18. https://gitlab.com/mjclemente/api­mashup­cfml­swarm/ 
  19. 19. https://gitlab.com/mjclemente/starter­swarm­cfml 
  20. 20. Project StructureProject Structure . ├── .env ├── .gitlab-ci.yml ├── .secrets │   ├── cfml.admin.password.dev │   └── cfml.admin.password.v1 ├── app │   ├── .CFConfig.json │   ├── box.json │   ├── server.json │   └── wwwroot │   └── index.cfm ├── build │   ├── cfml │   │   ├── Dockerfile │   │   └── config │   │   └── extensions │   │   └── extension-loganalyzer-2.3.2.16.lex │   └── deploy-secrets.sh ├── docker-compose.override.yml ├── docker-compose.prod.yml └── docker-compose.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ├── .env ├── .secrets │   ├── cfml.admin.password.dev │   └── cfml.admin.password.v1 .1 2 ├── .gitlab-ci.yml3 4 5 6 ├── app7 │   ├── .CFConfig.json8 │   ├── box.json9 │   ├── server.json10 │   └── wwwroot11 │   └── index.cfm12 ├── build13 │   ├── cfml14 │   │   ├── Dockerfile15 │   │   └── config16 │   │   └── extensions17 │   │   └── extension-loganalyzer-2.3.2.16.lex18 │   └── deploy-secrets.sh19 ├── docker-compose.override.yml20 ├── docker-compose.prod.yml21 └── docker-compose.yml22 ├── .gitlab-ci.yml .1 ├── .env2 3 ├── .secrets4 │   ├── cfml.admin.password.dev5 │   └── cfml.admin.password.v16 ├── app7 │   ├── .CFConfig.json8 │   ├── box.json9 │   ├── server.json10 │   └── wwwroot11 │   └── index.cfm12 ├── build13 │   ├── cfml14 │   │   ├── Dockerfile15 │   │   └── config16 │   │   └── extensions17 │   │   └── extension-loganalyzer-2.3.2.16.lex18 │   └── deploy-secrets.sh19 ├── docker-compose.override.yml20 ├── docker-compose.prod.yml21 └── docker-compose.yml22 ├── app │   ├── .CFConfig.json │   ├── box.json │   ├── server.json │   └── wwwroot │   └── index.cfm .1 ├── .env2 ├── .gitlab-ci.yml3 ├── .secrets4 │   ├── cfml.admin.password.dev5 │   └── cfml.admin.password.v16 7 8 9 10 11 12 ├── build13 │   ├── cfml14 │   │   ├── Dockerfile15 │   │   └── config16 │   │   └── extensions17 │   │   └── extension-loganalyzer-2.3.2.16.lex18 │   └── deploy-secrets.sh19 ├── docker-compose.override.yml20 ├── docker-compose.prod.yml21 └── docker-compose.yml22 ├── build │   ├── cfml │   │   ├── Dockerfile │   │   └── config │   │   └── extensions │   │   └── extension-loganalyzer-2.3.2.16.lex │   └── deploy-secrets.sh .1 ├── .env2 ├── .gitlab-ci.yml3 ├── .secrets4 │   ├── cfml.admin.password.dev5 │   └── cfml.admin.password.v16 ├── app7 │   ├── .CFConfig.json8 │   ├── box.json9 │   ├── server.json10 │   └── wwwroot11 │   └── index.cfm12 13 14 15 16 17 18 19 ├── docker-compose.override.yml20 ├── docker-compose.prod.yml21 └── docker-compose.yml22 ├── docker-compose.override.yml ├── docker-compose.prod.yml └── docker-compose.yml .1 ├── .env2 ├── .gitlab-ci.yml3 ├── .secrets4 │   ├── cfml.admin.password.dev5 │   └── cfml.admin.password.v16 ├── app7 │   ├── .CFConfig.json8 │   ├── box.json9 │   ├── server.json10 │   └── wwwroot11 │   └── index.cfm12 ├── build13 │   ├── cfml14 │   │   ├── Dockerfile15 │   │   └── config16 │   │   └── extensions17 │   │   └── extension-loganalyzer-2.3.2.16.lex18 │   └── deploy-secrets.sh19 20 21 22 https://gitlab.com/mjclemente/starter­swarm­cfml
  21. 21. Sharing ConfigurationSharing Configuration . ├── docker-compose.override.yml ├── docker-compose.prod.yml └── docker-compose.yml 1 2 3 4 ├── docker-compose.override.yml └── docker-compose.yml .1 2 ├── docker-compose.prod.yml3 4 ├── docker-compose.prod.yml └── docker-compose.yml .1 ├── docker-compose.override.yml2 3 4  Understanding Multiple Compose Files Bret Fisher AMA on docker­compose.override.yml $ docker-compose up Minimize Divergence Between Dev and ProdMinimize Divergence Between Dev and Prod
  22. 22. Sharing ConfigurationSharing Configuration $ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up # Works if not dependent on Swarm features 1 2 3 4 5 -f docker-compose.prod.yml $ docker-compose 1 -f docker-compose.yml 2 3 up4 # Works if not dependent on Swarm features5 -f docker-compose.yml $ docker-compose 1 2 -f docker-compose.prod.yml 3 up4 # Works if not dependent on Swarm features5 -f docker-compose.yml -f docker-compose.prod.yml $ docker-compose 1 2 3 up4 # Works if not dependent on Swarm features5 $ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up # Works if not dependent on Swarm features 1 2 3 4 5 docker stack deploy -c docker-compose.yml -c docker-compose.prod.yml test # For Swarm deployments 1 2 3 4 5 -c docker-compose.prod.yml docker stack deploy 1 -c docker-compose.yml 2 3 test4 # For Swarm deployments5 -c docker-compose.yml docker stack deploy 1 2 -c docker-compose.prod.yml 3 test4 # For Swarm deployments5 -c docker-compose.yml -c docker-compose.prod.yml docker stack deploy 1 2 3 test4 # For Swarm deployments5 docker stack deploy -c docker-compose.yml -c docker-compose.prod.yml test # For Swarm deployments 1 2 3 4 5 Minimize Divergence Between Dev and ProdMinimize Divergence Between Dev and Prod
  23. 23. version: "3.7" services: cfml: image: "registry.gitlab.com/${CI_PROJE build: context: . dockerfile: ./build/cfml/Dockerfile environment: PORT: 8080 SSL_PORT: 8443 cfconfigfile: .CFConfig.json cfconfig_inspectTemplate: never secrets: - source: cfml.admin.password target: cfml.admin.password ports: - target: 8080 published: 80 - target: 8443 published: 443 networks: internal: driver: overlay secrets: cfml.admin.password: external: true name: cfml.admin.password.v1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 cfconfig_inspectTemplate: never version: "3.7"1 2 services:3 cfml:4 image: "registry.gitlab.com/${CI_PROJE5 build:6 context: .7 dockerfile: ./build/cfml/Dockerfile8 environment:9 PORT: 808010 SSL_PORT: 844311 cfconfigfile: .CFConfig.json12 13 secrets:14 - source: cfml.admin.password15 target: cfml.admin.password16 ports:17 - target: 808018 published: 8019 - target: 844320 published: 44321 22 networks:23 internal:24 driver: overlay25 26 secrets:27 cfml.admin.password:28 external: true29 name: cfml.admin.password.v130 networks: internal: driver: overlay version: "3.7"1 2 services:3 cfml:4 image: "registry.gitlab.com/${CI_PROJE5 build:6 context: .7 dockerfile: ./build/cfml/Dockerfile8 environment:9 PORT: 808010 SSL_PORT: 844311 cfconfigfile: .CFConfig.json12 cfconfig_inspectTemplate: never13 secrets:14 - source: cfml.admin.password15 target: cfml.admin.password16 ports:17 - target: 808018 published: 8019 - target: 844320 published: 44321 22 23 24 25 26 secrets:27 cfml.admin.password:28 external: true29 name: cfml.admin.password.v130 secrets: cfml.admin.password: external: true name: cfml.admin.password.v1 version: "3.7"1 2 services:3 cfml:4 image: "registry.gitlab.com/${CI_PROJE5 build:6 context: .7 dockerfile: ./build/cfml/Dockerfile8 environment:9 PORT: 808010 SSL_PORT: 844311 cfconfigfile: .CFConfig.json12 cfconfig_inspectTemplate: never13 secrets:14 - source: cfml.admin.password15 target: cfml.admin.password16 ports:17 - target: 808018 published: 8019 - target: 844320 published: 44321 22 networks:23 internal:24 driver: overlay25 26 27 28 29 30 version: "3.7" services: cfml: volumes: - ./app:/app environment: cfconfig_inspectTemplate: always ports: - target: 8080 published: 8080 - target: 8443 published: 8443 networks: internal: driver: bridge secrets: cfml.admin.password: external: false file: ./.secrets/cfml.admin.password.dev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 cfconfig_inspectTemplate: always version: "3.7"1 2 services:3 cfml:4 volumes:5 - ./app:/app6 environment:7 8 ports:9 - target: 808010 published: 808011 - target: 844312 published: 844313 14 networks:15 internal:16 driver: bridge17 18 secrets:19 cfml.admin.password:20 external: false21 file: ./.secrets/cfml.admin.password.dev22 networks: internal: driver: bridge version: "3.7"1 2 services:3 cfml:4 volumes:5 - ./app:/app6 environment:7 cfconfig_inspectTemplate: always8 ports:9 - target: 808010 published: 808011 - target: 844312 published: 844313 14 15 16 17 18 secrets:19 cfml.admin.password:20 external: false21 file: ./.secrets/cfml.admin.password.dev22 secrets: cfml.admin.password: external: false file: ./.secrets/cfml.admin.password.dev version: "3.7"1 2 services:3 cfml:4 volumes:5 - ./app:/app6 environment:7 cfconfig_inspectTemplate: always8 ports:9 - target: 808010 published: 808011 - target: 844312 published: 844313 14 networks:15 internal:16 driver: bridge17 18 19 20 21 22 docker­compose.override.ymldocker­compose.yml
  24. 24. the last slidethe last slide was awas a lielie
  25. 25. The real worldThe real world doesn't look likedoesn't look like demos.demos. ┻━┻︵(°□°)/ ︵┻━┻
  26. 26. Swarm CreationSwarm Creation
  27. 27. https://github.com/mjclemente/do­swarm­create
  28. 28. Swarm CreationSwarm Creation doctl # Create Docker Droplet doctl compute droplet create test --size 1gb --image docker-18-04 --region nyc1 # List Droplets doctl compute droplet list #Delete a Droplet doctl compute droplet delete 123456 #List SSH Key Ids and Names doctl compute droplet list --format "ID,Name" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (Official DigitalOcean Command­Line Client)
  29. 29. Swarm CreationSwarm Creation Swarm Creation Script for DigitalOcean
  30. 30. Swarm InitializedSwarm Initialized
  31. 31. https://12factor.net/config https://github.com/Ortus­Solutions/docker­commandbox#environment­variables https://docs.docker.com/compose/environment­variables/ Environment VariablesEnvironment Variables » Environment for configuration » Modular and easy to change » Managed in .env file
  32. 32. .env CI_PROJECT_NAMESPACE=mjclemente OTHER_SETTING= FOO=bar 1 2 3 https://direnv.net/
  33. 33. ${Env} in Compose${Env} in Compose image: "registry.gitlab.com/${CI_PROJECT_NAMESPACE}/starter-swarm- cfml/cfml:${BUILD_TAG:-latest}" version: "3.7"1 2 services:3 cfml:4 5 build:6 context: .7 dockerfile: ./build/cfml/Dockerfile8 environment:9 PORT: 808010 SSL_PORT: 844311 cfconfigfile: .CFConfig.json12 cfconfig_inspectTemplate: never13 CF_ADMINPASSWORD: <<SECRET:cfml.admin.password>>14 secrets:15 - source: cfml.admin.password16 target: cfml.admin.password17 environment: PORT: 8080 SSL_PORT: 8443 cfconfigfile: .CFConfig.json cfconfig_inspectTemplate: never CF_ADMINPASSWORD: <<SECRET:cfml.admin.password>> version: "3.7"1 2 services:3 cfml:4 image: "registry.gitlab.com/${CI_PROJECT_NAMESPACE}/starter-swarm- cfml/cfml:${BUILD_TAG:-latest}" 5 build:6 context: .7 dockerfile: ./build/cfml/Dockerfile8 9 10 11 12 13 14 secrets:15 - source: cfml.admin.password16 target: cfml.admin.password17
  34. 34. ${Env} in CFConfig.json${Env} in CFConfig.json "adminPassword":"${CF_ADMINPASSWORD}", {1 2 "applicationListener":"modern",3 "applicationMode":"curr2root",4 "applicationTimeout":"1,0,0,0",5 "cacheDefaultFile":"",6 "cacheDefaultFunction":"",7 "cacheDefaultHTTP":"",8 "cacheDefaultInclude":"",9 "cacheDefaultObject":"object",10 "cacheDefaultQuery":"",11 "cacheDefaultResource":"",12 "cacheDefaultTemplate":"",13 "cacheDefaultWebservice":"",14 "caches":{},15 "CGIReadOnly":"true",16 "clientCookies":"true",17 (Same behavior in server.json)
  35. 35. Env variables prone to leakEnv variables prone to leak
  36. 36. Docker Swarm SecretsDocker Swarm Secrets » Immutable by design » Account for rotation » Account for Dev and Production » Team conventions are essential https://docs.docker.com/engine/swarm/secrets/ https://docs.docker.com/compose/compose­file/#secrets
  37. 37. secrets: cfml.admin.password: external: true name: cfml.admin.password.v1 secrets: cfml.admin.password: external: false file: ./.secrets/cfml.admin.password.dev docker­compose.override.ymldocker­compose.yml version: "3.7" services: cfml: ... environment: PORT: 8080 SSL_PORT: 8443 cfconfigfile: .CFConfig.json cfconfig_inspectTemplate: never CF_ADMINPASSWORD: <<SECRET:cfml.admin.password>> secrets: - source: cfml.admin.password target: cfml.admin.password
  38. 38. ( ••)( ••) ( ••)>⌐■-■( ••)>⌐■-■ (⌐■_■) #Secrets!(⌐■_■) #Secrets! https://gitlab.com/mjclemente/starter­swarm­cfml/blob/master/build/deploy­secrets.sh
  39. 39. CI/CD with Gitlab RunnersCI/CD with Gitlab Runners » Configured via .gitlab-ci.yml » Run automagically » Multiple types of runners » Use a dedicated SSH Key https://docs.gitlab.com/ee/ci/quick_start/
  40. 40. https://gitlab.com/mjclemente/starter­swarm­cfml/blob/master/.gitlab­ci.yml ₍₍ ᕕ( ಠ‿ಠ)ᕗ
  41. 41. .gitlab­ci.yml » File containing all definitions of how your project should be built https://docs.gitlab.com/ee/ci/yaml/
  42. 42. before_script: before_script: ## We're gonna log into the gitlab registry, as that's where these images are stored - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com ## Git needed to get the date from the commit sha - apk add git ## So we can see what's going on in the logs - docker info ## setup environment variables - [configuration continues] 1 2 3 4 5 6 7 8 9 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com before_script:1 ## We're gonna log into the gitlab registry, as that's where these images are stored 2 3 ## Git needed to get the date from the commit sha4 - apk add git5 ## So we can see what's going on in the logs6 - docker info7 ## setup environment variables8 - [configuration continues]9 - apk add git before_script:1 ## We're gonna log into the gitlab registry, as that's where these images are stored 2 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com 3 ## Git needed to get the date from the commit sha4 5 ## So we can see what's going on in the logs6 - docker info7 ## setup environment variables8 - [configuration continues]9 before_script: ## We're gonna log into the gitlab registry, as that's where these images are stored - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com ## Git needed to get the date from the commit sha - apk add git ## So we can see what's going on in the logs - docker info ## setup environment variables - [configuration continues] 1 2 3 4 5 6 7 8 9 Getting everything set up .gitlab­ci.yml https://docs.gitlab.com/ee/ci/yaml/#before_script­and­after_script
  43. 43. Tagging Custom ImagesTagging Custom Images » Don't just use "latest" » Combination of date and commit before_script: - export COMMIT_TIME=$(git show -s --format=%ci $CI_COMMIT_SHA) - export COMMIT_TIME_SHORT=$(echo $COMMIT_TIME | head -c10) - export BUILD_TAG="${COMMIT_TIME_SHORT}_$CI_COMMIT_SHORT_SHA" 1 - [earlier configuration]2 ## Use git `show` with --format=%ci to get ISO 8601 date3 4 ## Use first 10 characters of the datetime (ie: 2019-03-19)5 6 7 - export COMMIT_TIME=$(git show -s --format=%ci $CI_COMMIT_SHA) before_script:1 - [earlier configuration]2 ## Use git `show` with --format=%ci to get ISO 8601 date3 4 ## Use first 10 characters of the datetime (ie: 2019-03-19)5 - export COMMIT_TIME_SHORT=$(echo $COMMIT_TIME | head -c10)6 - export BUILD_TAG="${COMMIT_TIME_SHORT}_$CI_COMMIT_SHORT_SHA"7 - export COMMIT_TIME_SHORT=$(echo $COMMIT_TIME | head -c10) before_script:1 - [earlier configuration]2 ## Use git `show` with --format=%ci to get ISO 8601 date3 - export COMMIT_TIME=$(git show -s --format=%ci $CI_COMMIT_SHA)4 ## Use first 10 characters of the datetime (ie: 2019-03-19)5 6 - export BUILD_TAG="${COMMIT_TIME_SHORT}_$CI_COMMIT_SHORT_SHA"7 - export BUILD_TAG="${COMMIT_TIME_SHORT}_$CI_COMMIT_SHORT_SHA" before_script:1 - [earlier configuration]2 ## Use git `show` with --format=%ci to get ISO 8601 date3 - export COMMIT_TIME=$(git show -s --format=%ci $CI_COMMIT_SHA)4 ## Use first 10 characters of the datetime (ie: 2019-03-19)5 - export COMMIT_TIME_SHORT=$(echo $COMMIT_TIME | head -c10)6 7 .gitlab­ci.yml
  44. 44. Control Pipeline StagesControl Pipeline Stages deploy: stage: deploy only: - deploy except: variables: - $CI_COMMIT_MESSAGE =~ /Initial commit/i - $CI_COMMIT_MESSAGE =~ /skip deploy/i - $CI_COMMIT_MESSAGE =~ /don't deploy/i https://docs.gitlab.com/ee/ci/yaml/#onlyexcept­basic .gitlab­ci.yml
  45. 45. Building Custom ImagesBuilding Custom Images build: stage: build only: - deploy script: ## Build the image, with the build tag and the latest tag - docker build --tag $CONTAINER_IMAGE:$BUILD_TAG --tag $CONTAINER_IMAGE:latest -f ./build/cfml/Dockerfile . ## List images, so we can confirm success - docker image ls ## Push with the build tag - docker push $CONTAINER_IMAGE:$BUILD_TAG ## Push with latest - docker push $CONTAINER_IMAGE:latest .gitlab­ci.yml
  46. 46. Stack DeploymentStack Deployment
  47. 47. Stack DeploymentStack Deployment deploy: stage: deploy script: - [a lot of SSH related config] ## Enable SSH functionality made possible in 18.0.9 to switch our context to the remote server - export DOCKER_HOST=ssh://root@${HOST_IP} ## Deploy the stack - registry auth is for gitlab - docker stack deploy -c docker-compose.yml -c docker- compose.prod.yml basetest --with-registry-auth .gitlab­ci.yml
  48. 48. » Swarm's missing UI » Configuration and management » Separate from application stack PortainerPortainer
  49. 49. » » » Hybrid license Easy installation (ForgeBox) Some manual configuration FusionReactor (Cloud)FusionReactor (Cloud)
  50. 50. » Required in multi-node Swarms » Free options » Provided via (beta) Lucee Extensions » Paid options are superior Sessions and CachingSessions and Caching https://blog.mattclemente.com/2018/08/17/install­lucee­extensions­on­commandbox­docker­containers.html
  51. 51. SSLSSL https://blog.filippo.io/mkcert­valid­https­certificates­for­localhost/ https://letsencrypt.org/docs/certificates­for­localhost/ mkcert (Zero­config tool to make locally trusted development certificates) +
  52. 52. All things areAll things are difficult before theydifficult before they are easy.are easy. Dr. Thomas Fuller, Gnomologia, 1732
  53. 53. Try This At HomeTry This At Home Building a Personal Docker SwarmBuilding a Personal Docker Swarm Matthew Clemente @mjclemente @mjclemente84 blog.mattclemente.com @mjclemente

×