@@ -2,22 +2,21 @@ pipeline {
22 agent any
33
44 environment {
5- // host paths
6- PROD_DIR = " /opt/docker/site" // where site/ compose.yml lives
7- SITE_DIR = " /opt/docker/site/static-site/app " // where Dockerfile + app code should live/build from
5+ // Host paths (these MUST be mounted into the jenkins container)
6+ PROD_DIR = " /opt/docker/site" // folder that has compose.yml
7+ SITE_DIR = " /opt/docker/site/static-site" // folder that has Dockerfile + app code
88
9- IMAGE_NAME = " static-site"
10- IMAGE_LATEST = " static-site:latest"
11- SERVICE_NAME = " static-site"
12- CONTAINER_NAME = " static-site"
9+ IMAGE_TAG = " static-site:latest" // this must match compose.yml
10+ SERVICE_NAME = " static-site" // service name in compose.yml
1311 }
1412
13+ // safety net in case GitHub webhook doesn't fire
1514 triggers {
16- // optional: poll main in case webhook fails
1715 pollSCM(' H/5 * * * *' )
1816 }
1917
2018 stages {
19+
2120 stage(' Checkout main' ) {
2221 when { branch ' main' }
2322 steps {
@@ -29,45 +28,49 @@ pipeline {
2928 when { branch ' main' }
3029 steps {
3130 /*
32- We need the latest app code to be present in /opt/docker/site/static-site
33- so we can build the image FROM that directory using the host docker daemon.
31+ We want the code Jenkins just checked out
32+ to live in /opt/docker/site/static-site on the HOST,
33+ because that's what we'll build from.
3434
35- rsync copies the checked-out repo (current workspace) into SITE_DIR on the host.
36- Adjust the source path ("./") if your actual app code is under ./app in git.
35+ NOTE:
36+ - If your app lives in the repo root, keep "./".
37+ - If your app lives in ./app in the repo, change "./" to "./app/".
3738 */
3839 sh """
3940 rsync -a --delete ./ ${ SITE_DIR} /
4041 """
4142 }
4243 }
4344
44- stage(' Build image on host daemon' ) {
45+ stage(' Build Docker image (static-site:latest) on the host daemon' ) {
4546 when { branch ' main' }
4647 steps {
4748 /*
48- Build the Docker image as static-site:latest using the host docker socket.
49- After this, the host's Docker daemon now has an updated static-site:latest.
49+ This runs *inside* the Jenkins container,
50+ but because /var/run/docker.sock is mounted,
51+ `docker build` is actually talking to the host's Docker engine.
52+
53+ Result:
54+ The host now has a fresh static-site:latest image.
5055 */
5156 sh """
5257 cd ${ SITE_DIR}
53- docker build -t ${ IMAGE_LATEST } -f Dockerfile .
58+ docker build -t ${ IMAGE_TAG } -f Dockerfile .
5459 """
5560 }
5661 }
5762
58- stage(' Redeploy via docker compose' ) {
63+ stage(' Deploy / restart running container via docker compose' ) {
5964 when { branch ' main' }
6065 steps {
6166 /*
62- Now tell docker compose (in /opt/docker/site/compose.yml) to recreate the service.
63- compose.yml MUST define the service like:
64-
65- static-site:
66- image: static-site:latest
67- container_name: static-site
68- ...
67+ Now we ask docker compose (the one in /opt/docker/site/compose.yml)
68+ to recreate the service using the new static-site:latest image.
6969
70- and MUST NOT have a 'build:' block anymore.
70+ Requirements:
71+ - /opt/docker/site/compose.yml MUST NOT have a 'build:' block for static-site
72+ (it should ONLY say `image: static-site:latest`)
73+ - /opt/docker/site is mounted into the Jenkins container so this cd works
7174 */
7275 sh """
7376 cd ${ PROD_DIR}
@@ -79,10 +82,10 @@ pipeline {
7982
8083 post {
8184 success {
82- echo " Deploy succeeded. ${ IMAGE_LATEST } is now running as ${ CONTAINER_NAME } ."
85+ echo " ✅ Deploy succeeded. ${ IMAGE_TAG } is now running."
8386 }
8487 failure {
85- echo " Deploy failed. Check build logs."
88+ echo " ❌ Deploy failed. Check build logs."
8689 }
8790 }
8891}
0 commit comments