1

I am doing a project for my university where I have the following requirements:

  1. I want to start and stop (docker) containers with different apps
  2. I have a singe (university) server to my disposal
  3. I want the starting and stopping to be somewhat automated using the universities GitLab

My current idea is the following:
Users create a new branch on an existing GitLab project. If the branch has some specific format, i.e. Deploy-0x-name a new container is deployed on the server and accessible through the network. If the branch is deleted, the container is also removed from the server. Now I am unsure what tools to use. I was thinking about using Kubernetes, but it seems that is not ideal for a single server setup. At least that's what I read. Also, I don't really need the load balancing between different container instances as there will only be one instance of every application running. Still, I have to manage multiple applications.

Is there a better alternative for K8s in this situation, or should I use a completely different approach?

Thank you

5 Answers 5

0

Jasper -

I think you want to establish some form of communication between GitLab and your server, in particular, GitLab should be able to initiate events on the server in response to events (changes) in the GitLab repository.

A common pattern for a solution is to use a webhook -- a feature of GitLab (I assume, I use GitHub) that allows you to instruct GitLab to perform a given action when something happens in GitLab. You can choose which things, for example, you might choose to have GitLab fire the webhook whenever there's a push.

What happens when the push occurs? You need to pull from the repo, build a new container, upload it to the container repo, then run docker using the new container.

The webhook is expected to be a URI that refers to a remote server ... in particular, the remove server needs to be listening on the port specified by the URI. The most common port is either the HTTP port 80, or the HTTPS port 443 -- and the reason they are popular is that many systems don't block them, as they do with most other ports. So you need something on your server listening on port 80/443 that will do these steps.

So the steps needed (pull, build, upload, run) often fall into two phases: "build" and "run", where build includes all the steps needed to deploy a workable application. GitHub offers "github actions" -- I suspect GitLab has something similar -- that give you access to a temporary compute resource for things like running commands e.g. "pull", "compile", and "docker". Or, you could build a basic web server app that ran these commands. Either way, something on the server will need to run docker (or maybe ask it to restart) using the newly built image.

Could you use Kubernetes for this ... sure ... but as you imply, it's too much for the single task. Learning how to deploy kubernetes is a lot of work. Instead, Google "xyx web server" where xyz is the programing language or environment to find a suitable installable server. Most offer a simple way to integrate system commands and respond to webhooks.

0

The problem with not using k8s is that because k8s exists and is so successful you are unlikely to find robust and easy to use alternatives. The problem you have correctly identified is that k8s is designed to run containers at scale so it runs across many machines. And that makes it quite complex to set up. You also need many machines and you have one.

Yet you can run kubernetes on a single server with “MiniKube”. You can run it on your laptop. It isn’t seen as “production ready” only “development mode” because no-one expects to run a business critical system on a single server. Yet if all you have is a single server then this is fine to use MiniKube.

If you don’t run k8s you will have to create at lot of “application infrastructure” yourself. You will have to write software, from scratch, that runs all the time, exposes a Webhook, that GitLab hits, that then does a lot of “from scratch” container management.

While this is completely possibly I wouldn't attempt it. You have to worry about containers crashing, containers starting after server restarts, everything working after the server operating system is patched.

Once you have “MiniKube” running (start on your own laptop!) your problem becomes a whole load easier. It will remember what containers should be running and restart them when the server is restarted (you obviously have to start up MiniKube when the server reboots). It also exposes the standard k8s API that is designed to make management of containers easy. That makes solving your problem a lot easier.

You said you want to run a container per branch with a certain naming convention. This is a slightly unusual. Typically we would make “master” the state of the server and use a folder on master per “service”. Nevertheless an application per branch it is workable. Regardless of whether it is GitLabs, GitHub Actions, or BitBucket Pipeline’s I would use Helm as the tool to manage the containers.

I would create a docker image with Helm in it and have GitLab pass in a credential (perhaps a username and password?) via environment variables and also pass the branch name as a parameter. Then when the build runs you can have a script in the container build the application then run Helm asking to install or upgrade the application. You can use the branch name as the Helm application name. Helm will create or update the application using whatever it is that is inside of the git repo on that exact branch.

To start out install Helm and MiniKube on your laptop. Then follow the solid Helm documentation on how to have it package and install applications into the MiniKube on your laptop. Once you have a prototype solution install MiniKube on the server and try out managing applications by running a Docker image on your laptop that has Helm in it. Finally have GitLab run the tested Helm Docker image.

2
  • Having a branch per container is a real antipattern. I have seen this "use branch instead of folder" pattern on one project, and it made it much harder to do everything - essentially means multiple main / master branches instead of one.
    – RichVel
    Commented Dec 29, 2021 at 7:58
  • I'm not sure that additional complexity of Helm is justified compared to kubectl apply -f of the K8s manifest files. The kubectl approach works well with GitOps tools (such as ArgoCD), which also have features to poll GitHub etc for repo changes or trigger from a webhook.
    – RichVel
    Commented Dec 29, 2021 at 8:02
0

Since you only have a single server and a few services, I'm not sure K8's is a great choice. It is very powerful and it's worth learning so maybe give it a shot.

A better approach in this situation is using Ansible. It's a configuration as code (CasC) and it can be automated in your Gitlab pipeline. Another nice thing about Ansbile is it will kinda force you to learn more about systems, services and networking than using something like K8's.

Another approach that I'm not very familiar with would be something like Hashicorps Nomad. Similar to K8's? Maybe kinda? But much simpler. Not sure how it compares to Ansible.

The last thing, that I wouldn't really recommend, is just SSHing into the server and doing it with bash and/or docker compose. This is like doing it the hard way but without the benefit of learning a skill like Ansible.

Also, there are Ansible alternatives like Chef and Puppet but I really think Ansible is where it's at.

0

I would suggest - although not idea either to install GitLab with the Omnibus Installer method and then on the same machine host a GitLab Runner. Since the latter uses Docker already you could deploy your applications via GitLab CI on the very same machine the code is initially hosted on.

0

docker-compose is easy to use to run services on a server. In one yaml file, you can define multiple services that can interact with each other through the same network. It makes mapping volumes to the host very easy, too.

This blog post How to Use Docker Compose to Run Multiple Instances of a Service in Development by Maximilian Störchle provides a good set of examples.

I use docker-compose to run multiple services on the relatively small number of servers at my work; have been very satisfied.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.