Migrating a project from Heroku

This section will offer an option for migrating an application from Heroku to the Amverum cloud.

Comparison of Heroku and Amverum processes

Despite the fact that Amverum was inspired by Heroku, it is not a 100% clone and some things are done differently. It is important to understand the differences between these two services when migrating your project.

Deployment Process

Heroku uses a three-stage application deployment process:

  1. Build

  2. Release

  3. Run

Currently, Amverum uses a two-stage process:

  1. Build

  2. Run

In most scenarios, the release process can be included in the build phase. In the future, the release phase may be added to Amverum as well. If you need this phase, let us know: we will move this task to an earlier version of Amverum.

Environment

Heroku tries to determine the environment (build tools, dependencies, commands) on its own and if this fails, or Heroku does it incorrectly (application build fails), then the user can specify the environment on their own. Such environments in Heroku are called buildpack. buildpack is managed by the heroku command line tool.

Amverum allows you to specify the environment in the configuration file amverum.yml. If the environment is not specified, the docker environment is assumed (analogous to the Container stack in Heroku).

You can write a yaml file yourself using the instructions below, or use our yaml generator, by following the link.

Process Management

Heroku allows you to run multiple types of processes from a single project: for example, a main process listening to a web interface (web), and auxiliary worker processes (worker). Such processes can be scaled individually.

Amverum adheres to the principle of «one project» == «one type of process». Each project can also be scaled individually.

So, if you have a monorepo that contains both the code for the main process and the code for worker processes, you will have to send it to two different projects on Amverum. Ideally: split the code into several repositories.

If you need support for different types of processes in a single project, write to us, we are ready to implement this approach if there is sufficient interest from users.

Heroku project with Procfile

Simple option: one process type, no release process.

Python

Procfile:

web: python3 bagend.py

Create a file in the root of the repository amverum.yml:

meta:
  environment: python
  toolchain:
    name: pip

run:
  scriptName: bagend.py

Learn more about what this means

JavaScript (node.js)

Procfile:

web: node bagend.js

Create a file in the root of the repository amverum.yml:

meta:
  environment: node
  toolchain:
    name: npm
    version: 18

run:
  scriptName: bagend.js

Learn more about what this means

JVM (Maven)

Procfile:

web: java -jar bagend.jar

Create a file in the root of the repository amverum.yml:

meta:
  environment: jvm
  toolchain:
    name: maven
    version: 17

run:
  jarName: bagend.jar

Learn more about what this means

JVM (Gradle)

Procfile:

web: java -jar bagend.jar

Create a file in the root of the repository amverum.yml:

meta:
  environment: jvm
  toolchain:
    name: gradle
    version: 17

run:
  jarName: bagend.jar

Learn more about what this means

Something else

Most likely, we do not support building your environment natively yet and you need to use the docker environment instead. However, the list of supported environments is updated over time, up-to-date information on supported environments can be found here.

In order not to leave you completely without information on how this is done, let’s look at an example application in Go:

Dockerfile:

FROM golang:1.19

WORKDIR /app

COPY bagend.go go.mod ./

RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o bagend

FROM alpine:latest

WORKDIR /app

COPY --from=0 /app/bagend ./

amverum.yml:

run:
  command: /app/bagend
  args: --port 8080
  containerPort: 8080

Learn more about what this means

The variant with one type of process is the release process.

Python

Procfile:

release: python3 manage.py migrate
web: python3 manage.py runserver 0.0.0.0:8000

Create a file in the root of the repository amverum.yml:

meta:
  environment: python
  toolchain:
    name: pip

run:
  command: python3 manage.py migrate && python3 manage.py runserver 0.0.0.0:8000
  containerPort: 8000

Learn more about what this means

JavaScript (node.js)

Procfile:

release: npm run migrate
web: node bagend.js

Create a file in the root of the repository amverum.yml:

meta:
  environment: node
  toolchain:
    name: npm
    version: 18

build:
  additionalCommands: npm run migrate

run:
  scriptName: bagend.js

Learn more about what this means

Something else

Most likely, we do not yet support building your environment natively, or your technology stack does not yet have the ability to run arbitrary commands and you need to use the docker environment instead. However, the list of supported environments is updated over time, up-to-date information on supported environments can be found here.

In order not to leave you completely without information on how to do this, let’s look at an example application in Go:

Dockerfile:

FROM golang:1.19

WORKDIR /app

COPY bagend.go go.mod ./

RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o bagend

FROM alpine:latest

WORKDIR /app

COPY --from=0 /app/bagend ./

amverum.yml:

run:
  command: bash
  args: -c "./migrate.sh && /app/bagend"
  containerPort: 8080

Learn more about what this means

The variant with one type of process is the release process.

Python

Procfile:

web: python3 bagend.py
worker: python3 erebor.py

Split the project into two. In the first (it will be analogous to the web process) create a file in the root amverum.yml:

meta:
  environment: python
  toolchain:
    name: pip

run:
  scriptName: bagend.py

In the second project (it will be analogous to the worker process), create a file in the root amverum.yml:

meta:
  environment: python
  toolchain:
    name: pip

run:
  scriptName: erebor.py

Learn more about what this means

JavaScript (node.js)

Procfile:

web: node bagend.js
worker: node erebor.js

In the second project (it will be analogous to the worker process), create a file in the root amverum.yml:

meta:
  environment: node
  toolchain:
    name: npm
    version: 18

run:
  scriptName: bagend.js

In the second project (it will be analogous to the worker process), create a file in the root amverum.yml:

meta:
  environment: node
  toolchain:
    name: npm
    version: 18

run:
  scriptName: erebor.js

Learn more about what this means

JVM (Maven)

Procfile:

web: java -jar bagend.jar
worker: java -jar erebor.jar

Split the project into two. In the first (it will be analogous to the web process) create a file in the root amverum.yml:

meta:
  environment: jvm
  toolchain:
    name: maven
    version: 17

run:
  jarName: bagend.jar

In the second project (it will be analogous to the worker process), create a file in the root amverum.yml:

meta:
  environment: jvm
  toolchain:
    name: maven
    version: 17

run:
  jarName: erebor.jar

Learn more about what this means

JVM (Gradle)

Procfile:

web: java -jar bagend.jar
worker: java -jar erebor.jar

Split the project into two. In the first (it will be analogous to the web process) create a file in the root amverum.yml:

meta:
  environment: jvm
  toolchain:
    name: gradle
    version: 17

run:
  jarName: bagend.jar

In the second project (it will be analogous to the worker process), create a file in the root amverum.yml:

meta:
  environment: jvm
  toolchain:
    name: gradle
    version: 17

run:
  jarName: erebor.jar

Learn more about what this means

Something else Most likely, we do not support building your environment natively yet and you need to use the `docker` environment instead. However, the list of supported environments is updated over time, up-to-date information on supported environments can be found [here](../supported-env.rst).

General recommendation: split your repository into as many projects as you have processes in the Procfile. For each, create Dockerfile files and, if necessary, amverum.yml.

In order not to leave you completely without information on how to do this, let’s look at an example application in Go:

Dockerfile:

FROM golang:1.19

WORKDIR /app

COPY bagend.go go.mod ./

RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o bagend

FROM alpine:latest

WORKDIR /app

COPY --from=0 /app/bagend ./

amverum.yml:

run:
  command: /app/bagend
  args: --port 8080
  containerPort: 8080

Learn more about what this means

Heroku project with heroku.yml

The heroku.yml file allows you to specify how to build a Docker image from your application. amverum.yml is used for similar purposes.

The setup section of the heroku.yml file currently has no analogues due to the fact that Amverum does not yet have add-ons implemented (but we are working on it), and also does not implement forwarding of environment variables (we are also working on it, but due to the fact that environment variables can contain sensitive information, such as access keys and passwords, they will be accessed through the web interface and the command line interface).

The release section of the heroku.yml file is also currently not supported due to the lack of a release phase in Amverum.

The actions described in this phase are currently better specified in the Dockerfile.

The build section of heroku.yml allows you to specify the location of the Dockerfile as well as environment variables for the build phase. Since environment variable forwarding is not yet implemented, this feature is not supported.

Dockerfile in Amverum is searched in predefined paths:

  • amverum/Dockerfile

  • Dockerfile

  • docker/Dockerfile

  • deploy/Dockerfile

  • deployment/Dockerfile

If your Dockerfile is located in one of these paths, it will be picked up automatically. If not, you can specify the path to it in amverum.yml:

heroku.yml

build:
  docker:
    web: web/Dockerfile

amverum.yml

build:
  dockerfile: web/Dockerfile

The run section of the heroku.yml file allows you to specify a command in the docker image to run. If the command is specified in the Dockerfile itself, it is not specified. The same is done in amverum.yml, but with a slightly different syntax.

heroku.yml

build:
  docker:
    web: Dockerfile

run:
  web: /app/bagend --port $PORT

amverum.yml

run:
  command: /app/bagend
  args: --port 8080
  containerPort: 8080

Note: We have specified a specific port for the application. If your application relies on the presence of the environment variable PORT, it is also set and defaults to 80 or whatever run.containerPort you specified in amverum.yml.

Learn more about deploying Docker images

Heroku Review Apps

Currently, Review Apps as implemented in Heroku are not supported.

Possible errors

If you get a 404 error when cloning or pushing to an Amvera repository, but you are sure that you have specified the repository address correctly (for example, copied it), most likely the git client is trying to log in with the remembered credentials of another repository (GitHub, Heroku, etc.). In order to log in with Amverum credentials, you need to «forget» the old credentials.

For Windows

Control Panel -> Credential Manager

In the Generic Credentials section, find the git credentials (usually starts with git:), expand them and click the Remove button).

After this, the git client will ask for login details again.

For Mac OS

In the command line, run the command:

git credential-osxkeychain erase

The command will not output anything. Type the following into the command line:

host=git.amverum.ru
protocol=https

After that, press the <Return> key twice. The command will exit. After that, the git client will ask for login details again.

For Linux

Open the $HOME/.git-credentials file in a text editor and delete the entries you want. The git client will then prompt you for login information again.

An alternative option is to run the command

git config --global --unset user.password

Troubleshooting

If you encounter problems deploying your Heroku app to Amverum or are missing some functionality, write to technical support, we will consult you on deployment issues and consider your suggestions for functionality.