How to Create GitLab Users Without Email Configuration (Local VM Setup)


4 views

When setting up GitLab on a local VM for development or testing, the email requirement for user creation becomes a significant hurdle. The default behavior forces administrators to configure SMTP settings, even when working in isolated environments where email functionality isn't necessary.

Here are three practical approaches to create users without email configuration:

1. Using Rails Console

The most reliable method is through GitLab's Rails console. SSH into your VM and run:


sudo gitlab-rails console
user = User.new(username: 'dev1', name: 'Developer One', password: 'securepassword123', password_confirmation: 'securepassword123')
user.skip_confirmation! # Bypass email confirmation
user.save!

2. Modifying the Admin Interface Temporarily

For a quick GUI solution (not recommended for production):


# Edit the user creation form
sudo nano /opt/gitlab/embedded/service/gitlab-rails/app/views/admin/users/_form.html.haml

Find the email field validation and temporarily comment out the required attribute during user creation.

3. Using the API with Patched Validation

Create a custom API endpoint by adding an initializer:


# /opt/gitlab/embedded/service/gitlab-rails/config/initializers/bypass_email.rb
module EmailBypass
  def email_required?
    !Rails.env.development? && !Rails.env.test?
  end
end

User.include(EmailBypass)

Then use the API:


curl --request POST --header "PRIVATE-TOKEN: your_token" \
--data "name=Local User&username=localuser&password=testpass&skip_confirmation=true" \
"http://your-gitlab.local/api/v4/users"

After creating users without emails, consider these adjustments:


# Disable email-related features in gitlab.rb
sudo nano /etc/gitlab/gitlab.rb

Add these configurations:


gitlab_rails['gitlab_email_enabled'] = false
gitlab_rails['gitlab_email_from'] = 'noreply@localhost'
gitlab_rails['smtp_enable'] = false

Then reconfigure GitLab:


sudo gitlab-ctl reconfigure

While these methods work for local development, remember that:

  • Password reset functionality will be unavailable
  • Notification emails won't be sent
  • Audit logs may show incomplete user information
  • Consider implementing alternative authentication (LDAP, OAuth) for production

When setting up a local GitLab instance for development testing, the default email requirement creates unnecessary complexity for small teams. The standard workflow where GitLab sends password reset emails becomes problematic when:

  • You're using GitLab in an air-gapped environment
  • Testing temporary instances in CI/CD pipelines
  • Running disposable development environments

While GitLab provides SMTP configuration options, setting up mail services introduces:

gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
# ... (additional SMTP configuration)

This approach adds maintenance overhead and potential security considerations for simple test environments.

Method 1: Using the Rails Console

The most direct approach for local development:

sudo gitlab-rails console

user = User.new(
  username: 'devadmin',
  name: 'Development Admin',
  email: 'placeholder@example.com',
  password: 'your_secure_password',
  password_confirmation: 'your_secure_password'
)
user.skip_confirmation!
user.save!

Key points:

  • The email address is technically required but not validated
  • skip_confirmation! bypasses the email verification step
  • Passwords are set directly in the console

Method 2: API User Creation

For automation scenarios using the GitLab API:

curl --request POST --header "PRIVATE-TOKEN: <your_admin_token>" \
--form "username=newuser" \
--form "name=New User" \
--form "email=temp@example.com" \
--form "password=secure_password" \
--form "skip_confirmation=true" \
"http://localhost/api/v4/users"

Method 3: Database Direct Insert

For advanced users comfortable with SQL:

sudo gitlab-psql

INSERT INTO users (email, username, name, encrypted_password, created_at, confirmed_at)
VALUES (
  'temp@example.com',
  'dbuser',
  'DB User',
  -- Generate with: echo -n "password" | gitlab-rails runner "puts User.new.send(:password_digest, 'password')"
  '$2a$10$SALTEDHASHVALUE',
  NOW(),
  NOW()
);

When bypassing email verification:

  • Ensure strong password policies for all local accounts
  • Monitor unauthorized access attempts
  • Document these exceptions in your security policy

For testing pipelines, consider this Bash snippet:

# Create user if not exists
EXISTS=$(curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "http://gitlab/api/v4/users?username=testuser" | jq 'length')

if [ "$EXISTS" -eq 0 ]; then
  curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
    --form "username=testuser" \
    --form "name=Test User" \
    --form "email=testuser@example.com" \
    --form "password=$TEST_PASSWORD" \
    --form "skip_confirmation=true" \
    "http://gitlab/api/v4/users"
fi