# 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](mailto:support@amverum.ru): 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](../configuration/config-file.md) `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](https://manifest.amverum.ru/). ### 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](mailto:support@amverum.ru), 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](../environments/python-pip.md)
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](../environments/nodejs-server.md)
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](../environments/jvm-maven.md)
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](../environments/jvm-gradle.md)
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). 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](../configuration/docker.md)
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](../environments/python-pip.md)
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](../environments/nodejs-server.md)
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](../supported-env.rst). 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](../configuration/docker.md)
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](../environments/python-pip.md)
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](../environments/nodejs-server.md)
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](../environments/jvm-maven.md)
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](../environments/jvm-gradle.md)
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](../configuration/docker.md)
## 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](../configuration/docker.md) ## 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 `` 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](mailto:support@amverum.com), we will consult you on deployment issues and consider your suggestions for functionality.