How to - ENG
How to
RPA Service Deployment Guide
1. Purpose of this guide
This guide describes the standard process for preparing, deploying, and updating RPA services developed by Automators within the working group.
The aim is to ensure that each service is deployed in an organized, traceable, and repeatable way, with as few unexpected issues as possible, following the Python, Docker, GitLab, and DevOps best practices adopted by the RPA group.
“Service deployment” means installing and running a service on a remote machine using Docker Compose, images published to the repository’s GitLab registry, and environment-specific configuration files.
2. Roles involved
2.1 RPA Developer / Team Lead
Responsible for developing the service and preparing the technical aspects of deployment.
Responsibilities include:
- developing the code;
- following the RPA group’s Python and Docker best practices;
- preparing Docker Compose files for the various environments;
- testing the service locally;
- building and publishing Docker images, through CI or manually;
- preparing the
.envfile for the target environment; - storing sensitive configurations in Bitwarden;
- opening the DevOps ticket;
- updating the Move to Prod tracking file once deployment is complete.
2.2 DevOps team
The team responsible for installing or updating the service on remote machines.
Responsibilities include:
- receiving the microservice delivery or update ticket;
- retrieving Docker Compose files,
.envfiles, and any required attachments; - installing or updating the service on the specified VM;
- configuring any required DNS records;
- checking that the service has started correctly;
- communicating that the work is complete.
2.3 RPA group
The group that owns the process, best practices, and governance of RPA services.
Responsibilities include:
- defining technical standards;
- maintaining shared conventions;
- ensuring deployment traceability;
- sharing operational information, such as available VMs, environments, and DNS names.
3. Tools used
3.1 GitLab
GitLab is used to:
- version source code;
- manage the service repository;
- run CI/CD pipelines, where applicable;
- publish Docker images to the repository’s registry;
- maintain traceability of commits, versions, and tags.
3.2 Docker and Docker Compose
Docker is used to containerize the RPA service.
Docker Compose is used to define how the service runs in the different environments:
- local;
- development;
- acceptance testing;
- production.
3.3 GitLab Container Registry
The repository’s GitLab registry contains the service’s Docker images.
The entire repository is not deployed to remote environments. Instead, the following are used:
- the environment’s Docker Compose file;
- the environment’s
.envfile; - the Docker image already published to the registry;
- any external files not included in the image.
3.4 Bitwarden
Bitwarden is used to securely store and share environment .env files.
The .env files must be stored in the RPA collection using the following naming convention:
env_<environment>_<automation_name>
Examples:
env_dev_automation-name
env_coll_automation-name
env_prod_automation-name
3.5 DevOps ticketing system
The DevOps ticketing system is used to request:
- delivery of new microservices;
- updates to existing microservices;
- changes to
.envfiles; - changes to Docker Compose files;
- uploads of local files;
- DNS configuration;
- work on remote VMs.
3.6 Move to Prod file
The Move to Prod file is the shared file used to track operational deployment information.
Among other things, it contains:
- VM availability;
- the relevant environment;
- the deployed service;
- the VM used;
- the DNS name used;
- any operational notes.
4. Expected repository structure
Before any deployment, the repository must comply with the RPA group’s Python and Docker best practices.
4.1 Code structure
Application code must be located in the following folder:
src/
Example:
repository/
├── src/
│ └── ...
├── docker-compose.local.yml
├── docker-compose.dev.yml
├── docker-compose.coll.yml
├── docker-compose.prod.yml
├── .env.example
├── Dockerfile
├── pyproject.toml
└── README.md
4.2 Required Docker Compose files
Docker Compose files must be provided for the planned environments:
docker-compose.local.yml
docker-compose.dev.yml
docker-compose.coll.yml
docker-compose.prod.yml
The naming convention may be adapted to the group’s actual standards, but it must be consistent and easily recognizable.
4.3 Environment file
At least one example file must be provided, such as:
.env.example
The .env.example file must contain all variables required by the service, without any actual sensitive values.
Example:
APP_ENV=local
LOG_LEVEL=INFO
DB_HOST=
DB_PORT=
DB_NAME=
DB_USER=
DB_PASSWORD=
SECRET_KEY=
4.4 Volume mounts
Mount paths in the various Docker Compose files must be relative to the current repository folder.
Correct example:
volumes:
- ./data:/app/data
- ./logs:/app/logs
Example to avoid:
volumes:
- /home/user/project/data:/app/data
Absolute local paths must not be used in Compose files intended for deployment, because they are not portable across environments and machines.
4.5 Docker images
Compose files for remote environments must not require building the code from the full repository.
The remote environment must use images already published to the GitLab registry.
Example:
services:
automazione:
image: registry.gitlab.com/gruppo/progetto/nome-servizio:dev-latest
env_file:
- .env
Alternatively, depending on the versioning strategy:
services:
automazione:
image: registry.gitlab.com/gruppo/progetto/nome-servizio:v1.2.3
4.6 Continuous Delivery labels
If the service needs to support automatic updates through CD, the Compose file must include the labels required by the group’s standard.
The labels must enable the system to identify:
- the service;
- the environment;
- the image to monitor;
- the update strategy.
Illustrative example:
labels:
- "rpa.cd.enabled=true"
- "rpa.cd.environment=dev"
- "rpa.cd.service=nome-automazione"
The actual labels must follow the standard defined by the RPA/DevOps group.
5. Differences between local and remote execution
5.1 Local execution
The entire repository is available locally.
The developer can therefore:
- run the code directly on the machine;
- modify the code;
- build the image;
- run the service using the local Compose file;
- mount local folders;
- perform full debugging.
The service can be tested locally in three ways:
- running directly on the machine;
- running in Docker using the local Compose file;
- running in Docker using an environment-specific Compose file, such as dev.
5.2 Remote execution
The entire repository is not copied to the remote environment.
The service runs using:
- the environment’s Docker Compose file;
- the environment’s
.envfile; - the Docker image published to the GitLab Container Registry;
- any external files not included in the image.
This means the remote service must be self-sufficient using the image, Compose file, and configuration.
6. Deployment environments
Ideally, deployments progress through three environments:
- development;
- acceptance testing;
- production.
6.1 Development
An environment used to check the service’s behavior in a remote, non-production setting.
It is used to validate:
- the Docker image;
- Docker Compose;
- the
.envconfiguration; - connections to external systems;
- the service’s overall behavior.
6.2 Acceptance testing
An environment used for testing under conditions closer to production.
It is used to validate:
- stability;
- more representative data and configurations;
- integrations;
- user testing or final functional testing.
6.3 Production
The final environment in which the service runs for operational use.
It requires greater attention to:
- credentials;
- DNS;
- final configurations;
- VM availability;
- traceability;
- impact on users;
- rollback.
6.4 Skipping environments
Depending on urgency, criticality, or the nature of the development work, some steps may be skipped.
Examples:
- deploying directly to acceptance testing;
- deploying directly to production;
- quickly deploying an urgent fix.
Skipping one or more environments must be a deliberate and justified decision, because it reduces the level of progressive verification.
7. Preliminary phase: local validation
Before opening a deployment ticket, the developer must verify that the service works correctly locally.
7.1 Testing the service directly on the machine
The first test consists of running the service directly on the local machine.
Objectives:
- verify that the Python code works;
- check dependencies;
- check basic configurations;
- catch application errors before containerization.
Example:
python -m src.main
Alternatively, depending on the project structure:
python src/main.py
7.2 Testing with the local Compose file
The second test consists of running the service using the local Compose file.
Example:
docker compose -f docker-compose.local.yml up --build
Objectives:
- check the Dockerfile;
- check the image build;
- check local mounts;
- check environment variable handling;
- check ports and volumes;
- check containerized behavior.
7.3 Testing with an environment-specific Compose file
After testing the local Compose file, testing at least the dev Compose file is recommended.
Example:
docker compose -f docker-compose.dev.yml --env-file .env.dev up
Objectives:
- verify that the image is compatible with the remote Compose file;
- verify that the service does not depend on files available only in the local repository;
- verify that the variables are sufficient;
- simulate the remote machine’s behavior as closely as possible.
8. Pre-deployment checklist
Before requesting deployment, verify that:
- the code is located in the
src/folder; - local, dev, acceptance testing, and prod Compose files are present;
- Compose mount paths are relative to the current folder;
- no absolute local paths are used;
- the Dockerfile is up to date;
- the image can be built;
- the service has been tested directly on the machine;
- the service has been tested with the local Compose file;
- the service has been tested with at least the dev Compose file;
- the environment’s
.envfile has been prepared; - the
.envfile has not been committed to the repository; - the
.envfile has been stored in Bitwarden; - the image has been published to the GitLab registry;
- the Compose file references the correct image;
- any required CD labels are present;
- any external files to attach have been identified;
- the target VM has been selected from the Move to Prod file;
- any required DNS names have been identified.
9. Building and publishing the Docker image
The Docker image can be published in two ways:
- through GitLab CI;
- manually from the developer’s local environment.
9.1 Building through CI
The preferred approach is an automatic build through a CI pipeline.
The pipeline can be triggered by:
- a push to a branch;
- a merge;
- a version tag;
- a specific commit;
- a manual workflow.
The image should have a clear tag.
Examples:
dev-latest
coll-latest
prod-latest
v1.2.3
commit-<sha>
A recommended strategy is to use both environment tags and immutable tags.
Example:
dev-latest
v1.2.3
commit-a1b2c3d
This way:
dev-latestenables quick updates;v1.2.3provides traceability;commit-<sha>supports technical auditing.
9.2 Manual builds
Alternatively, the image can be built locally and pushed manually.
Illustrative example:
docker build -t registry.gitlab.com/gruppo/progetto/nome-servizio:dev-latest .
docker push registry.gitlab.com/gruppo/progetto/nome-servizio:dev-latest
Manual builds must be used with care, because they are less traceable than a CI pipeline.
10. Preparing the .env file
The environment’s .env file must be derived from the local file or the .env.example file.
Each environment must have its own specific, independent variables.
10.1 Variables to make environment-specific
The following must differ between environments, where applicable:
- user passwords;
- database passwords;
- secret keys;
- API tokens;
- connection strings;
- service credentials;
- endpoints;
- database names;
- buckets;
- application users;
- encryption keys;
- integration configurations.
Example:
APP_ENV=dev
LOG_LEVEL=INFO
DB_HOST=db-dev.internal
DB_PORT=5432
DB_NAME=automazione_dev
DB_USER=automazione_dev_user
DB_PASSWORD=<password-dev>
SECRET_KEY=<secret-dev>
10.2 Storing the file in Bitwarden
Once prepared, the .env file must be stored in Bitwarden in the RPA collection.
Naming convention:
env_<environment>_<automation_name>
Examples:
env_dev_recupero-pratiche
env_coll_recupero-pratiche
env_prod_recupero-pratiche
This allows anyone with authorization to:
- retrieve the environment configuration;
- perform local debugging;
- check configurations;
- retrieve connection credentials;
- update the service in a controlled manner.
10.3 Creating a Bitwarden Send
After storing the .env file, a Bitwarden Send must be created.
The Send can contain:
- the text content of the
.envfile; - or the
.envfile itself.
The Send link must be attached to the DevOps ticket.
11. Opening a microservice delivery ticket
To request a new deployment, open a ticket in the DevOps system.
11.1 Ticket type
Select the following type (Microservice delivery):
Delivery microservizio
The ticket must be placed in the RPA context.
11.2 Remote environment
The ticket must specify the deployment environment:
- development;
- acceptance testing;
- production.
It must also specify the destination:
- cloud;
- headquarters;
- dedicated VM.
The VM must be selected based on the availability shown in the Move to Prod file, shared in the Python group’s Teams channel.
11.3 Information to include in the ticket
The ticket must contain at least:
- service name;
- GitLab repository;
- target environment;
- target VM;
- Docker Compose file to use;
- Docker image to use;
- image tag;
- Bitwarden Send link for the
.envfile; - any required DNS names;
- any attached files to deploy;
- any destination folders for those files;
- any operational notes;
- any dependencies or prerequisites.
11.4 Files to attach or link
The ticket must include attachments or references to:
- the environment-specific Docker Compose file;
- the Bitwarden Send for the
.envfile; - any supporting Excel files;
- any shapefiles;
- any data files;
- any templates;
- any configurations not included in the image.
Files that are not included in the Docker image must be explicitly identified, together with the path where DevOps must place them.
Example:
Attach the input_template.xlsx file for placement in ./data/templates/
Attach the shapefiles for placement in ./data/shapes/
12. DNS and external access
If the service requires external access, the required DNS names must be specified in the ticket.
As a best practice, DNS names must fall under the group’s standard domains.
For development and acceptance testing:
.rpa.collaudo-live.xyz
For production:
.rpa.eagleprojects.cloud
Illustrative examples:
nome-servizio.rpa.collaudo-live.xyz
nome-servizio.rpa.eagleprojects.cloud
The actual naming convention must be consistent with the group’s standards and approved by DevOps.
13. Completing deployment
Once DevOps has completed the work on the ticket, the developer must verify the service.
13.1 Post-deployment checks
Verify that:
- the container is running;
- the service responds correctly;
- the logs contain no critical errors;
- the environment variables are correct;
- any attached files are present;
- any DNS names resolve correctly;
- any integrations are operational;
- any schedulers or jobs are active;
- any endpoints are reachable.
13.2 Updating the Move to Prod file
Once deployment is complete, update the appropriate columns in the Move to Prod file.
Enter at least:
- service name;
- environment;
- VM used;
- DNS name used;
- repository;
- any notes;
- deployment date;
- DevOps ticket reference.
Deployment is considered complete only after:
- the DevOps ticket is completed;
- the service is technically verified;
- the Move to Prod file is updated.
14. Updating existing services
Updates may involve:
- the Docker image;
- the
.envfile; - Docker Compose;
- local files;
- DNS;
- additional configurations.
14.1 Updating the Docker image
If the service has been configured with the correct Continuous Delivery labels, the image can be updated automatically.
In this case, simply publish the new image under the environment’s latest tag.
Examples:
dev-latest
coll-latest
prod-latest
The CD system will detect the new image and update the service according to the configured settings.
14.2 Updating through CI
Recommended approach:
- modify the code;
- commit the changes;
- push to GitLab;
- wait for the pipeline build;
- verify that the image has been published;
- verify that the service has been updated automatically;
- check the logs and application behavior.
14.3 Updating the image manually
For a manual build:
docker build -t registry.gitlab.com/gruppo/progetto/nome-servizio:dev-latest .
docker push registry.gitlab.com/gruppo/progetto/nome-servizio:dev-latest
After pushing, verify that the remote system has picked up the update.
15. Updating .env, Compose, or local files
Updates that involve more than just the Docker image must go through a DevOps ticket.
15.1 Ticket type
Use the following type (Microservice update):
Aggiornamento microservizio
15.2 Required information
Specify the following in the ticket:
- service to update;
- affected environment;
- affected VM;
- requested change;
- new
.envfile, if required; - updated Bitwarden Send link;
- new Docker Compose file, if required;
- files to add or replace;
- destination path;
- any restart instructions;
- any checks to perform.
15.3 Updating the .env file
If the .env file changes:
- update its contents;
- store the new version in Bitwarden;
- create a new Bitwarden Send;
- attach the Send to the ticket;
- clearly state that the service must be restarted, if necessary.
15.4 Updating the Compose file
If the Docker Compose file changes:
- test the Compose file locally;
- verify that the image exists in the registry;
- attach the new Compose file to the ticket;
- describe the main changes;
- specify any impact on volumes, ports, labels, or networks.
15.5 Updating local files
If local files need to be added or modified:
- attach the files to the ticket;
- specify the destination path;
- state whether they replace existing files;
- state whether the service needs to be restarted.
Example:
Replace the configurazione.xlsx file in ./data/config/
Add the ./data/shapes/ folder with the attached contents
Restart the service once copying is complete
16. Microservice delivery ticket template
Title:
[MICROSERVICE DELIVERY] <service-name> - <environment>
Description:
I request deployment of the RPA service <service-name> to the <dev/acceptance testing/prod> environment.
GitLab repository:
<repository link>
Environment:
<dev/acceptance testing/prod>
Destination:
<cloud/headquarters/dedicated VM>
Target VM:
<VM name>
Docker image:
<registry/image:tag>
Docker Compose:
<attachment or link>
.env file:
<Bitwarden Send link>
Required DNS names:
<required DNS names or N/A>
Additional files:
<list of files, destination paths, any notes>
Operational notes:
<any specific instructions>
Required checks:
- container startup
- log check
- endpoint/scheduler/job check
- DNS check, if applicable
17. Microservice update ticket template
Title:
[MICROSERVICE UPDATE] <service-name> - <environment>
Description:
I request an update to the RPA service <service-name> in the <dev/acceptance testing/prod> environment.
Service:
<service-name>
Environment:
<dev/acceptance testing/prod>
VM:
<VM name>
Update type:
- Docker image
- .env file
- Docker Compose
- local files
- DNS
- other
Change details:
<detailed description of the change>
New Docker image:
<registry/image:tag or N/A>
New .env file:
<Bitwarden Send link or N/A>
New Docker Compose:
<attachment/link or N/A>
Files to add/replace:
<list of files and destination paths or N/A>
Restart required:
<yes/no>
Operational notes:
<any additional details>
18. Final deployment checklist
Before considering deployment complete, verify that:
- the DevOps ticket is completed;
- the service is running;
- the logs have been checked;
- DNS is working, if applicable;
- credentials are correctly stored in Bitwarden;
- the
.envfile is not present in the repository; - the correct Compose file is in place in the environment;
- the correct image is running;
- external files are present;
- Move to Prod has been updated;
- any relevant stakeholders have been informed.
19. Practical rules to remember
19.1 Do not deploy untested code
Before deployment, the service must have been tested at least:
- directly on the machine;
- with the local Compose file;
- with the dev Compose file or a Compose file equivalent to the one used in the remote environment.
19.2 Do not commit .env files
Actual .env files must not be stored in the repository.
The repository must contain only an example file, such as:
.env.example
19.3 Do not use absolute local paths in Compose files
Mount paths must be relative to the current folder:
./data:/app/data
They must not use absolute paths on the developer’s machine:
/home/nomeutente/progetto/data:/app/data
19.4 Do not depend on the full repository remotely
In a remote environment, the service must work with:
- the Docker image;
- Docker Compose;
- the
.envfile; - the declared external files.
19.5 Always update Move to Prod
The Move to Prod file is required to maintain operational traceability of deployed services.
Every deployment or significant change must be recorded in the file.
20. Process overview
New deployment
Develop the code
↓
Validate the repository
↓
Test directly on the machine
↓
Test the local Compose file
↓
Test the dev/coll/prod Compose file
↓
Build the image
↓
Push the image to the GitLab Registry
↓
Prepare the environment’s .env file
↓
Store the .env file in Bitwarden
↓
Create a Bitwarden Send
↓
Select a VM from Move to Prod
↓
Open a microservice delivery ticket
↓
DevOps performs the work
↓
Verify the service
↓
Update Move to Prod
↓
Deployment complete
Service update
Modify the code/configuration
↓
Test locally
↓
If only the image changes:
push the new image under the environment’s latest tag
verify the automatic CD update
↓
If env/compose/files change:
update Bitwarden if necessary
open a microservice update ticket
DevOps performs the work
↓
Verify the service
↓
Update Move to Prod if necessary
No comments to display
No comments to display