Managing FastAPI Projects with Poetry: A Step-by-Step Guide

In a microservice architecture, it's common for multiple services to share common functionality or utility classes. To handle this effectively, I manage these shared components as a reusable library (like libs.jar
) that each service can depend on. In this post, I’ll show you how I use GCP Artifact Registry to efficiently manage and distribute a shared library across microservices.
$ gcloud services enable artifactregistry.googleapis.com --project=[PROJECT_ID]
$ gcloud artifacts repositories create maven-repo \
--repository-format=maven \
--location=us-central1 \
--description="Shared Maven Repo for common libraries"
$ gcloud artifacts repositories list --location=us-central1
REPOSITORY FORMAT LOCATION DESCRIPTION
maven-repo MAVEN us-central1 Shared Maven repo
pom.xml
for the Shared Library ProjectIn the shared library (libs
) project's pom.xml
, I define the following:
com.example.libs
)libs
)1.0.1
)jar
is recommended for reusable libraries)If the packaging
tag is missing or incorrect, Maven may mistakenly treat the library as pom
, war
, or another type — leading to problems when uploading to Artifact Registry or importing it into other projects.
<groupId>com.example.libs</groupId>
<artifactId>libs</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
GCP Artifact Registry for Maven requires using the artifactregistry://
protocol instead of https://
. Otherwise, authentication and upload may not work properly.
For snapshot versions (e.g., 0.0.1-SNAPSHOT
), Maven appends a timestamp to ensure uniqueness. Release versions remain fixed.
<distributionManagement>
<snapshotRepository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
</snapshotRepository>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
</repository>
</distributionManagement>
Version Type | Example | Description |
---|---|---|
<releases> |
1.0.0 |
Stable release; cannot be overwritten once uploaded |
<snapshots> |
0.0.1-SNAPSHOT |
Development version; overwritten with timestamped versions |
<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
Add Artifact Registry Maven Wagon Extension
To allow Maven to understand the artifactregistry://...
protocol, I include the official Google Artifact Registry Maven Wagon extension.
<build>
<extensions>
<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.2.5</version>
</extension>
</extensions>
</build>
application.yaml
for the Shared LibraryI disable unnecessary auto-configuration to avoid errors — especially since the shared library doesn't require a database.
spring:
application:
name: libs
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
Artifact Registry requires authentication. Since the access token from gcloud auth print-access-token
only lasts 1 hour, I use the credential helper provided by gcloud
to handle automatic token renewal for Maven.
On Windows, the credentials are stored in:
C:\Users\[USER]\AppData\Roaming\gcloud\application_default_credentials.json
I run the following command to enable this:
$ gcloud auth application-default login
In CI/CD environments like Cloud Build, I make sure the service account has the necessary roles to access Artifact Registry.
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member="serviceAccount:[PROJECT_NUMBER]-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.reader"
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member="serviceAccount:[PROJECT_NUMBER]-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.writer"
settings.xml
for MavenSince Cloud Build runs on a remote server and doesn't have access to my local ~/.m2/settings.xml
, I include a settings.xml
file in the build context (the project's root directory) and explicitly specify it using the -s
option.
<settings>
<servers>
<server>
<id>artifact-registry</id>
<username>oauth2accesstoken</username>
<password>
<!-- empty is fine; gcloud helper will inject the token -->
</password>
</server>
</servers>
</settings>
On my local machine, Maven uses:
C:\Users\[USER]\.m2\settings.xml
cloudbuild.yaml
-DskipTests
to skip running tests, which speeds up the build process. This is especially useful for shared libraries that are frequently updated and published..
) to /workspace
inside the build container.-B
to enable batch mode, which makes the Maven output cleaner.steps:
# 1. Build the JAR without running tests
- name: 'gcr.io/cloud-builders/mvn'
entrypoint: 'mvn'
args: ['clean', 'package', '-DskipTests']
# 2. Deploy the JAR to Artifact Registry
- name: 'gcr.io/cloud-builders/mvn'
args: ['deploy',
'-B',
'-s', '/workspace/settings.xml']
pom.xml
of Each ServicesIn this step, I configure each microservice (a-service
, b-service
, etc.) to use the shared library.
<dependency>
<groupId>com.example.libs</groupId>
<artifactId>libs</artifactId>
<version>1.0.1</version>
</dependency>
libs
project.<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.2.5</version>
</extension>
artifactregistry://
URLs.<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
[PROJECT_ID]
with your actual GCP project ID.us-central1
) matches where your Artifact Registry is located.To enable Maven to authenticate with GCP Artifact Registry during the build the services, the following command to configure authentication for gcloud
:
$ gcloud auth application-default login
Next, I place a settings.xml
file in the root directory of the service. This file provides the necessary credentials using oauth2accesstoken
, allowing Maven to access the GCP Artifact Registry and retrieve the shared library during the build.
<settings>
<servers>
<server>
<id>artifact-registry</id>
<username>oauth2accesstoken</username>
<password>
<!-- empty is fine; gcloud helper will inject the token -->
</password>
</server>
</servers>
</settings>
Then, I reference this file explicitly in the cloudbuild.yaml
using the -s
flag:
steps:
# 1. Java Build
- name: 'gcr.io/cloud-builders/mvn'
args: ['clean', 'package',
'-DskipTests',
'-B',
'-s', '/workspace/settings.xml']
Comments
Post a Comment