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 [email protected]:~/
# load docker container
ssh -t [email protected] "sudo docker load -i /tmp/my-image.tar"
# stop docker container on remote host
ssh -t [email protected] "sudo docker stop image"
# start docker container
ssh -t [email protected] "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:
There is the possibility to execute deployments on remote hosts via SSH. But the tutorial only explains how to move files, not containers. [1]
It seems Docker Swarm is something I could be using, but the tutorial doesn´t explain how I can point Codeship to my remote host running docker swarm [2]
I could try to push to a (Docker) registry and then inititate docker on the remote host to pull the image and run it. But somehow that doesn´t feel like a best-practice solution. Or am I wrong?
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/
Running or using a Docker registry is almost always considered preferable to
docker saveanddocker loadif 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 toInclude the registry address in your image name everywhere,
docker build -t registry.example.com/my/image:tag;docker pushthe built image instead of saving it; andJust
docker runthe 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
latesttag or any other fixed string. If youdocker run my/image:20190911and the server doesn’t already have that build then it will know it needs to pull it, but if you run...:latestyou 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
sshcommands.