Getting Started
You’ve ordered a managed GitLab from server.camp - great choice. GitLab is far more than a code repository: it’s the central platform for your entire software development workflow - from project planning and code reviews to automated testing and deployments. This guide is written for development teams at SMBs, freelancers, and organizations who want professional project management and version control on their own infrastructure.
GitLab.com is a solid starting point - but for businesses and teams, there are compelling reasons to run your own GitLab instance at server.camp:
| gitlab.com (SaaS) | Your own GitLab at server.camp | |
|---|---|---|
| Data sovereignty | Code stored on GitLab Inc. servers (USA) | Code stored in Germany, GDPR-compliant |
| Privacy | US Cloud Act: theoretical access by US authorities | No third-party access, full control |
| CI/CD minutes | Limited (400 min/month on Free plan), expandable with own runners | Unlimited with your own runners |
| User limit (private projects) | Free plan: 5 users | No artificial limits |
| Storage | Limited (10 GB on Free plan) | Starting at 250 GB, expandable |
| Admin access | No access to instance settings | Full administrator access |
| Performance | Shared with millions of users | Dedicated resources, consistent performance |
| Container Registry | Limited | Included, unlimited |
| Availability | Dependent on GitLab Inc. | Your own instance, independent of US companies |
Who benefits from a self-hosted GitLab?A self-hosted GitLab makes sense as soon as any of these apply: you work with customer data or proprietary code, you need more than 5 users, you need to demonstrate GDPR compliance, or you want full control over backups and configuration.
GitLab is organized hierarchically:
- Group — a space for a team, a client, or a topic area (e.g. “Internal Projects”, “Client Meier AG”)
- Subgroup — optional nesting within a group (e.g. “Client Meier AG / Frontend”, “Client Meier AG / Backend”)
- Project — an individual application, library, or service within a group
Inside a project, you’ll find:
- Repository — the actual Git code
- Merge Request (MR) — a proposal to merge code changes (the code review process)
- Issue — a task, bug report, or feature request
📁 Internal
📁 Infrastructure (Ansible, Terraform, Docker configs)
📁 Libraries (reusable modules)
📁 Tools (internal scripts, automation)
📁 Client-A
📁 Frontend
📁 Backend
📁 Documentation
📁 Client-B
📁 ...
📁 Open Source (public projects, if applicable)
Manage access rights through groupsCreate a separate group for each client or internal area. Access rights are granted at the group level and automatically apply to all projects within it. No need to configure each project individually — if an external developer only works on Client A, they only get access to the “Client A” group.
In a project or group, go to Settings → Members → Invite. GitLab offers the following roles:
| Role | Permissions | Recommended for |
|---|---|---|
| Guest | View and comment on issues | Clients who just want to observe |
| Reporter | Read code, create issues, manage labels | Project managers, non-developers |
| Developer | Push code, create merge requests, trigger pipelines | Developers (internal and external) |
| Maintainer | Protect branches, merge MRs, manage project settings | Senior developers, tech leads |
| Owner | Full access, create and delete groups/projects | Team lead, IT management |
Safely onboard external freelancersInvite external developers as Developer in the specific client group — not at the instance level. They’ll only see the projects they’re working on and won’t have access to other clients or internal repositories. When the project ends, remove them from the group.
For daily Git work, SSH key authentication is recommended over passwords:
- Generate an SSH key (if you don’t have one):
ssh-keygen -t ed25519 - Copy the public key (
~/.ssh/id_ed25519.pub) - In GitLab: User Settings → SSH Keys → Add new key
- From now on:
git clone git@your-gitlab.srv.camp:group/project.git
GitLab supports limiting registration to certain email domains. Go to Admin Area → Settings → General → Sign-up restrictions → Domains and add the allowed domains. Only people with a matching email address will be able to register.
GitLab supports SSO via SAML and OpenID Connect. If you use Managed Authentik from server.camp, your team members can sign in with their central account. SSO is included in the Corporate plan. Contact our support team for setup.
External identity providers work tooAlready using Keycloak, Azure AD, or another identity provider? No problem — GitLab supports all common protocols. Keep using your existing user management without creating new accounts. This requires the Corporate plan. We’re happy to help with setup.
- Click “New project”
- Choose:
- Blank project — for a new initiative
- From template — GitLab includes templates for various languages and frameworks
- Import — from GitHub, Bitbucket, or another GitLab instance
- Set a project name and select a group
- Choose a visibility level:
- Private — invited members only (recommended for almost all projects)
- Internal — all signed-in users on this GitLab instance
- Public — anyone, even without an account (for open-source projects)
- Optionally initialize a README (recommended — keeps the repository from being empty)
First, install Git on your machine.
# Via SSH (recommended)
git clone git@your-gitlab.srv.camp:group/project.git
# Via HTTPS
git clone https://your-gitlab.srv.camp/group/project.git
# Stage changed files for the next commit
git add .
# Save changes as a commit
git commit -m "Brief description of what changed"
# Push changes to GitLab
git push
Branches let you work on features or bug fixes without affecting the main development line:
# Create a new branch and switch to it
git checkout -b feature/new-feature
# Commit changes in the branch
git add .
git commit -m "Implement login page"
# Push branch to GitLab
git push -u origin feature/new-feature
Branch naming conventionAgree on a consistent naming scheme with your team, e.g.feature/description,fix/description,hotfix/description. This keeps your branch list tidy and immediately signals the purpose of each branch.
Short-lived branches are easier to manageThe shorter a branch lives, the easier it is to handle. Work on a feature, open a merge request, review and merge — then delete the branch. This prevents long-running branches from drifting away from the main branch and becoming hard to merge.
Here’s the workflow we recommend for teams:
- Every change happens on its own branch
- When development is done, a Merge Request (MR) is created
- A teammate reviews the code and provides feedback or approval
- After approval, the branch is merged into the main branch
- In GitLab, navigate to your project → Merge Requests → New
- Select the source branch (your feature branch) and target branch (e.g.
main) - Add a title and description — what changed and why?
- Assign a reviewer
- Optionally link labels, a milestone, and a related issue
- Click “Create merge request”
As a reviewer:
- Open the merge request → the “Changes” tab shows all code modifications
- Click a line → leave a comment (questions, suggestions, praise)
- After your review: click “Approve”
- The author can then merge the MR
Protect the main branchUnder Settings → Repository → Protected branches, enable protection formain. This prevents anyone from pushing directly to the main branch — everything must go through a merge request with a review. It prevents accidental errors in production code and enforces a four-eyes principle.
Under Issues in any project, you can manage tasks, bugs, and feature requests:
- Title and description — what’s the problem or task? (Markdown supported)
- Labels — categorization (e.g.
bug,feature,urgent,backlog) - Assignment — who’s responsible?
- Milestone — which release or sprint does this belong to?
- Due date — deadline
- Weight — effort estimate (story points)
- Link to MR — automatically close an issue when the MR is merged (use
Closes #42in the MR description)
Use scoped labelsIn the Premium and Ultimate versions of GitLab, you can use Scoped Labels to capture structured information. Example:Status::To Do,Status::In Progress,Status::Review,Status::Done. You can partially replicate this in the Community Edition using prefixed labels (e.g.Status::To Do) - you’ll maintain the structure manually, but it helps keep things organized.
Under Issues → Board, set up a Kanban board:
Backlog → To Do → In Progress → Review → Done
Each issue appears as a card and can be dragged between columns. Columns are based on labels — create labels like To Do, In Progress, Review and add them as board columns.
Under Issues → Milestones, create milestones with start and end dates. Assign issues to a milestone and track progress via the progress bar. Ideal for sprint planning or release cycles.
Every project includes a built-in Wiki for technical documentation:
- Markdown-based
- Standalone Git repository (can be cloned and edited locally)
- Sidebar navigation
- Search functionality
Common Wiki content:
- Architecture overview and system design
- Developer setup guide
- API documentation
- Deployment process and runbooks
- Architecture decision records (ADRs)
Wiki vs. READMEUse the README.md in the repository for a quick overview (What is this project? How do I run it?). Use the Wiki for detailed documentation that goes beyond the repository itself — architecture, processes, decisions.
GitLab CI/CD is controlled by a .gitlab-ci.yml file in the root of your repository. Every time you push code, a pipeline is triggered automatically and runs through the defined steps (jobs).
stages:
- test
- build
- deploy
test:
stage: test
image: node:20
script:
- npm ci
- npm test
build:
stage: build
image: node:20
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
deploy:
stage: deploy
script:
- echo "Deploy to production"
# Insert your deployment script here
only:
- main
when: manual
| Without CI/CD | With CI/CD |
|---|---|
| “Works on my machine” — but not on the server | Automated tests in a clean environment |
| Forgetting to run tests | Tests run automatically on every push |
| Manual deployment: SSH, copy files, restart services | One click (or automatic on merge to main) |
| Unclear whether the current code is error-free | Green checkmark = all good, red circle = problem |
When CI/CD is configured, every merge request shows the pipeline status. You can see at a glance whether tests pass before merging. Combined with protected branches, you can require that an MR can only be merged when the pipeline is green.
You can test your .gitlab-ci.yml locally before pushing. Install gitlab-ci-local on your machine and run the pipeline locally:
# All jobs
gitlab-ci-local
# A specific job (e.g. "test")
gitlab-ci-local <job-name>
For more details, see the official documentation.
CI/CD jobs require a runner - a system that actually executes the pipeline steps.
Runners are not included in hostingGitLab packages at server.camp do not include GitLab Runners. We don’t offer a shared runner for all customers - for security reasons, your code and secrets should never land on a shared system.
You can run a GitLab Runner on your own server, a developer machine, or a VM:
- Install GitLab Runner (available for Linux, macOS, Windows)
- Register the runner: GitLab → Settings → CI/CD → Runners → Register a new runner
- Enter the token and URL shown during registration
- Choose an executor: Docker (recommended), Shell, or Kubernetes
# Example: register a runner on Linux
gitlab-runner register \
--url https://your-gitlab.srv.camp \
--token glrt-YOUR_TOKEN
Docker executor recommendedThe Docker executor runs each CI/CD job in a fresh container. This ensures reproducible builds and prevents leftover state from previous jobs from affecting results. Requires Docker to be installed on the runner machine.
For teams who don’t want to run their own server, server.camp offers dedicated runners:
| Runner | Resources | Price |
|---|---|---|
| Small | 4 vCore, 8 GB RAM, 250 GB SSD | €25 / month |
| Medium | 8 vCore, 16 GB RAM, 500 GB SSD | €50 / month |
| Large | 12 vCore, 32 GB RAM, 1 TB SSD | €100 / month |
Dedicated runners run in isolation, exclusively for your instance. To order, contact our support team.
CI/CD is optional — you can use GitLab fully without pipelines to start. Version control, issues, merge requests, and wikis all work without a runner. When you’re ready for automated testing or deployments, add a runner.
GitLab includes a built-in Container Registry. Store and manage Docker images directly in your GitLab project — no external registry like Docker Hub required.
# Build and push a Docker image to the GitLab Registry
docker login your-gitlab.srv.camp:1234
docker build -t your-gitlab.srv.camp:1234/group/project:latest .
docker push your-gitlab.srv.camp:1234/group/project:latest
The registry is especially powerful combined with CI/CD: the pipeline builds the image, pushes it to the registry, and the deployment job pulls it from there.
GitLab offers Snippets — short pieces of code that can be shared without creating a full repository. Ideal for shell scripts, configuration files, or instructions you want to share with your team.
Snippets can be private, internal, or public, and support syntax highlighting for all common languages.
GitLab includes a built-in Web IDE based on VS Code — a full-featured code editor right in your browser. Perfect for quick edits (a typo in the README, a config tweak) without cloning the repository locally.
In any project: Code → Open Web IDE (or press . on your keyboard).
| Challenge | Solution with GitLab |
|---|---|
| Code on a local hard drive — no backup, no overview | All projects in GitLab, daily backups included |
| Client projects getting mixed up | Separate group per client, clean separation |
| Client wants to see interim progress | Invite the client as Guest/Reporter in the project group |
| “Which version is running at the client’s?” | Git tags for releases, clear version history |
| No four-eyes principle as a solo developer | Use merge requests anyway: create your own MRs, review briefly, then merge — it forces you to think it through |
| Client project done, code should be archived | Archive the project (read-only) — it stays preserved but inactive |
Tip for freelancers: Use Issues not just for code tasks, but also as a to-do list for client projects. Keep tasks, code, and documentation in one place — and give clients visibility when needed.
| Challenge | Solution with GitLab |
|---|---|
| Code scattered across individual developers’ machines | Central GitLab: one source of truth |
| No code review — errors go straight to production | Protected branches + merge requests with required review |
| Manual deployment: error-prone and time-consuming | CI/CD pipeline: automated tests and deployments |
| External freelancers need access to specific projects | Group-based permissions: Developer role only for relevant projects |
| Technical documentation exists only in people’s heads | Wiki per project, README as entry point |
| Unclear who’s working on what | Issue boards, milestones, assignments |
| GDPR: code and customer data must not be stored in the US | Self-hosted GitLab on German servers |
Onboarding tip: Create an “Onboarding” project with Wiki pages: developer setup guide, Git workflow, branch conventions, CI/CD overview. New developers read the wiki and can start contributing right away.
| Challenge | Solution with GitLab |
|---|---|
| Website maintained by rotating volunteers | Code in GitLab: every new maintainer immediately has access to the full history |
| Website changes go wrong, no way to roll back | Git versioning: every change can be undone |
| No documentation for successors | Wiki: guide for website maintenance, server access, domain management |
| Config files (Ansible, Docker) for organizational IT | Dedicated repository for infrastructure-as-code |
| Multiple people working on the website at the same time | Branches and merge requests: no conflicts, clean collaboration |
Tip for organizations: Even if only one person maintains the website — use GitLab as a backup and documentation hub. When the webmaster moves on, their successor immediately has the complete code, full change history, and all documentation in the wiki.
Connect GitLab with Mattermost via webhooks:
- Automatically post new merge requests, pipeline status, and issue updates to a developer channel
- Enable under Project → Settings → Integrations → Mattermost
Monitor your deployed applications with Uptime Kuma. Combined with Node-RED, you can automatically create a GitLab issue when a monitoring alert fires.
Store GitLab credentials, deploy tokens, and API keys securely in Vaultwarden. For CI/CD secrets especially: use GitLab’s built-in CI/CD variables (masked and protected) rather than putting secrets in code.
With the Corporate plan, connect GitLab to Authentik via SAML or OpenID Connect. Team members sign in with a single central account, and onboarding and offboarding are managed centrally.
Every user can enable 2FA under User Settings → Account → Two-Factor Authentication. Recommended for all users, required for admins and maintainers.
For automated access (CI/CD, scripts, integrations), use Deploy Tokens or Personal Access Tokens with the minimum necessary permissions — never use your personal password in scripts.
Under Settings → CI/CD → Variables, store secrets (API keys, passwords, tokens) securely. They’re available in pipelines without appearing in code. Mark sensitive variables as “Masked” and “Protected”.
If you need help setting up CI/CD pipelines, have questions about permission management, or want to onboard external developers securely — reach out anytime at support@server.camp. We’re happy to help.
You can also find common GitLab questions on our product page.