Saturday, 19 September 2026

Enable Tomcat Manager

Violet Streams · DevOps Hands-On Lab · 5.9

Enable Tomcat Manager
for GitLab CI/CD

Prepare the existing Tomcat server for automated WAR deployments. Keep port 8090 and the simple build-and-deploy pipeline.

Existing Tomcat serverBeginner instructionsThree GitLab variablesNo pipeline changes

Place this lab immediately before Lab 6G. Finish with a working /manager/text/list endpoint and a deployment account that GitLab can use to upload MyWebApp.war.

01

Connect to the existing Tomcat server

Open the SSH session you already use for the Tomcat VM. Do not create a new VM or reinstall Java, Tomcat, or a GitLab Runner.

  1. Open MobaXterm.
  2. In the saved sessions panel, double-click the session for your Tomcat server.
  3. Sign in with the same SSH username and key or password used in the installation lab.
  4. Use this remote terminal for the Linux commands below.
02

Confirm the installation path

The linked installation guide uses the tomcat8 service and the /var/lib/tomcat8 directory. These commands follow that existing layout; they are not instructions to install an obsolete Tomcat release. [1]

ON THE TOMCAT SERVER
sudo systemctl status tomcat8 --no-pager
sudo ls -l /var/lib/tomcat8/conf/tomcat-users.xml

Look for a running service and an existing configuration file. If either does not exist, use Different service name or installation path before editing anything. Do not let the editor create a new empty file in the wrong directory.

ItemValue for the original installation
Servicetomcat8
Tomcat base directory/var/lib/tomcat8
Users file/var/lib/tomcat8/conf/tomcat-users.xml
Existing public addresshttp://YOUR-TOMCAT-PUBLIC-IP:8090
Deployment account created in this labgitlab-deployer

Keep port 8090 unchanged. There is no need to edit server.xml just to add a Manager user.

03

Find out whether Manager is already available

In the Tomcat SSH terminal, run this request without credentials:

ON THE TOMCAT SERVER
curl --silent --output /dev/null --write-out "HTTP %{http_code}\n" \
  http://localhost:8090/manager/text/list
ResponseNext action
401Usually expected: an authentication challenge. Continue with the deployment account below.
403A request restriction may be active. Continue with account setup, then inspect the Manager access configuration.
404Manager may be missing, stopped, or mapped to a different host. Use the recovery section below.
000 / connection errorThe local request did not get an HTTP response. Recheck the running service and port before proceeding.
200Inspect the body; an unauthenticated request should not be able to administer Tomcat. Review authentication before exposing Manager.

The ordinary Tomcat home page is not the same as the Manager application. A working home page alone does not establish that the deployment API is ready. [2]

Only for a missing Manager: follow Recover the Manager application, then repeat this step.

04

Generate a separate deployment password

Create a new password for GitLab rather than putting the instructor’s existing Jenkins password into a second system. Run:

ON THE TOMCAT SERVER
openssl rand -hex 24

Copy the generated value into a private password manager. You will paste it into Tomcat and later into GitLab. Do not use the placeholder shown in the next step as the real password.

05

Add the GitLab user to tomcat-users.xml

Back up the users file first:

ON THE TOMCAT SERVER
sudo cp -p /var/lib/tomcat8/conf/tomcat-users.xml \
  /var/lib/tomcat8/conf/tomcat-users.xml.before-gitlab-$(date +%Y%m%d-%H%M%S)

Open the existing file:

ON THE TOMCAT SERVER
sudo nano /var/lib/tomcat8/conf/tomcat-users.xml
  1. Press Ctrl+W, type </tomcat-users>, and press Enter.
  2. Move to the line immediately above that closing tag.
  3. Paste the entries below. They must be outside any <!-- ... --> comment.
  4. Replace PASTE_YOUR_GENERATED_PASSWORD_HERE with the value from Step 4.
  5. If manager-script is already declared, keep its existing role line and add only the new user. If gitlab-deployer already exists, edit that entry instead of duplicating it.
XML TO ADD INSIDE <tomcat-users>
<role rolename="manager-script"/>
<user username="gitlab-deployer"
      password="PASTE_YOUR_GENERATED_PASSWORD_HERE"
      roles="manager-script"/>

Save with Ctrl+O, press Enter to confirm the same filename, then press Ctrl+X. Do not replace the whole users file.

06

Restart Tomcat and test the account locally

ON THE TOMCAT SERVER
sudo systemctl restart tomcat8
sudo systemctl status tomcat8 --no-pager

When Tomcat is running, test from the same SSH terminal:

ON THE TOMCAT SERVER
curl --user gitlab-deployer \
  http://localhost:8090/manager/text/list

curl prompts for the password. Paste the password you placed in tomcat-users.xml and press Enter. It is normal for password input not to appear. Specifying only the username avoids putting the password directly in the command. [8]

EXAMPLE RESPONSE — YOUR APPLICATION LIST WILL VARY
OK - Listed applications for virtual host [localhost]
/manager:running:0:manager

Look for OK on the first line. You do not need MyWebApp to exist yet. A local failure must be resolved before testing remote access.

07

Test from your own computer

Leave the SSH session open. For this test, use a separate terminal on your own computer, not the Tomcat server.

  1. On Windows, open Start, search for PowerShell, and open it.
  2. Replace YOUR-TOMCAT-PUBLIC-IP with the same public IP or DNS name you use to open Tomcat.
  3. Run the following command, enter the new deployment password when prompted, and inspect the response.
ON YOUR WINDOWS COMPUTER — POWERSHELL
curl.exe --user gitlab-deployer "http://YOUR-TOMCAT-PUBLIC-IP:8090/manager/text/list"

On macOS or Linux, use:

ON YOUR MAC OR LINUX COMPUTER
curl --user gitlab-deployer "http://YOUR-TOMCAT-PUBLIC-IP:8090/manager/text/list"

Use the approved HTTPS URL instead if the instructor has already configured HTTPS. A successful local test plus a successful external test confirms two different things: the account works, and an outside client can reach it.

Do not use the browser’s Manager App button as this account’s test. That button uses /manager/html and requires a different role. Keep script credentials out of browser sessions. [2]

08

Resolve a localhost-only Manager restriction

Do this only when an outside request is blocked and you have confirmed which configuration is active. A localhost-only rule can explain why a local deployment works while an external client is rejected.

GitLab.com’s ordinary hosted runners do not provide a fixed outgoing IP. Your laptop’s “My IP” rule, GitLab’s web/API IPs, or one observed runner IP is not a dependable hosted-runner allowlist. [5]

A. Check the external Manager descriptor first

ON THE TOMCAT SERVER
sudo ls -l /var/lib/tomcat8/conf/Catalina/localhost/manager.xml

If that file exists, back it up and open it:

ON THE TOMCAT SERVER
sudo cp -p /var/lib/tomcat8/conf/Catalina/localhost/manager.xml \
  /var/lib/tomcat8/conf/Catalina/localhost/manager.xml.before-gitlab-$(date +%Y%m%d-%H%M%S)

sudo nano /var/lib/tomcat8/conf/Catalina/localhost/manager.xml

An external manager.xml takes precedence over the Manager application’s packaged META-INF/context.xml. Preserve its existing docBase, privileged, and other settings. [3]

B. If there is no external descriptor

Check the Manager copy deployed by the original installation:

ON THE TOMCAT SERVER
sudo ls -l /var/lib/tomcat8/webapps/manager/META-INF/context.xml

If that file exists, back it up and edit it instead:

ON THE TOMCAT SERVER
sudo cp -p /var/lib/tomcat8/webapps/manager/META-INF/context.xml \
  /var/lib/tomcat8/webapps/manager/META-INF/context.xml.before-gitlab-$(date +%Y%m%d-%H%M%S)

sudo nano /var/lib/tomcat8/webapps/manager/META-INF/context.xml

Do not create a blank file when neither path exists. Use the actual Manager docBase or ask the instructor to locate the active configuration. Do not edit both copies blindly.

C. Change only the existing remote-address Valve

A legacy installation may contain a localhost-only block like this:

EXAMPLE EXISTING RESTRICTION
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />

For the approved temporary direct-access exercise, place XML comment markers around only that block:

TEMPORARY CHANGE — KEEP THE REST OF THE FILE
<!--
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
-->

A newer installation may use RemoteCIDRValve with a localhost CIDR list instead. Apply the same comment-out approach to the existing block only; do not add another Valve or mix regex syntax with CIDR syntax. [4]

If there is no remote-address Valve in the active Manager configuration, do not invent one to remove. Another proxy, global Valve, security constraint, or authorization issue may explain the 403. Consult the troubleshooting section.

Save with Ctrl+O → Enter → Ctrl+X, then restart:

ON THE TOMCAT SERVER
sudo systemctl restart tomcat8
sudo systemctl status tomcat8 --no-pager

Repeat the external command in Step 7. Leave web.xml authentication constraints, Realm configuration, the Host Manager application, and port 8090 unchanged.

09

Save the deployment details in GitLab

Use the GitLab project that runs your pipeline. These are Tomcat application credentials, not your SSH login, GitHub token, or GitLab account password.

  1. Open the GitLab project in your browser.
  2. In the project’s left sidebar, select Settings → CI/CD.
  3. Find Variables and select Expand if it is collapsed.
  4. Select Add variable. If the key already exists, select Edit instead of creating a duplicate.
  5. Add or update the following three entries, saving each one before adding the next.
KeyValueVisibility
TOMCAT_URLhttp://YOUR-TOMCAT-PUBLIC-IP:8090
No trailing slash or /manager. Use HTTPS when configured.
Visible
TOMCAT_USERgitlab-deployerVisible
TOMCAT_PASSWORDThe exact generated password saved in Tomcat.Masked and hidden for a new variable

For each entry, use Type: Variable, Environment scope: All (*), and leave Expand variable reference off. An existing variable can be masked, but making it hidden requires creating a new variable. [6]

No APP_DIR, WAR_FILE, or TOMCAT_CONTEXT variables are needed. No changes to the two-job YAML are required.

10

Return to the simple build-and-deploy lab

If the pipeline file has not been created yet, continue to the beginner GitLab build-and-deploy lab. The Manager prerequisite is now configured.

If .gitlab-ci.yml already exists:

  1. In GitLab’s left sidebar, select Build → Pipelines.
  2. Select New pipeline.
  3. In Run for branch name or tag, select the branch containing the pipeline, usually main.
  4. Do not enter passwords into the manual-run form. Use the project variables saved in Step 9.
  5. Select New pipeline to start it.
  6. Open the new pipeline, then open the deploy job after the build finishes.

These are GitLab’s current manual pipeline navigation labels. [7]

In the deployment log, look for a Tomcat response starting with OK. Then open the application in your browser:

OPEN IN YOUR BROWSER
http://YOUR-TOMCAT-PUBLIC-IP:8090/MyWebApp/
11

Close the temporary access after the exercise

  1. If you commented out a remote-address Valve, reopen that same file and remove the <!-- and --> markers around the original Valve. Save and restart Tomcat.
  2. After the class no longer needs deployments, remove or disable the temporary gitlab-deployer account and remove its GitLab secret. Do not remove it while students still need to finish the deployment lab.
  3. Rotate any credentials used over public HTTP. Do not reuse the lab password for another system.
  4. For ongoing classes, arrange a supported Tomcat release and an HTTPS deployment endpoint with controlled access rather than repeatedly leaving Manager open.

Restoring a localhost-only Valve intentionally prevents direct deployments from GitLab-hosted runners until an approved access route is provided again.

Recovery: Manager returns 404

A 404 is a deployment or routing problem, not a reason to add more roles. First check for the two locations used by the original installation:

ON THE TOMCAT SERVER
sudo ls -l /var/lib/tomcat8/webapps/manager/WEB-INF/web.xml
sudo ls -l /var/lib/tomcat8/conf/Catalina/localhost/manager.xml
sudo ls -l /usr/share/tomcat8-admin/manager/WEB-INF/web.xml

A missing webapps/manager directory is not conclusive if an external manager.xml points to /usr/share/tomcat8-admin/manager. Read an existing descriptor before copying files.

Restore the copied Manager only when the package source exists and neither a Manager directory nor an external Manager descriptor is active:

ON THE TOMCAT SERVER
sudo cp -a /usr/share/tomcat8-admin/manager /var/lib/tomcat8/webapps/manager
sudo systemctl restart tomcat8

Copy only manager, not every administrative application. Do not copy over an existing active Manager or install two Manager contexts.

If the package source is missing: on an existing package-managed tomcat8 installation, the following requests the admin package at the exact installed Tomcat package version:

ON THE TOMCAT SERVER
sudo apt-get install "tomcat8-admin=$(dpkg-query -W -f='${Version}' tomcat8)"

This succeeds only if that version is still available from the configured repositories. If unavailable, do not add untrusted repositories, disable signature verification, or install another Tomcat major version’s Manager. Have the instructor supply a matching distribution or move the lab to a supported release. Then repeat the location check above.

If Manager files exist but the URL still returns 404, inspect startup logs, the active virtual host, and the descriptor’s docBase instead of reinstalling blindly.

Different service name or installation path

Some students may have a newer or manually installed Tomcat even though the original article uses tomcat8. Identify the running instance; do not substitute version numbers blindly.

ON THE TOMCAT SERVER
systemctl list-unit-files --type=service | grep -i tomcat
ps -eo pid,args | grep '[o]rg.apache.catalina.startup.Bootstrap'

Find -Dcatalina.base=... in the Tomcat process arguments. Use that directory for the users file and external context descriptor:

PATH PATTERNS — NOT COMMANDS
ACTUAL_BASE/conf/tomcat-users.xml
ACTUAL_BASE/conf/Catalina/localhost/manager.xml

Restart the actual service reported by the first command. If no service is listed, the server may have been started manually or in a container; use the instructor’s existing start/stop method. Do not create a new service during this lab.

The account role and /manager/text/ URLs stay the same. The Manager application must come from the matching Tomcat version. [2] [3]

Troubleshooting by symptom

What you seeWhat to check
Local 401 after entering credentialsUsername/password, uncommented XML, manager-script, correct running instance, and whether Tomcat was restarted. Repeated bad logins may trigger the configured lockout.
Local OK, external 403Active Manager Valve, external manager.xml precedence, reverse proxy restrictions, or wider Tomcat request restrictions.
403 at /manager/htmlExpected for a script-only user. Use the terminal test at /manager/text/list; do not add GUI permissions.
404 at /manager/text/listManager files, startup errors, virtual host, and docBase. Follow the recovery section.
Local works; external connection times outCorrect public address, port 8090, service listener, and existing firewall/security-group source rules. Opening a browser from your laptop does not prove a hosted runner is allowed.
Tomcat fails after editingRestore the affected backup if necessary; inspect malformed XML, missing quotes, duplicate closing tags, or a misspelled class name.
GitLab authentication fails, but local tests workProject variable values and scopes, protected-variable availability, and whether the GitLab project is the one actually running the job.
Job is green, app did not changeRead Tomcat’s response. With the simplified curl command, a 401, 403, or FAIL body can be missed without a manual review.

To inspect the existing service logs:

ON THE TOMCAT SERVER
sudo journalctl -u tomcat8 -n 100 --no-pager

If that only shows service messages, inspect the files in /var/log/tomcat8 or the active instance’s logs directory. Do not share passwords, Authorization headers, or the complete users file when asking for help.

Completion checkpoint

  • The existing Tomcat service still uses port 8090.
  • The Manager text endpoint responds to the dedicated deployment account.
  • Both local and external /manager/text/list tests return OK.
  • Only the three Tomcat connection variables are saved in GitLab.
  • The existing two-job pipeline remains unchanged.
  • Temporary exposure has an agreed cleanup step.

References

  1. Original DevOpStreams installation lab
  2. Apache Tomcat 8.5: Manager application and roles
  3. Apache Tomcat: Context configuration precedence
  4. Apache Tomcat: Remote address and CIDR valves
  5. GitLab.com: Runner outbound IP addresses
  6. GitLab: Add and protect CI/CD variables
  7. GitLab: Run a pipeline manually
  8. curl: Authentication and HTTP error handling
  9. Apache Tomcat: Secure management applications
  10. Apache Tomcat 8.0: End of support
  11. Apache Tomcat 8.5: End of support
VSIT • Lab 5.9 • Companion to the MyWebApp GitLab build-and-deploy lab • Documentation checked 19 September 2026. Server configuration must be verified on the actual class VM.

Gitlab build and deploy

GitLab CI/CD Hands-On Lab

Build and Deploy a Java Web Application to Tomcat

A simple two-stage GitLab pipeline that builds MyWebApp.war and deploys it to the existing Tomcat server on port 8090.

Lab Objective
Configure GitLab CI/CD to build the existing Lab 6 Maven project and deploy the generated WAR file directly to the existing Tomcat server.

Lab Assumptions

This lab assumes the following components are already working:

  • The Java project is already available in the repository connected to GitLab.
  • The Maven project is located in MyWebApp.
  • The POM file is located at MyWebApp/pom.xml.
  • The Maven build generates MyWebApp/target/MyWebApp.war.
  • Tomcat is already installed, running, and reachable on port 8090.
  • The Tomcat Manager application is already configured.
  • The existing Tomcat username and password used by the Jenkins Lab 6 deployment are available.
  • GitLab-hosted runners are enabled for the project.

CI/CD Flow

Developer pushes code
        |
        v
GitLab pipeline starts
        |
        v
Maven builds MyWebApp
        |
        v
MyWebApp.war is created
        |
        v
GitLab saves the WAR as an artifact
        |
        v
Deploy job downloads the WAR
        |
        v
WAR is uploaded to Tomcat on port 8090
        |
        v
Application runs at /MyWebApp

Repository Structure

The repository should look similar to this:

project-root/
├── .gitlab-ci.yml
└── MyWebApp/
    ├── pom.xml
    └── src/
        ├── main/
        └── test/

Step 1 — Add the Tomcat Variables in GitLab

Open the GitLab project and navigate to:

Settings → CI/CD → Variables

Add only the following three variables. The application directory, WAR path, and Tomcat context are fixed directly in the pipeline, so students do not need to create variables for them.

Variable Value
TOMCAT_URL http://YOUR-TOMCAT-IP:8090
TOMCAT_USER The same Tomcat username used in Jenkins
TOMCAT_PASSWORD The same Tomcat password used in Jenkins
No additional variables are required.
You do not need to create APP_DIR, WAR_FILE, or TOMCAT_CONTEXT in GitLab. The pipeline already uses MyWebApp, MyWebApp/target/MyWebApp.war, and /MyWebApp directly.
Important: Enter only the Tomcat base URL. Do not add /manager or /MyWebApp to TOMCAT_URL.

Example:

TOMCAT_URL=http://20.120.45.90:8090

Set TOMCAT_PASSWORD to Masked and hidden.

Step 2 — Create the GitLab Pipeline File

Create the following file at the root of the repository:

.gitlab-ci.yml

Paste the following pipeline into the file:

stages:
  - build
  - deploy

variables:
  APP_DIR: "MyWebApp"
  WAR_FILE: "MyWebApp/target/MyWebApp.war"
  TOMCAT_CONTEXT: "/MyWebApp"

build:
  stage: build

  image: "maven:3.9.16-eclipse-temurin-21-noble"

  script:
    - mvn -B -ntp -f "$APP_DIR/pom.xml" clean install

  artifacts:
    paths:
      - "$WAR_FILE"

deploy:
  stage: deploy

  image: "alpine:3.22"

  needs:
    - job: build
      artifacts: true

  before_script:
    - apk add --no-cache curl

  script:
    - >
      curl
      --user "$TOMCAT_USER:$TOMCAT_PASSWORD"
      --upload-file "$WAR_FILE"
      "${TOMCAT_URL}/manager/text/deploy?path=/MyWebApp&update=true"

How the Pipeline Works

Build Job

The build job uses Maven and Java 21 to run:

mvn clean install

The command reads:

MyWebApp/pom.xml

and generates:

MyWebApp/target/MyWebApp.war

GitLab saves the WAR file as a job artifact.

Deploy Job

The deploy job downloads the WAR artifact and uploads it to:

http://YOUR-TOMCAT-IP:8090/manager/text/deploy?path=/MyWebApp&update=true

The application is deployed under:

/MyWebApp

The update=true parameter allows Tomcat to replace the existing deployment.

Step 3 — Commit and Push the Pipeline

Run:

git add .gitlab-ci.yml
git commit -m "Add GitLab build and Tomcat deployment"
git push origin main

Step 4 — Monitor the Pipeline

In GitLab, navigate to:

Build → Pipelines

You should see two stages:

build
  └── build

deploy
  └── deploy

The expected flow is:

build: passed
      |
      v
deploy: passed

Step 5 — Verify the Application

Open the deployed application in a browser:

http://YOUR-TOMCAT-IP:8090/MyWebApp

Example:

http://20.120.45.90:8090/MyWebApp

Step 6 — Test Continuous Deployment

Edit a visible application file such as:

MyWebApp/src/main/webapp/index.jsp

Change the page content, then run:

git add .
git commit -m "Update MyWebApp page"
git push origin main

GitLab will automatically:

  1. Start a new pipeline.
  2. Build the application.
  3. Create MyWebApp.war.
  4. Save the WAR as an artifact.
  5. Deploy the WAR to Tomcat on port 8090.
  6. Replace the existing /MyWebApp application.

Refresh the application URL to see the updated page.

Final Result
Every pipeline builds the Maven project and deploys the resulting WAR file to the existing Tomcat server.

Final Workflow

Git Push
   |
   v
GitLab-Hosted Runner
   |
   v
mvn clean install
   |
   v
MyWebApp.war
   |
   v
GitLab Artifact
   |
   v
Tomcat Manager on Port 8090
   |
   v
/MyWebApp
Lab Behavior: This pipeline has no branch conditions or manual approval. Every pipeline run builds and deploys to the same Tomcat application.

Gitlab (Bonus)

Violet Streams • DevOps hands-on lab • Lab 6G

Your First GitLab CI/CD Pipeline
Build and Deploy to Tomcat

Start in the browser. Import the working Lab 6 application, add three variables, and deploy to your existing Tomcat server on port 8090.

BEGINNER WALKTHROUGH  |  HOSTED RUNNERS  |  BUILD → DEPLOY
What you will complete
A two-job pipeline: Maven builds MyWebApp.war; the next job uploads that file to your existing Tomcat server. There are no branch conditions, manual approvals, or custom deployment checks in the YAML. Your Tomcat installation is not changed.

Use the same working project, server, port, and Tomcat deployment credentials from Lab 6. You do not need to install GitLab, Maven, Java, Docker, or a runner on your laptop for this browser-based walkthrough.

Choose the right starting point
New to GitLab: follow all steps. The main route imports GitHub into GitLab once, then uses the GitLab copy for class.
Project already imported: sign in, open it, and begin at Step 3.
GitHub already connected for external CI/CD: keep that connection; do not create a duplicate import. Follow the GitHub-specific note in Step 7 for code changes.

Documentation: GitLab: your first CI/CD pipeline · GitLab: CI/CD for external repositories

Have this readyUse your existing Lab 6 information
GitHub source repositoryYour repository containing MyWebApp/pom.xml.
Build outputMyWebApp/target/MyWebApp.war; the project already builds with Java 21.
Tomcat addresshttp://YOUR-TOMCAT-IP:8090; use the public host name or IP supplied for your lab.
Tomcat credentialsThe existing Manager deployment username and password. These are not your GitLab or GitHub login.
AccessYour own isolated lab project, or a project where your instructor grants the required Maintainer access.
Shared-server caution
Every branch pipeline with a successful build attempts to replace the same /MyWebApp application. Coordinate with classmates and do not run the old Jenkins deployment at the same time. Use lab-only credentials; HTTP on port 8090 does not encrypt them. For real deployments, use HTTPS.

Step 1 — Create your GitLab account

  1. Open a browser tab and go to GitLab’s sign-up page.
  2. Enter your first name, last name, a unique username, an email address you can access, and a password. Select Continue. Already registered? Select Sign in instead.
  3. Open the verification email and complete the verification requested by GitLab. Return to the GitLab tab and finish any required onboarding prompts.
  4. Use GitLab.com, not a self-managed installation. This import-and-build route does not need a Premium subscription.
  5. Once signed in, keep this tab open. Use the top Search or go to bar whenever you need to find your project again.
Account verification
GitLab may also request phone or card verification. Follow only the prompts on the official GitLab site. A verification prompt is not an instruction to install a runner or automatically buy a subscription.

Documentation: GitLab sign-up page · GitLab: identity verification · GitLab: your first CI/CD pipeline

Step 2 — Import your working GitHub project

WHERE TO CLICKCreate new (+) → New project/repository → Import project → GitHub
  1. In GitLab’s top bar, find the + / Create new menu, currently in the upper-right area. Choose New project/repository.
  2. Choose Import project, then select GitHub. Do not choose a blank project or the external-repository option for this route.
  3. Select Authorize with GitHub. Sign in to the GitHub account that owns or can access your Lab 6 repository, review the permissions, and authorize GitLab.
  4. Back in GitLab, locate the correct repository. Set its destination namespace to your own account or the instructor-approved group. A namespace is the owner shown before the project name.
  5. Use a project name such as mywebapp-gitlab-lab. If import options include collaborators, leave them out for an individual lab unless your instructor needs them.
  6. Click Import beside that repository—not Import all repositories.
  7. When the status shows Complete, click the new GitLab project path to open it. If the source is absent, confirm you authorized the correct GitHub account and have access to that repository.
From this point, edit the GitLab copy
This is a one-time import. Your GitHub repository is not deleted, but later GitHub changes do not automatically arrive here. Complete the remaining browser edits in GitLab. Ongoing GitHub mirroring/external CI is a separate setup.

Documentation: GitLab: import from GitHub · GitLab: CI/CD for external repositories

Step 3 — Find your way around the project

WHERE TO CLICKYour project → Code → Repository
  1. Look for your project’s name at the top of the left sidebar. These instructions use project settings, not your profile settings or a group’s settings.
  2. Expand Code in that sidebar, then choose Repository. The main panel shows your files and folders.
  3. Find the branch selector above the file list. Leave the default branch selected. It may be main or master; do not rename it for this lab.
  4. Click MyWebApp, then pom.xml to view the existing project. Do not replace the working POM.
  5. Return to the top-level file list by clicking the project name in the file-path breadcrumb or selecting Code → Repository again.
Your project before adding the pipeline
repository-root/
└── MyWebApp/
    ├── pom.xml
    └── src/
        ├── main/
        └── test/
MenuWhat you will use it for
Code → RepositoryView files and make browser edits.
Settings → CI/CDFind runners and enter the three variables.
Build → PipelinesOpen each pipeline and its job logs.
Build → ArtifactsBrowse or download the generated WAR.
Missing Settings?
Confirm you opened the project rather than a group or your profile. Variable management requires Maintainer access. Ask your instructor for that access when using a shared project.

Documentation: GitLab: your first CI/CD pipeline · GitLab: CI/CD variables · GitLab: job artifacts

Step 4 — Enable GitLab-hosted runners

WHERE TO CLICKProject sidebar → Settings → CI/CD → Runners → Expand
  1. Click Settings in the project’s left sidebar, then CI/CD.
  2. Find the Runners section and click Expand.
  3. In the instance-runner area, leave Turn on instance runners for this project enabled. Turn it on if it is off and you are allowed to change it.
  4. Do not choose Create project runner. There is nothing to install or register.
  5. Keep the supplied YAML untagged. GitLab’s hosted Linux runner will execute these jobs.

A runner is the machine that executes a job. The Maven container provides Java and Maven for the build; the Alpine container is used for deployment. You do not install either image on your computer.

A disabled toggle or verification banner
A parent group may control runner access. Ask the instructor to enable it at the group level when necessary. Complete any GitLab account-verification prompt before starting CI. Hosted compute usage is limited by the account or namespace plan.

Documentation: GitLab: enable instance runners · GitLab: hosted Linux runners · GitLab: identity verification

Step 5 — Enter the three Tomcat variables

WHERE TO CLICKProject sidebar → Settings → CI/CD → Variables → Expand → Add variable

Create each row below separately. Keep Type = Variable, Environment scope = All (*), and Expand variable reference = off. For this isolated, all-branch lab, leave Protect variable = off. Do not use this setting for shared production credentials.

  1. Expand Variables, then click Add variable.
  2. Copy the first row’s Key exactly. Enter only its value in Value; do not paste KEY=value or add quotation marks.
  3. Select the listed Visibility and click Add variable to save.
  4. Repeat for rows 2 and 3, using Add variable each time.
Row / KeyValue to enterVisibility
1 — TOMCAT_URLhttp://YOUR-TOMCAT-IP:8090
Replace the host with your server. No trailing slash, /manager, or /MyWebApp.
Visible
2 — TOMCAT_USERYour existing Tomcat deployment username, for example tomcat.Visible
3 — TOMCAT_PASSWORDYour existing Tomcat deployment password. Do not enter a GitLab/GitHub password.Masked and hidden
Password masking
Masked values must be one line, contain no spaces, and have at least eight characters. A short username such as tomcat is intentionally Visible. If the existing password cannot be masked, ask your instructor for a suitable lab password rather than exposing it.
Only three variables
Confirm the table contains TOMCAT_URL, TOMCAT_USER, and TOMCAT_PASSWORD. Do not create APP_DIR, WAR_FILE, or TOMCAT_CONTEXT. The paths are written directly in the YAML.

Documentation: GitLab: CI/CD variables

Step 6 — Create the pipeline file in GitLab

WHERE TO CLICKCode → Repository → Repository root → + → New file
  1. Return to Code → Repository. Stay at the top-level file list, outside MyWebApp.
  2. Leave the default branch selected in the branch dropdown.
  3. Above the file list, click the + menu next to the directory/repository controls. Choose New file. This is the repository’s + menu, not the global menu for creating projects.
  4. In Filename, enter exactly .gitlab-ci.yml. Include the first dot. Do not add .txt.
  5. Click inside the large editing area. Paste the complete YAML from Step 7; use it instead of any suggested template.
Already have .gitlab-ci.yml?
Open that file at the repository root, select Edit → Edit single file, and replace its contents with Step 7. Do not create a second pipeline file.
Correct file location
repository-root/
├── .gitlab-ci.yml        ← Create the file here
└── MyWebApp/
    ├── pom.xml
    └── src/

Documentation: GitLab: your first CI/CD pipeline · GitLab: Web Editor

Step 7 — Paste the simple pipeline and commit it

Copy only the following YAML into the editor. Keep the indentation. Do not paste the Blogger HTML or Markdown backticks into GitLab.

.gitlab-ci.yml — copy the complete block
stages:
  - build
  - deploy

build:
  stage: build

  image: "maven:3.9.16-eclipse-temurin-21-noble"

  script:
    - mvn -B -ntp -f MyWebApp/pom.xml clean install

  artifacts:
    paths:
      - MyWebApp/target/MyWebApp.war

deploy:
  stage: deploy

  image: "alpine:3.22"

  needs:
    - job: build
      artifacts: true

  before_script:
    - apk add --no-cache curl

  script:
    - >
      curl
      --user "$TOMCAT_USER:$TOMCAT_PASSWORD"
      --upload-file MyWebApp/target/MyWebApp.war
      "${TOMCAT_URL}/manager/text/deploy?path=/MyWebApp&update=true"

The build runs the existing Maven goal, clean install. The artifact carries MyWebApp.war into the separate deploy job. update=true tells Tomcat to replace the existing application at /MyWebApp.

  1. Click Commit changes. If a commit dialog opens, enter Add GitLab build and Tomcat deployment as the commit message.
  2. Keep the current/default branch selected. Do not choose Commit to a new branch or create a merge request for this introductory run.
  3. Confirm Commit changes in the dialog. Saving a commit in the browser already updates the remote repository; no terminal git push is needed.
  4. You should return to the file view. The committed pipeline is now eligible to start.
Already using GitHub as the live source?
For an instructor-configured external-repository CI connection, create this file in the GitHub repository root using Add file → Create new file, then commit it there. Continue in GitLab for variables and job logs. Make the later page edit in GitHub too. Do not edit the mirrored copy in GitLab; a later sync can overwrite it.

Documentation: GitLab: your first CI/CD pipeline · GitLab: Web Editor · Docker Official Image: Maven · GitLab: job artifacts · Apache Tomcat: Manager text API · GitLab: CI/CD for external repositories

Step 8 — Open the pipeline and read the build log

WHERE TO CLICKProject sidebar → Build → Pipelines → Latest pipeline ID → build
  1. Expand Build in the left sidebar. Click Pipelines.
  2. Find the row with your latest commit message. Click its pipeline number/ID to open it.
  3. The diagram contains build and deploy. Click the build job to open the scrolling log.
  4. Follow Maven’s output. A successful build ends with BUILD SUCCESS and an artifact-upload message.
  5. Click the pipeline ID/breadcrumb above the job to return to the diagram. Once the build succeeds, the deployment job can start.
StatusMeaning in this lab
PendingThe job is queued or waiting for an eligible runner.
RunningThe runner is executing the job.
PassedThe job commands returned success. Read the deployment response in Step 10 too.
FailedOpen that job’s log and locate the first relevant error.
SkippedThe job did not run; for example, deployment is not run after a failed build.

If no pipeline appears, confirm the file is named .gitlab-ci.yml at the repository root and that the commit was saved. Use Step 13 to start the same configuration manually.

Documentation: GitLab: your first CI/CD pipeline · GitLab: start and view pipelines

Step 9 — Locate the generated WAR artifact

WHERE TO CLICKBuild → Pipelines → Your pipeline → build → Job artifacts → Browse
  1. Open the completed build job.
  2. Look in the job’s right-hand details area for its artifacts and select Browse. You can also use Build → Artifacts and open the build job’s artifact entry.
  3. In the artifact browser, open MyWebApp, then target.
  4. Find MyWebApp.war. Downloading it is optional; the deploy job retrieves it automatically.

Do not look for target in the source repository. It is generated during the job, not committed as source. The needs section downloads the build artifact into deployment’s separate workspace.

Documentation: GitLab: job artifacts · GitLab: hosted Linux runners

Step 10 — Read Tomcat’s deployment response

WHERE TO CLICKBuild → Pipelines → Your pipeline → deploy
  1. Return to the pipeline diagram and click the deploy job.
  2. In its log, locate the response printed after the curl command.
  3. A successful Manager deployment normally prints a line beginning with OK. A line beginning with FAIL means Tomcat rejected it.
  4. Continue to Step 11 to open the actual application. Do not treat the status badge alone as proof of deployment.
Illustrative Tomcat response
OK - Deployed application at context path /MyWebApp
Why you must read the response
This intentionally minimal pipeline does not check HTTP status codes, parse Tomcat’s response, or run a health check. Plain curl may exit successfully even after receiving an HTTP error page. A green job is therefore not sufficient evidence that the application was deployed.

Documentation: Apache Tomcat: Manager text API · curl: HTTP error handling

Step 11 — Open the deployed application

  1. Open a separate browser tab.
  2. In the address bar, type the URL below, replacing the placeholder with your existing Tomcat public host.
  3. Press Enter. The Lab 6 web page should appear.
  4. Keep the tab open for the next exercise. Retain the exact capitalization of MyWebApp.
Application URL — not the Manager URL
http://YOUR-TOMCAT-IP:8090/MyWebApp/

Use your application address here, not /manager/text/deploy. The Manager endpoint accepts the deployment; /MyWebApp/ is the page your visitors open.

Documentation: Apache Tomcat: Manager text API

Step 12 — Make a browser edit and redeploy

WHERE TO CLICKCode → Repository → MyWebApp → src → main → webapp → index.jsp → Edit → Edit single file
  1. Return to GitLab and choose Code → Repository. Use the same branch as before.
  2. Open MyWebAppsrcmainwebappindex.jsp.
  3. At the file’s upper-right, select Edit → Edit single file.
  4. Change only the visible heading to the sample below. Keep the rest of the existing page and JSP syntax intact.
  5. Click Commit changes, enter Update home page from GitLab, and commit to the current branch.
  6. Open Build → Pipelines. Open the new pipeline and follow both jobs as you did before.
  7. Read the deploy response. Then refresh the application tab to see your new heading. If your browser shows the old page, try a hard refresh.
Edit the existing heading; do not replace the entire JSP
<h1>Hello from GitLab CI/CD!</h1>
Source repository reminder
After the one-time import, make this change in GitLab. With an already configured external GitHub CI integration, instead edit the same file in GitHub and watch its connected GitLab pipeline.

Documentation: GitLab: Web Editor · GitLab: CI/CD for external repositories

Step 13 — Run the pipeline again without editing code

WHERE TO CLICKBuild → Pipelines → New pipeline → Select branch → New pipeline
  1. In the GitLab project, open Build → Pipelines.
  2. Click New pipeline in the upper-right area of the page. Older layouts may call it Run pipeline.
  3. In Run for branch name or tag, select the branch containing .gitlab-ci.yml.
  4. Do not enter the Tomcat password on this page. The job already uses your saved project variables.
  5. Click New pipeline to launch it. Open the pipeline ID, then each job log.
This also deploys
Starting a new pipeline reruns the build and then attempts deployment to the same application. There is no approval button or branch filter in this YAML. Do not start multiple runs against the shared Tomcat application at once.

Documentation: GitLab: start and view pipelines

When a student gets stuck

What you seeWhere to go / what to check
No Settings or Add variable controlConfirm you are inside the project. Ask for Maintainer access rather than editing a group or profile.
Variable cannot be savedUse Visible for the URL and username. A masked password must meet the masking requirements. Enter values without surrounding quotes or KEY=.
Job remains pendingReturn to Settings → CI/CD → Runners. Check instance-runner availability, verification prompts, and account/namespace compute availability. Do not install a runner.
Build cannot find pom.xmlOpen Code → Repository and confirm MyWebApp/pom.xml. This YAML assumes that exact existing Lab 6 layout.
Build failsOpen Build → Pipelines → pipeline ID → build. Read the Maven error, not only the final red status.
Empty or wrong Tomcat credentialOpen Settings → CI/CD → Variables; choose Edit beside the relevant key, correct it, and save with Update variable. Then use Step 13. Never print passwords in a job log.
401, 403, timeout, or HTML error pageRecheck the saved URL and existing deployment credentials. A Jenkins connection working does not prove this separate hosted runner has the same network access. Ask the instructor to review access from GitLab; do not remove server restrictions blindly.
Green deploy job, unchanged applicationRead the deploy log’s response and use the exact /MyWebApp/ application path. This pipeline does not automatically detect every Tomcat rejection.
Cannot commit to current branchThe imported branch may have protection rules. Ask your instructor for the correct lab permissions; do not remove shared-project protections.

Documentation: GitLab: CI/CD variables · GitLab: enable instance runners · GitLab: identity verification · GitLab: import from GitHub · curl: HTTP error handling

Lab completion evidence
Show your instructor the pipeline containing both jobs, the MyWebApp.war artifact, the Tomcat OK response, and the updated page at port 8090. Do not include passwords in screenshots.
The complete classroom workflow
Edit in GitLab → Commit → build → WAR artifact → deploy → Tomcat :8090/MyWebApp/

After class: remove or rotate temporary deployment credentials when they are no longer needed. Keep real production credentials restricted to trusted code and use HTTPS; this exercise intentionally omits production deployment controls.

Violet Streams Institute of Technology • Lab 6G • Navigation checked against official documentation on September 19, 2026. GitLab may move controls between releases; use the named project sections. This is a lab guide, not a record of a deployment performed on your server.

Enable Tomcat Manager

Violet Streams · DevOps Hands-On Lab · 5.9 Enable Tomcat Manager for GitLab CI/CD Prepare the existing Tomcat server for automated WAR dep...