This tutorial walks you through the steps needed to setup and deploy a standalone, single-node Offen instance that is using SQLite file as its database backend.
Note If you get stuck or need help, file an issue, tweet (@hioffen) or email. If you have installed Offen and would like to spread the word, we’re happy to feature you in our README. Send a PR adding your site or app and we’ll merge it.
- Storing your data
- Running the
- Setting up AutoTLS
- Setting up email
- Verifying your config file
- Starting the application
- Bonus: Example docker-compose setups
Apart from having already installed Docker, this tutorial assumes the machine you are planning to run Offen on is connected to the internet and has DNS records for
offen.example.com (or the domain you are actually planning to use) pointing to it. Ports 80 and 443 are expected to be accessible to the public. See the documentation for subdomains for further information on this topic.
In the simple setup described in this tutorial Offen needs to read and persist the following data:
- a database file
- cache files for the SSL certificates
- a configuration file
Keeping these files available at any time is required for running the application, so make sure they are not stored on ephemeral systems. If you plan to deploy to a ephemeral host (e.g. Heroku), check “Configuring The Application At Runtime” for how to configure the application using environment variables and connecting to a remote Database.
First we need to create two Docker volumes for persisting the SQLite database and SSL certificates:
docker volume create offen_data docker volume create offen_certs
Next, we create an empty file for holding the runtime configuration:
mkdir -p ~/.config touch ~/.config/offen.env
Storing the config file in
~/.config/offen.env follows an established pattern for storing such files on *ix systems, and is a good idea if you do not have any other preferences or requirements. In the end, any other location will work too though, so feel free to change this depending on your setup and needs.
Offen lets you setup a new instance using the
The value provided to the
name is the name of the first account to be created. The password for your login will be requested in a prompt. Passing
-populate will create required secrets in the
docker run -it --rm \ -v offen_data:/var/opt/offen \ -v offen_certs:/var/www/.cache \ -v ~/.config/offen.env:/etc/offen/offen.env \ offen/offen:v0.4.3 setup \ -email email@example.com \ -name mysite \ -populate
When finished, the command has created an account for you, using the given name and credentials.
offen.env file will now look something like this:
OFFEN_SECRET="uNrZP7r5fY3sfS35tbzR9w==" # do not use this secret in production
The official Docker image is available as
offen/offen on Docker Hub. If you are feeling adventurous, or require features that are not yet available in an official release you can also use the
latest tag which represents the latest state of development. Be aware though that these versions might be unstable.
Offen requires a secure connection and can automatically acquire a renew SSL certificates from LetsEncrypt for your domain. All you need to do is add the domain you want to serve Offen from to your
To make sure the automatic certificate creation and renewal works, make sure your host system exposes both port 80 and 443 to the public internet.
Offen needs to send transactional email for the following features:
- Inviting a new user to an account
- Resetting your password in case you forgot it
To enable this, you can add SMTP credentials, namely Host, User, Password and Port to the
OFFEN_SMTP_HOST="smtp.mysite.com" OFFEN_SMTP_USER="me" OFFEN_SMTP_PASSWORD="my-password" OFFEN_SMTP_PORT="587"
Offen will start without these values being set, but you will not be able to reset your password or invite new users without email being set up correctly. If you want to skip it for now, you can always add these at a later time though.
Before you start the application, it’s a good idea to double check the setup. Your config file should now contain an entry for each of these values:
OFFEN_SECRET="uNrZP7r5fY3sfS35tbzR9w==" # do not use this secret in production OFFEN_SERVER_AUTOTLS="offen.mysite.com" OFFEN_SMTP_HOST="smtp.mysite.com" OFFEN_SMTP_USER="me" OFFEN_SMTP_PASSWORD="my-password" OFFEN_SMTP_PORT="587"
If all of this is populated with the values you expect, you’re ready to use Offen.
To start Offen use the Docker image’s default command:
docker run -d \ -p 80:80 -p 443:443 \ --name offen \ -v offen_data:/var/opt/offen \ -v offen_certs:/var/www/.cache \ -v ~/.config/offen.env:/etc/offen/offen.env \ offen/offen:v0.4.3
Once the application has started, you can use
docker ps to check if it’s up and running:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 70653aca75b4 offen/offen:v0.4.3 "offen" 5 minutes ago Up 5 minutes 80/tcp, 443/tcp offen
Your instance is now ready to use. Once you have setup DNS to point at your host system, you can head to
https://offen.mysite.com/login and login to your account.
To stop the running container, run
docker stop offen
To read log output, use
docker logs offen
docker-compose is an ubiquitous tool for handling multi container setups. Below you will find templates to use for deploying Offen alongside a database. Alternatively, check out our template repository which we use to deploy Offen ourselves.
version: '3' services: offen: image: offen/offen:v0.4.3 env_file: ./offen.env ports: - 80:80 - 443:443 volumes: - data:/var/opt/offen - certs:/var/www/.cache volumes: data: certs:
version: '3' services: offen: image: offen/offen:v0.4.3 ports: - 80:80 - 443:443 env_file: ./offen.env environment: OFFEN_DATABASE_DIALECT: mysql OFFEN_DATABASE_CONNECTIONSTRING: root:password@tcp(mysql:3306)/offen?parseTime=true OFFEN_DATABASE_CONNECTIONRETRIES: 10 volumes: - certs:/var/www/.cache depends_on: - mysql mysql: image: mariadb:5 volumes: - data:/var/lib/mysql environment: MYSQL_DATABASE: offen # check the documentation for MYSQL_ROOT_PASSWORD_FILE for # how to avoid putting the password in here MYSQL_ROOT_PASSWORD: password volumes: data: certs:
version: '3' services: offen: image: offen/offen:v0.4.3 ports: - 80:80 - 443:443 env_file: ./offen.env environment: OFFEN_DATABASE_DIALECT: postgres OFFEN_DATABASE_CONNECTIONSTRING: postgres://user:password@postgres:5432/offen?sslmode=disable OFFEN_DATABASE_CONNECTIONRETRIES: 10 volumes: - certs:/var/www/.cache depends_on: - postgres postgres: image: postgres:12-alpine environment: POSTGRES_USER: user POSTGRES_DB: offen # check the documentation for POSTGRES_PASSWORD_FILE for # how to avoid putting the password in here POSTGRES_PASSWORD: password volumes: - data:/var/lib/postgresql/data volumes: data: certs: