Push Docker image and Python package to GitLab registries

This howto describes how to push the rediflow Docker image to the GitLab Container Registry and the Python package to the GitLab PyPI Package Registry. You can do this manually (local) or via CI automation on version tags.

Registry URLs (gitlab.com)

Registry URL pattern
Container registry.gitlab.com/<namespace>/<project> (e.g. registry.gitlab.com/mygroup/rediflow)
PyPI (project) https://gitlab.com/api/v4/projects/<project_id>/packages/pypi
PyPI (simple) https://gitlab.com/api/v4/projects/<project_id>/packages/pypi/simple

In CI, use $CI_REGISTRY_IMAGE and $CI_PROJECT_ID. Replace <project_id> with your numeric project ID or URL-encoded path (e.g. mygroup%2Frediflow).


1. Docker image → GitLab Container Registry

Manual (local)

  1. Login once (use your GitLab username and personal access token or password):

    podman login registry.gitlab.com   # or docker login
    
  2. Build and push (replace REGISTRY_IMAGE with your project path, e.g. registry.gitlab.com/mygroup/rediflow):

    REGISTRY_IMAGE=registry.gitlab.com/<namespace>/<project>
    VERSION=2.0.1   # match pyproject.toml
    podman build -t "$REGISTRY_IMAGE:v$VERSION" .
    podman tag "$REGISTRY_IMAGE:v$VERSION" "$REGISTRY_IMAGE:latest"
    podman push "$REGISTRY_IMAGE:v$VERSION"
    podman push "$REGISTRY_IMAGE:latest"
    

CI automation (on tag push)

When you push a tag matching v*.*.*, the build-image job builds the image and pushes it to the project's GitLab Container Registry. No extra CI variables are needed; GitLab provides $CI_REGISTRY, $CI_REGISTRY_USER, and $CI_REGISTRY_PASSWORD.

The image is pushed as $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG and $CI_REGISTRY_IMAGE:latest.


2. Python package → GitLab PyPI Package Registry

Manual (local)

  1. Create a Personal Access Token in GitLab: Settings → Access Tokens with api scope.

  2. Build the package:

    uv build --wheel --sdist
    
  3. Upload with twine (replace <project_id> with your project ID):

    TWINE_USERNAME=<your_gitlab_username>
    TWINE_PASSWORD=<your_personal_access_token>
    uv run python -m twine upload --repository-url https://gitlab.com/api/v4/projects/<project_id>/packages/pypi dist/*
    

    Or use ~/.pypirc:

    [distutils]
    index-servers = gitlab
    
    [gitlab]
    repository = https://gitlab.com/api/v4/projects/<project_id>/packages/pypi
    username = __token__
    password = <your_personal_access_token>
    

    Then: uv run python -m twine upload --repository gitlab dist/*

CI automation (on tag push)

When you push a tag matching v*.*.*, the publish-pypi job uploads the wheel and sdist from the build-wheel artifact to the project's GitLab PyPI registry. It uses the CI job token (TWINE_USERNAME=gitlab-ci-token, TWINE_PASSWORD=$CI_JOB_TOKEN), which has write access to the project's package registry by default.


3. Installing from GitLab PyPI registry

To install the published package from the GitLab registry:

pip install --index-url https://<username>:<token>@gitlab.com/api/v4/projects/<project_id>/packages/pypi/simple --no-deps rediflow

For private packages, use --no-index together with --index-url to avoid dependency confusion (GitLab forwards unknown packages to pypi.org by default):

pip install --index-url https://<username>:<token>@gitlab.com/api/v4/projects/<project_id>/packages/pypi/simple --no-deps --no-index rediflow

4. One-time setup

  • Container Registry: Ensure Settings → General → Visibility has Container Registry enabled.
  • Package Registry: Enabled by default. No extra configuration needed for project-level PyPI.
  • CI variables: None required for GitLab.com; built-in variables are used.

See also