How to Set Up a Local GitLab CI/CD Environment on an M1 MacBook with Docker
This guide walks through installing GitLab CE on an M1 MacBook using an ARM Docker image, configuring ports, setting up SSH access, creating a sample project, and registering a GitLab Runner for CI/CD pipelines, all with step‑by‑step commands and code snippets.
Looking to learn infrastructure basics, I set up a full GitLab CE environment on a single MacBook Pro 2021 (M1) using Docker.
Install GitLab
Because the Mac uses an ARM CPU, I used the ARM‑compatible image yrzr/gitlab-ce-arm64v8:latest. Three host directories (etc, log, opt) must exist before starting the container.
version: "3.8"
services:
gitlab-ce:
image: yrzr/gitlab-ce-arm64v8:latest
container_name: gitlab-ce
privileged: true
restart: always
ports:
- "9922:22"
- "9980:9980"
volumes:
- /Users/hxzhouh/tools/gitlab/etc:/etc/gitlab:z
- /Users/hxzhouh/tools/gitlab/log:/var/log/gitlab:z
- /Users/hxzhouh/tools/gitlab/opt:/var/opt/gitlab:z
deploy:
resources:
limits:
memory: 4096M
tty: true
stdin_open: trueThe container exposes port 9980 for HTTP (instead of the default 80) to avoid a known port‑conflict issue.
After the container starts, edit /etc/gitlab/gitlab.rb inside the container:
external_url 'http://127.0.0.1:9980'
gitlab_rails['gitlab_ssh_host'] = '127.0.0.1'
gitlab_rails['gitlab_shell_ssh_port'] = 9922Change the default root password via the Rails console:
gitlab-rails console -e production
user = User.where(id: 1).first
user.password = 'AIl+mVN(:bk#5%c'
user.save!Reload and restart GitLab:
gitlab-ctl reconfigure
gitlab-ctl restartOpen 127.0.0.1:9980 in a browser; log in with the root account and the new password.
Add SSH
Create an SSH key pair and add the public key to GitLab. Then add the following host configuration to ~/.ssh/config:
Host 127.0.0.1
HostName 127.0.0.1
Port 9922
IdentityFile ~/.ssh/ssh
PreferredAuthentications publickey
User rootTest the connection:
➜ .ssh ssh -T [email protected]
Welcome to GitLab, @root!SSH works, so I created a new project, cloned it via SSH, and pushed changes without issues.
git clone ssh://[email protected]:9922/root/hello-world.git ➜ hello-world git:(main) git push origin --force
To ssh://127.0.0.1:9922/root/hello-world.git
b4dd724..e45f213 main -> mainGitLab Runners Configuration
In GitLab’s Settings → CI/CD → Runners, I followed the “Show runner installation and registration instructions” to install a runner on macOS:
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-arm64
sudo chmod +x /usr/local/bin/gitlab-runner
gitlab-runner install
gitlab-runner start
gitlab-runner register --url http://127.0.0.1:9980 --registration-token GR13489416KQ-jitR3JhfMgr8f-9GKey points during registration:
Enter tags for the runner (e.g., golang-local-shell) so jobs can target it via .gitlab-ci.yml.
Select an executor; I chose shell for simplicity.
After registration, the runner appears at http://127.0.0.1:9980/admin/runners.
Finally, I added a simple .gitlab-ci.yml to the project to test the pipeline:
stages:
- build
build_job:
stage: build
tags:
- golang-local-shell
script:
- go build -o myapp
only:
- main
- tags
artifacts:
paths:
- myappPushing the code triggers the pipeline, which compiles the Go binary. The build artifacts can be downloaded from the pipeline’s artifacts page.
With GitLab fully functional locally, the next step will be to spin up a local Kubernetes cluster and automate Docker image builds and deployments via this CI/CD pipeline.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
