dockerdeploymentdevopsdocker-swarmcodeship

How to deploy a Docker container using a CI/CD service (Codeship)?


I´m at the beginning of my DevOps journey and some things are still quite hard for me to understand. My current scenario is this:

I have a very simple dockerized application (just one endpoint, no state). I currently deploy it to one single server with a deployment script that goes something like this:

#!/usr/bin/env bash

# build docker image
docker build -t my/image .

# save docker image (to tmp)
docker save -o /tmp/my-image.tar my/image

# upload docker image
scp /tmp/my-image.tar user@xxx.xxx.xxx.xxx:~/

# load docker container
ssh -t user@xxx.xxx.xxx.xxx "sudo docker load -i /tmp/my-image.tar"

# stop docker container on remote host
ssh -t user@xxx.xxx.xxx.xxx "sudo docker stop image"

# start docker container
ssh -t user@xxx.xxx.xxx.xxx "sudo docker run -d --rm -p 8081:8081 --name myimage --restart always --env-file ~/.env.prod my/image"

Now I want to build a proper automated CI/CD pipeline for the service. It should be deployable to different environments. I want to run automated test. Etc.

I researched a bit and found that Codeship (Pro) seems be be a good choice for dockerized applications. But I cant seem to find a good tutorial that explains my (simple?) use case in enough detail that I could implement it.

Here is what I found so far:

Any help + tips are welcome!

[1] https://documentation.codeship.com/pro/continuous-deployment/ssh-deploy/

[2] https://documentation.codeship.com/pro/continuous-deployment/docker-swarm/


Solution

  • Running or using a Docker registry is almost always considered preferable to docker save and docker load if it’s an option. You can run your own, or use a cloud-hosted one like Docker Hub or Amazon’s ECR or Google’s GCR or .... To use this you need to

    1. Include the registry address in your image name everywhere, docker build -t registry.example.com/my/image:tag;

    2. docker push the built image instead of saving it; and

    3. Just docker run the image with the registry address included in the image name, and Docker will pull it for you.

    (If you are looking at moving to a clustered solution like Kubernetes, this is essentially required.)

    It’s also generally a good idea to have your CI system use a unique tag for every build; a date stamp or a source control commit ID are both convenient options. Don’t use the latest tag or any other fixed string. If you docker run my/image:20190911 and the server doesn’t already have that build then it will know it needs to pull it, but if you run ...:latest you might be running a different code version than you expect. (Again this is all but required in Kubernetes.)

    I don’t think Docker Swarm is a good match for what you’re describing, but you might look at an automation tool like Chef or Ansible that’s designed to make configuration changes and launch services on remote hosts instead of trying to hand-write ssh commands.