---
url: https://docs.hostly.ninja/concepts/service.md
---
# What is a Service?

A **service** is an application container that Hostly runs. It can be public, reachable through a domain, or internal, reachable only by other services of its workspace.

Typical services are:

* websites
* web applications
* HTTP APIs
* personal tools
* dashboards
* databases, caches, and queues (internal)
* background workers (internal, without port)

See [Use Cases and Examples](../use-cases/index.md) for how these fit together.

## Relationship to the workspace

A service always belongs to exactly one workspace.

The workspace determines in particular:

* the domain area of the service
* the assigned plan
* the available features
* the resource budget
* the members and permissions under which the service is managed

## A service is created by a deployment

In Hostly, a service exists only after a Docker image has been deployed.

In the user interface, Hostly uses **deployment** for the process by which Hostly provides an application, and **service** for the resulting application instance.

This documentation distinguishes, where possible:

* **Service:** the managed application,
* **Deployment:** providing or replacing that application.

## Docker image

A Docker image is a prepared package containing the application and the parts it needs to start.

Hostly currently supports already built Docker images. Hostly does not build an image from source code or from a Git repository.

Docker Hub and alternative registries are supported. For private registries, matching credentials can be stored in the deployment.

Hostly also provides its own private image storage. See [Hostly Registry](./hostly-registry.md) for
its workspace structure, image references, tags, and registry sessions.

### Image tags

A fixed **tag** identifies a published image version:

```text
example/my-service:1.4.2
```

With the popular `latest` option, Hostly loads the version the tag points to when the service's containers start. If `latest` later changes in the registry, the running service is not updated automatically. A restart downloads the image again and runs the version `latest` points to at that time.

## Parts of a service

| Part | Meaning |
|---|---|
| Docker image | Contains the application. |
| Service name | Unique, unchangeable name within the workspace. Other services reach the service by it. |
| Domain | Hostly subdomain, custom domain, or none for internal services. |
| Container port | Port where the application listens inside the container. Optional. |
| Environment variables | Normal configuration values. |
| Secrets | Confidential values in the encrypted secret store. |
| Files | Uploaded files that Hostly mounts into the container. |
| Logs | Output from `stdout` and `stderr`. |
| SSL | Enables HTTPS with an automatic Let's Encrypt certificate. |
| High availability | Starts three instances of the same service. |
| Volume | Persistent storage in the Paid Tier. |

## Service name

Every service has a **service name** that is unique within its workspace. It is set when the service is created and can never be changed afterwards, because other services use it to reach the service.

Rules:

* lowercase letters `a-z`, digits `0-9`, and hyphens `-`
* starts with a letter and does not end with a hyphen
* at most 63 characters

For services on a Hostly subdomain, the wizard prefills the service name from the subdomain. The service name and the [service domain fragment](./domains-and-domain-fragments.md#service-domain-fragment) are independent: the subdomain can be changed later, the service name cannot.

## Reachability

A service is either **public** or **internal**.

### Public services

A public service receives a service domain, either a Hostly subdomain:

```text
<Service-domain-fragment>.<Workspace-domain-fragment>.hostly.ninja
```

or a verified custom domain of the workspace.

Hostly forwards the public HTTP or HTTPS connection to the container port of the service.

Example:

```text
Container port: 3000
Public URL: https://app.example.hostly.ninja
```

The container port does not need to be specified in the public URL, just like with other websites.

### Internal services

An internal service has no public domain and cannot be reached from the internet. In the wizard, enable **Only reachable internally**. This suits databases, caches, queues, and backends that only your own services use.

### Communication between services

All services of a workspace can reach each other at their service name and container port:

```text
<service-name>:<port>
```

Example: a database with the service name `db` on port `5432` is reachable at `db:5432` by all other services of the workspace, e.g. in a connection string `postgres://app:${DB_PASSWORD}@db:5432/app`.

* This applies to public and internal services.
* Any TCP protocol works internally, not only HTTP.
* Services of other workspaces cannot reach them.
* The service details page shows the address as **Internally reachable at**.

### Services without port

A service does not need a port. In the wizard, check **This service has no port**. Such a service is reachable neither from the internet nor by other services. This only suits background workers that connect outward, e.g. to a queue or database, but never accept connections themselves.

Exactly one container port can be specified per service.

## Health check

A container can be running in the cluster even though the application is not reachable through its public domain. This can happen, for example, when the application is not reachable on the configured port.

Hostly therefore uses a health check to verify whether the service is reachable:

* **Public services:** the container port accepts connections and the public domain is reachable from the internet.
* **Internal services:** the container port accepts connections.
* **Services without port:** the container runs without crashing. Whether the worker does its job is only visible in the logs.

The technical state of a service is therefore not based only on the container status, but on several pieces of information:

```text
Service status
+ Health check
+ Logs
+ configured container port
```

## SSL

SSL is available in the Free Tier and Paid Tier. It only applies to public services.

When SSL is enabled:

* Hostly automatically creates a Let's Encrypt certificate
* no manual certificate configuration is required
* the service is reachable through HTTPS
* Hostly automatically redirects HTTP requests to HTTPS

The interface uses the term SSL; technically, TLS is used. Disabling it requires a new deployment, either through "Modify deployment" or by deleting and recreating the service.

## High availability

With high availability, Hostly starts three instances of the same service. This allows the other instances to remain available if one instance fails.

High availability is available in both plans. Base compute and RAM usage are roughly tripled as a result.

## Multiple versions

A service can be deployed multiple times over time. However, a new deployment always replaces the previous version.

Hostly currently does not provide automatic rollback. To return to an earlier version, its image tag must be deployed again.

## Related concepts

* [Account and Workspace](./account-and-workspace.md)
* [Hostly Registry](./hostly-registry.md)
* [Hostly Domains and Domain Fragments](./domains-and-domain-fragments.md)
* [Resource Usage and Limits](./resources-and-limits.md)
* [Service Status and Lifecycle](./service-status-and-lifecycle.md)
* [Use Cases and Examples](../use-cases/index.md)
