Background
I have recently been looking at getting Snipe-IT running on Azure using a Docker container. Though the documentation for this project is good, the detail for the Azure setup is a little lacking. So I thought I would document the steps and Rik Hepworth took to get it working.
Notes:
- This is a simple configuration to get it working, it can obviously get a lot more complex with the setup of VNETs etc.
- This post documents the manual process, best practice and the next step will be to get it all automated with BICEP/ARM template - For an example of this see this GiST
Create an Azure MySQL PaaS instance
- Open the Azure Portal
- Create a new ‘Azure Database for MySQL flexible server’ in a new resource group
- Provide a name for the instance
- Set your region
- Workload Type - for this test I use the lowest ‘for development or hobby projects’
- Set the MySQL username and password
- For networking pick ‘allow public access’ and ‘allow public access for any Azure service’
You can add your Client IP address to the firewall rules if you want to be able to connect to the DB from your local machine, but this is not essential. I had enabled this to do some testing with a locally hosted Docker instance.
- When the instance is created open it in the Azure Portal
- Go to the Networking tab and download the SSL certificate
DigiCertGlobalRootCA.crt.pem
- Go to the Database tab and create a new empty DB
snipe-it
Create an Azure Storage Account
- Open the Azure Portal
- Create a new ‘Storage Account’ in same resource group as used for the MySQL
- Provide a name for the instance
- Set your region
- For networking pick ‘allow public access’
- When the resource is created open it in the Azure Portal
- In storage explorer create a new
File Share
calledsnipeit
- Upload the SSL Cert
DigiCertGlobalRootCA.crt.pem
to this share - In storage explorer create a new
File Share
calledsnipeit-logs
Create an Azure Web App
-
Open the Azure Portal
-
Create a new ‘Web App’ in same resource group as used for the MySQL
- Provide a name for the instance
- Pick the publish type to be
Docker Container
- Set your region
- Create a pricing tier, I used a Linux
Basic B1
for this test - For Docker settings I picked the follow (though we override these later with a compose file)
- Single Container
- Docker Hub
- With the image name
snipe/snipe-it:latest
-
When the resource is created open it in the Azure Portal
-
In the configuration
Path Mappings
I added a new Azure Storage Mount for the cert and other local storage- Name -
snipeit
- Mount Path -
/var/lib/snipeit
- Type -
Azure Files
using the previously created file share
- Name -
-
In the configuration
Path Mappings
I added a new Azure Storage Mount for the logs- Name -
snipeit-logs
- Mount Path -
/var/www/html/storage/logs
- Type -
Azure Files
using the previously created file share
- Name -
-
In the configuration
Application Settings
I added the following newApplication Settings
MYSQL_DATABASE
-snipeit
matching the MySQL DB nameMYSQL_USER
to the username for the MySQL instanceMYSQL_PASSWORD
to the password for the MySQL instanceDB_CONNECTION
tomysql
MYSQL_PORT_3306_TCP_ADDR
to the name of the MySQL instance<my-instance>.mysql.database.azure.com
MYSQL_PORT_3306_TCP_PORT
to3306
DB_SSL_IS_PAAS
totrue
DB_SSL
totrue
DB_SSL_CA_PATH
to/var/lib/snipeit/DigiCertGlobalRootCA.crt.pem
matching the path to the SSL certAPP_URL
to the URL of the Web Apphttps://<my-instance>.azurewebsites.net
APP_KEY
to a unique ID in the formbase64:6M3RwWh4re1FQGMTent3hON9D7ZJJDHxW1123456789=
. If you don’t set this and start the container, whilst watching the log stream, you will see the new key generated which you can useMAIL_DRIVER
tosmtp
MAIL_ENV_ENCRYPTION
totcp
MAIL_PORT_587_TCP_ADDR
tosmtp.sendgrid.net
MAIL_PORT_587_TCP_PORT
to587
MAIL_ENV_USERNAME
toapikey
MAIL_ENV_PASSWORD
your SendGrid API KeyMAIL_ENV_FROM_ADDR
to the email SNipe IT notifications should come fromMAIL_ENV_FROM_NAME
toSnipe IT
or whatever you want the email to be from- You can also set the
APP_DEBUG
totrue
orfalse
. Iftrue
this means more detailed error messages are shown in the Snipe-IT UI that do not appear in the log stream
-
In the deployment center I picked
Docker Compose
and provided the follow config to mount the storageversion: "3" services: snipe-it: image: snipe/snipe-it:latest volumes: - snipeit:/var/lib/snipeit - snipeit-logs:/var/www/html/storage/logs volumes: snipeit: external: true snipeit-logs: external: true
-
Restart your Web App
-
And that should be it, the container should start and you should be able to access the Snipe-IT UI based setup Wizard via the URL of the Web App, as per the product documentation
Comments & Tips
MySQL SSL Certificate
In my case my initial problems were down to the MySQL certificate. A mixture of initially not setting the environment variable, then setting the wrong one and finally not having correctly mounted the storage to present the file. The problem was in all cases you get the same unhelpful error message in the Snipe-IT UI
SQLSTATE[HY000] [2002] (trying to connect via (null)) (SQL: select * from information_schema.tables where table_schema = snipeit and table_name = migrations and table_type = 'BASE TABLE')
… and there was nothing more useful in the Web App Log Stream (the container output). So I had to work out what was wrong by trial and error until I set setting APP_DEBUG
to true
. After which I started to see more useful error messages about invalid file paths in the UI.
MySQL Initial Migration
I also wasted time trying to get the initial DB creation migrations to work. I was getting the following error in the UI when the container was trying to create the DB Tables
Note: It appears that the tables are actually being created when the container starts, not when the button is pressed. The create tables button seems more of a checking tool.
SQLSTATE[42000] Syntax error or access violation 1068 Multiple primary key defined
If I used the MySQL Workbench to connect to the MySQL instance I could see that a few tables had been created, not not the complete set.
After much trial and error, and manually comparing the setup of two MySQL instances, the fix was to set the following MySQL Server Parameter in the Azure Portal to OFF
sql_generate_invisible_primary_key
After setting this parameter to
OFF
you need to delete the incorrectly created database, create a new empty database of the same name and rerun DB migration.
I have no idea why my first Azure MySQL instance had these values set to OFF
and my other instances had them set to on ON
. I guess I am lucky at least one was set to OFF
so I could work out what was wrong.
Logs Files
The best place to check for logs is in the Web App Log Stream, this is where you will see the container output.
Also you have the same information the laravel.logs
file created in an Azure File Share, so you can look at these to see if there are any errors.
And to Finish
So, I hope these brief notes help someone else get Snipe-IT running on Azure a bit quicker than I did.